2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "wbc_async.h"
26 static fstring host
, workgroup
, share
, password
, username
, myname
;
27 static int max_protocol
= PROTOCOL_NT1
;
28 static const char *sockops
="TCP_NODELAY";
30 static int port_to_use
=0;
31 int torture_numops
=100;
32 int torture_blocksize
=1024*1024;
33 static int procnum
; /* records process count number when forking */
34 static struct cli_state
*current_cli
;
35 static fstring randomfname
;
36 static bool use_oplocks
;
37 static bool use_level_II_oplocks
;
38 static const char *client_txt
= "client_oplocks.txt";
39 static bool use_kerberos
;
40 static fstring multishare_conn_fname
;
41 static bool use_multishare_conn
= False
;
42 static bool do_encrypt
;
44 bool torture_showall
= False
;
46 static double create_procs(bool (*fn
)(int), bool *result
);
49 static struct timeval tp1
,tp2
;
52 void start_timer(void)
57 double end_timer(void)
60 return((tp2
.tv_sec
- tp1
.tv_sec
) +
61 (tp2
.tv_usec
- tp1
.tv_usec
)*1.0e-6);
65 /* return a pointer to a anonymous shared memory segment of size "size"
66 which will persist across fork() but will disappear when all processes
69 The memory is not zeroed
71 This function uses system5 shared memory. It takes advantage of a property
72 that the memory is not destroyed if it is attached when the id is removed
74 void *shm_setup(int size
)
79 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
81 printf("can't get shared memory\n");
84 ret
= (void *)shmat(shmid
, 0, 0);
85 if (!ret
|| ret
== (void *)-1) {
86 printf("can't attach to shared memory\n");
89 /* the following releases the ipc, but note that this process
90 and all its children will still have access to the memory, its
91 just that the shmid is no longer valid for other shm calls. This
92 means we don't leave behind lots of shm segments after we exit
94 See Stevens "advanced programming in unix env" for details
96 shmctl(shmid
, IPC_RMID
, 0);
101 /********************************************************************
102 Ensure a connection is encrypted.
103 ********************************************************************/
105 static bool force_cli_encryption(struct cli_state
*c
,
106 const char *sharename
)
109 uint32 caplow
, caphigh
;
112 if (!SERVER_HAS_UNIX_CIFS(c
)) {
113 d_printf("Encryption required and "
114 "server that doesn't support "
115 "UNIX extensions - failing connect\n");
119 if (!cli_unix_extensions_version(c
, &major
, &minor
, &caplow
, &caphigh
)) {
120 d_printf("Encryption required and "
121 "can't get UNIX CIFS extensions "
122 "version from server.\n");
126 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
127 d_printf("Encryption required and "
128 "share %s doesn't support "
129 "encryption.\n", sharename
);
133 if (c
->use_kerberos
) {
134 status
= cli_gss_smb_encryption_start(c
);
136 status
= cli_raw_ntlm_smb_encryption_start(c
,
142 if (!NT_STATUS_IS_OK(status
)) {
143 d_printf("Encryption required and "
144 "setup failed with error %s.\n",
153 static struct cli_state
*open_nbt_connection(void)
155 struct nmb_name called
, calling
;
156 struct sockaddr_storage ss
;
160 make_nmb_name(&calling
, myname
, 0x0);
161 make_nmb_name(&called
, host
, 0x20);
165 if (!(c
= cli_initialise())) {
166 printf("Failed initialize cli_struct to connect with %s\n", host
);
170 c
->port
= port_to_use
;
172 status
= cli_connect(c
, host
, &ss
);
173 if (!NT_STATUS_IS_OK(status
)) {
174 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
178 c
->use_kerberos
= use_kerberos
;
180 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
181 if (use_oplocks
) c
->use_oplocks
= True
;
182 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
184 if (!cli_session_request(c
, &calling
, &called
)) {
186 * Well, that failed, try *SMBSERVER ...
187 * However, we must reconnect as well ...
189 status
= cli_connect(c
, host
, &ss
);
190 if (!NT_STATUS_IS_OK(status
)) {
191 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
195 make_nmb_name(&called
, "*SMBSERVER", 0x20);
196 if (!cli_session_request(c
, &calling
, &called
)) {
197 printf("%s rejected the session\n",host
);
198 printf("We tried with a called name of %s & %s\n",
208 /* Insert a NULL at the first separator of the given path and return a pointer
209 * to the remainder of the string.
212 terminate_path_at_separator(char * path
)
220 if ((p
= strchr_m(path
, '/'))) {
225 if ((p
= strchr_m(path
, '\\'))) {
235 parse a //server/share type UNC name
237 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
238 char **hostname
, char **sharename
)
242 *hostname
= *sharename
= NULL
;
244 if (strncmp(unc_name
, "\\\\", 2) &&
245 strncmp(unc_name
, "//", 2)) {
249 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
250 p
= terminate_path_at_separator(*hostname
);
253 *sharename
= talloc_strdup(mem_ctx
, p
);
254 terminate_path_at_separator(*sharename
);
257 if (*hostname
&& *sharename
) {
261 TALLOC_FREE(*hostname
);
262 TALLOC_FREE(*sharename
);
266 static bool torture_open_connection_share(struct cli_state
**c
,
267 const char *hostname
,
268 const char *sharename
)
275 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
277 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
278 if (use_level_II_oplocks
)
279 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
281 status
= cli_full_connection(c
, myname
,
282 hostname
, NULL
, port_to_use
,
285 password
, flags
, Undefined
, &retry
);
286 if (!NT_STATUS_IS_OK(status
)) {
287 printf("failed to open share connection: //%s/%s port:%d - %s\n",
288 hostname
, sharename
, port_to_use
, nt_errstr(status
));
292 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
295 return force_cli_encryption(*c
,
301 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
303 char **unc_list
= NULL
;
304 int num_unc_names
= 0;
307 if (use_multishare_conn
==True
) {
309 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
310 if (!unc_list
|| num_unc_names
<= 0) {
311 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
315 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
317 printf("Failed to parse UNC name %s\n",
318 unc_list
[conn_index
% num_unc_names
]);
319 TALLOC_FREE(unc_list
);
323 result
= torture_open_connection_share(c
, h
, s
);
325 /* h, s were copied earlier */
326 TALLOC_FREE(unc_list
);
330 return torture_open_connection_share(c
, host
, share
);
333 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
335 uint16 old_vuid
= cli
->vuid
;
336 fstring old_user_name
;
337 size_t passlen
= strlen(password
);
341 fstrcpy(old_user_name
, cli
->user_name
);
343 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
347 *new_vuid
= cli
->vuid
;
348 cli
->vuid
= old_vuid
;
349 status
= cli_set_username(cli
, old_user_name
);
350 if (!NT_STATUS_IS_OK(status
)) {
357 bool torture_close_connection(struct cli_state
*c
)
361 printf("tdis failed (%s)\n", cli_errstr(c
));
371 /* check if the server produced the expected error code */
372 static bool check_error(int line
, struct cli_state
*c
,
373 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
375 if (cli_is_dos_error(c
)) {
379 /* Check DOS error */
381 cli_dos_error(c
, &cclass
, &num
);
383 if (eclass
!= cclass
|| ecode
!= num
) {
384 printf("unexpected error code class=%d code=%d\n",
385 (int)cclass
, (int)num
);
386 printf(" expected %d/%d %s (line=%d)\n",
387 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
396 status
= cli_nt_error(c
);
398 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
399 printf("unexpected error code %s\n", nt_errstr(status
));
400 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
409 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
411 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
412 if (!check_error(__LINE__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
418 static bool rw_torture(struct cli_state
*c
)
420 const char *lockfname
= "\\torture.lck";
424 pid_t pid2
, pid
= getpid();
429 memset(buf
, '\0', sizeof(buf
));
431 fnum2
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
434 fnum2
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
);
436 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
441 for (i
=0;i
<torture_numops
;i
++) {
442 unsigned n
= (unsigned)sys_random()%10;
444 printf("%d\r", i
); fflush(stdout
);
446 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
448 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
452 fnum
= cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
);
454 printf("open failed (%s)\n", cli_errstr(c
));
459 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
460 printf("write failed (%s)\n", cli_errstr(c
));
465 if (cli_write(c
, fnum
, 0, (char *)buf
,
466 sizeof(pid
)+(j
*sizeof(buf
)),
467 sizeof(buf
)) != sizeof(buf
)) {
468 printf("write failed (%s)\n", cli_errstr(c
));
475 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
476 printf("read failed (%s)\n", cli_errstr(c
));
481 printf("data corruption!\n");
485 if (!cli_close(c
, fnum
)) {
486 printf("close failed (%s)\n", cli_errstr(c
));
490 if (!cli_unlink(c
, fname
)) {
491 printf("unlink failed (%s)\n", cli_errstr(c
));
495 if (!cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
496 printf("unlock failed (%s)\n", cli_errstr(c
));
502 cli_unlink(c
, lockfname
);
509 static bool run_torture(int dummy
)
511 struct cli_state
*cli
;
516 cli_sockopt(cli
, sockops
);
518 ret
= rw_torture(cli
);
520 if (!torture_close_connection(cli
)) {
527 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
534 unsigned countprev
= 0;
539 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
541 SIVAL(buf
, i
, sys_random());
546 fnum
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
549 printf("first open read/write of %s failed (%s)\n",
550 lockfname
, cli_errstr(c
));
556 for (i
= 0; i
< 500 && fnum
== -1; i
++)
558 fnum
= cli_open(c
, lockfname
, O_RDONLY
,
563 printf("second open read-only of %s failed (%s)\n",
564 lockfname
, cli_errstr(c
));
570 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
572 if (count
>= countprev
) {
573 printf("%d %8d\r", i
, count
);
576 countprev
+= (sizeof(buf
) / 20);
581 sent
= ((unsigned)sys_random()%(20))+ 1;
582 if (sent
> sizeof(buf
) - count
)
584 sent
= sizeof(buf
) - count
;
587 if (cli_write(c
, fnum
, 0, buf
+count
, count
, (size_t)sent
) != sent
) {
588 printf("write failed (%s)\n", cli_errstr(c
));
594 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
598 printf("read failed offset:%d size:%ld (%s)\n",
599 count
, (unsigned long)sizeof(buf
)-count
,
606 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
608 printf("read/write compare failed\n");
609 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
618 if (!cli_close(c
, fnum
)) {
619 printf("close failed (%s)\n", cli_errstr(c
));
626 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
628 const char *lockfname
= "\\torture2.lck";
637 if (!cli_unlink(c1
, lockfname
)) {
638 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
641 fnum1
= cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
644 printf("first open read/write of %s failed (%s)\n",
645 lockfname
, cli_errstr(c1
));
648 fnum2
= cli_open(c2
, lockfname
, O_RDONLY
,
651 printf("second open read-only of %s failed (%s)\n",
652 lockfname
, cli_errstr(c2
));
653 cli_close(c1
, fnum1
);
657 for (i
=0;i
<torture_numops
;i
++)
659 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
661 printf("%d\r", i
); fflush(stdout
);
664 generate_random_buffer((unsigned char *)buf
, buf_size
);
666 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
667 printf("write failed (%s)\n", cli_errstr(c1
));
672 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
673 printf("read failed (%s)\n", cli_errstr(c2
));
674 printf("read %d, expected %ld\n", (int)bytes_read
,
675 (unsigned long)buf_size
);
680 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
682 printf("read/write compare failed\n");
688 if (!cli_close(c2
, fnum2
)) {
689 printf("close failed (%s)\n", cli_errstr(c2
));
692 if (!cli_close(c1
, fnum1
)) {
693 printf("close failed (%s)\n", cli_errstr(c1
));
697 if (!cli_unlink(c1
, lockfname
)) {
698 printf("unlink failed (%s)\n", cli_errstr(c1
));
705 static bool run_readwritetest(int dummy
)
707 static struct cli_state
*cli1
, *cli2
;
708 bool test1
, test2
= False
;
710 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
713 cli_sockopt(cli1
, sockops
);
714 cli_sockopt(cli2
, sockops
);
716 printf("starting readwritetest\n");
718 test1
= rw_torture2(cli1
, cli2
);
719 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
722 test2
= rw_torture2(cli1
, cli1
);
723 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
726 if (!torture_close_connection(cli1
)) {
730 if (!torture_close_connection(cli2
)) {
734 return (test1
&& test2
);
737 static bool run_readwritemulti(int dummy
)
739 struct cli_state
*cli
;
744 cli_sockopt(cli
, sockops
);
746 printf("run_readwritemulti: fname %s\n", randomfname
);
747 test
= rw_torture3(cli
, randomfname
);
749 if (!torture_close_connection(cli
)) {
756 static bool run_readwritelarge(int dummy
)
758 static struct cli_state
*cli1
;
760 const char *lockfname
= "\\large.dat";
765 if (!torture_open_connection(&cli1
, 0)) {
768 cli_sockopt(cli1
, sockops
);
769 memset(buf
,'\0',sizeof(buf
));
771 cli1
->max_xmit
= 128*1024;
773 printf("starting readwritelarge\n");
775 cli_unlink(cli1
, lockfname
);
777 fnum1
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
779 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
783 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
785 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
786 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
790 if (fsize
== sizeof(buf
))
791 printf("readwritelarge test 1 succeeded (size = %lx)\n",
792 (unsigned long)fsize
);
794 printf("readwritelarge test 1 failed (size = %lx)\n",
795 (unsigned long)fsize
);
799 if (!cli_close(cli1
, fnum1
)) {
800 printf("close failed (%s)\n", cli_errstr(cli1
));
804 if (!cli_unlink(cli1
, lockfname
)) {
805 printf("unlink failed (%s)\n", cli_errstr(cli1
));
809 fnum1
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
811 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
815 cli1
->max_xmit
= 4*1024;
817 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
));
819 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
820 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
824 if (fsize
== sizeof(buf
))
825 printf("readwritelarge test 2 succeeded (size = %lx)\n",
826 (unsigned long)fsize
);
828 printf("readwritelarge test 2 failed (size = %lx)\n",
829 (unsigned long)fsize
);
834 /* ToDo - set allocation. JRA */
835 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
836 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
839 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
840 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
844 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
847 if (!cli_close(cli1
, fnum1
)) {
848 printf("close failed (%s)\n", cli_errstr(cli1
));
852 if (!torture_close_connection(cli1
)) {
861 #define ival(s) strtol(s, NULL, 0)
863 /* run a test that simulates an approximate netbench client load */
864 static bool run_netbench(int client
)
866 struct cli_state
*cli
;
871 const char *params
[20];
878 cli_sockopt(cli
, sockops
);
882 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
884 f
= fopen(client_txt
, "r");
891 while (fgets(line
, sizeof(line
)-1, f
)) {
895 line
[strlen(line
)-1] = 0;
897 /* printf("[%d] %s\n", line_count, line); */
899 all_string_sub(line
,"client1", cname
, sizeof(line
));
901 /* parse the command parameters */
902 params
[0] = strtok_r(line
, " ", &saveptr
);
904 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
910 if (!strncmp(params
[0],"SMB", 3)) {
911 printf("ERROR: You are using a dbench 1 load file\n");
915 if (!strcmp(params
[0],"NTCreateX")) {
916 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
918 } else if (!strcmp(params
[0],"Close")) {
919 nb_close(ival(params
[1]));
920 } else if (!strcmp(params
[0],"Rename")) {
921 nb_rename(params
[1], params
[2]);
922 } else if (!strcmp(params
[0],"Unlink")) {
923 nb_unlink(params
[1]);
924 } else if (!strcmp(params
[0],"Deltree")) {
925 nb_deltree(params
[1]);
926 } else if (!strcmp(params
[0],"Rmdir")) {
928 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
929 nb_qpathinfo(params
[1]);
930 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
931 nb_qfileinfo(ival(params
[1]));
932 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
933 nb_qfsinfo(ival(params
[1]));
934 } else if (!strcmp(params
[0],"FIND_FIRST")) {
935 nb_findfirst(params
[1]);
936 } else if (!strcmp(params
[0],"WriteX")) {
937 nb_writex(ival(params
[1]),
938 ival(params
[2]), ival(params
[3]), ival(params
[4]));
939 } else if (!strcmp(params
[0],"ReadX")) {
940 nb_readx(ival(params
[1]),
941 ival(params
[2]), ival(params
[3]), ival(params
[4]));
942 } else if (!strcmp(params
[0],"Flush")) {
943 nb_flush(ival(params
[1]));
945 printf("Unknown operation %s\n", params
[0]);
953 if (!torture_close_connection(cli
)) {
961 /* run a test that simulates an approximate netbench client load */
962 static bool run_nbench(int dummy
)
971 signal(SIGALRM
, nb_alarm
);
973 t
= create_procs(run_netbench
, &correct
);
976 printf("\nThroughput %g MB/sec\n",
977 1.0e-6 * nbio_total() / t
);
983 This test checks for two things:
985 1) correct support for retaining locks over a close (ie. the server
986 must not use posix semantics)
987 2) support for lock timeouts
989 static bool run_locktest1(int dummy
)
991 struct cli_state
*cli1
, *cli2
;
992 const char *fname
= "\\lockt1.lck";
993 int fnum1
, fnum2
, fnum3
;
995 unsigned lock_timeout
;
997 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1000 cli_sockopt(cli1
, sockops
);
1001 cli_sockopt(cli2
, sockops
);
1003 printf("starting locktest1\n");
1005 cli_unlink(cli1
, fname
);
1007 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1009 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1012 fnum2
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1014 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1017 fnum3
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
);
1019 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1023 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1024 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1029 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1030 printf("lock2 succeeded! This is a locking bug\n");
1033 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1034 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1038 lock_timeout
= (1 + (random() % 20));
1039 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1041 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1042 printf("lock3 succeeded! This is a locking bug\n");
1045 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1046 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1050 if (ABS(t2
- t1
) < lock_timeout
-1) {
1051 printf("error: This server appears not to support timed lock requests\n");
1054 printf("server slept for %u seconds for a %u second timeout\n",
1055 (unsigned int)(t2
-t1
), lock_timeout
);
1057 if (!cli_close(cli1
, fnum2
)) {
1058 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1062 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1063 printf("lock4 succeeded! This is a locking bug\n");
1066 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1067 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1070 if (!cli_close(cli1
, fnum1
)) {
1071 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1075 if (!cli_close(cli2
, fnum3
)) {
1076 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1080 if (!cli_unlink(cli1
, fname
)) {
1081 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1086 if (!torture_close_connection(cli1
)) {
1090 if (!torture_close_connection(cli2
)) {
1094 printf("Passed locktest1\n");
1099 this checks to see if a secondary tconx can use open files from an
1102 static bool run_tcon_test(int dummy
)
1104 static struct cli_state
*cli
;
1105 const char *fname
= "\\tcontest.tmp";
1107 uint16 cnum1
, cnum2
, cnum3
;
1108 uint16 vuid1
, vuid2
;
1113 memset(buf
, '\0', sizeof(buf
));
1115 if (!torture_open_connection(&cli
, 0)) {
1118 cli_sockopt(cli
, sockops
);
1120 printf("starting tcontest\n");
1122 cli_unlink(cli
, fname
);
1124 fnum1
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1126 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1133 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1134 printf("initial write failed (%s)", cli_errstr(cli
));
1138 status
= cli_tcon_andx(cli
, share
, "?????",
1139 password
, strlen(password
)+1);
1140 if (!NT_STATUS_IS_OK(status
)) {
1141 printf("%s refused 2nd tree connect (%s)\n", host
,
1148 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1149 vuid2
= cli
->vuid
+ 1;
1151 /* try a write with the wrong tid */
1154 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1155 printf("* server allows write with wrong TID\n");
1158 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1162 /* try a write with an invalid tid */
1165 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1166 printf("* server allows write with invalid TID\n");
1169 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1172 /* try a write with an invalid vuid */
1176 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1177 printf("* server allows write with invalid VUID\n");
1180 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1186 if (!cli_close(cli
, fnum1
)) {
1187 printf("close failed (%s)\n", cli_errstr(cli
));
1193 if (!cli_tdis(cli
)) {
1194 printf("secondary tdis failed (%s)\n", cli_errstr(cli
));
1200 if (!torture_close_connection(cli
)) {
1209 checks for old style tcon support
1211 static bool run_tcon2_test(int dummy
)
1213 static struct cli_state
*cli
;
1214 uint16 cnum
, max_xmit
;
1218 if (!torture_open_connection(&cli
, 0)) {
1221 cli_sockopt(cli
, sockops
);
1223 printf("starting tcon2 test\n");
1225 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1229 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1231 if (!NT_STATUS_IS_OK(status
)) {
1232 printf("tcon2 failed : %s\n", cli_errstr(cli
));
1234 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1235 (int)max_xmit
, (int)cnum
, SVAL(cli
->inbuf
, smb_tid
));
1238 if (!torture_close_connection(cli
)) {
1242 printf("Passed tcon2 test\n");
1246 static bool tcon_devtest(struct cli_state
*cli
,
1247 const char *myshare
, const char *devtype
,
1248 const char *return_devtype
,
1249 NTSTATUS expected_error
)
1254 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1255 password
, strlen(password
)+1);
1257 if (NT_STATUS_IS_OK(expected_error
)) {
1258 if (NT_STATUS_IS_OK(status
)) {
1259 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1262 printf("tconX to share %s with type %s "
1263 "succeeded but returned the wrong "
1264 "device type (got [%s] but should have got [%s])\n",
1265 myshare
, devtype
, cli
->dev
, return_devtype
);
1269 printf("tconX to share %s with type %s "
1270 "should have succeeded but failed\n",
1276 if (NT_STATUS_IS_OK(status
)) {
1277 printf("tconx to share %s with type %s "
1278 "should have failed but succeeded\n",
1282 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1286 printf("Returned unexpected error\n");
1295 checks for correct tconX support
1297 static bool run_tcon_devtype_test(int dummy
)
1299 static struct cli_state
*cli1
= NULL
;
1305 status
= cli_full_connection(&cli1
, myname
,
1306 host
, NULL
, port_to_use
,
1308 username
, workgroup
,
1309 password
, flags
, Undefined
, &retry
);
1311 if (!NT_STATUS_IS_OK(status
)) {
1312 printf("could not open connection\n");
1316 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1319 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1322 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1325 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1328 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1331 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1334 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1337 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1340 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1343 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1349 printf("Passed tcondevtest\n");
1356 This test checks that
1358 1) the server supports multiple locking contexts on the one SMB
1359 connection, distinguished by PID.
1361 2) the server correctly fails overlapping locks made by the same PID (this
1362 goes against POSIX behaviour, which is why it is tricky to implement)
1364 3) the server denies unlock requests by an incorrect client PID
1366 static bool run_locktest2(int dummy
)
1368 static struct cli_state
*cli
;
1369 const char *fname
= "\\lockt2.lck";
1370 int fnum1
, fnum2
, fnum3
;
1371 bool correct
= True
;
1373 if (!torture_open_connection(&cli
, 0)) {
1377 cli_sockopt(cli
, sockops
);
1379 printf("starting locktest2\n");
1381 cli_unlink(cli
, fname
);
1385 fnum1
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1387 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1391 fnum2
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
);
1393 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1399 fnum3
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
);
1401 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1407 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1408 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1412 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1413 printf("WRITE lock1 succeeded! This is a locking bug\n");
1416 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1417 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1420 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1421 printf("WRITE lock2 succeeded! This is a locking bug\n");
1424 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1425 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1428 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1429 printf("READ lock2 succeeded! This is a locking bug\n");
1432 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1433 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1436 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1437 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1440 if (cli_unlock(cli
, fnum1
, 100, 4)) {
1441 printf("unlock at 100 succeeded! This is a locking bug\n");
1445 if (cli_unlock(cli
, fnum1
, 0, 4)) {
1446 printf("unlock1 succeeded! This is a locking bug\n");
1449 if (!check_error(__LINE__
, cli
,
1451 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1454 if (cli_unlock(cli
, fnum1
, 0, 8)) {
1455 printf("unlock2 succeeded! This is a locking bug\n");
1458 if (!check_error(__LINE__
, cli
,
1460 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1463 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1464 printf("lock3 succeeded! This is a locking bug\n");
1467 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1472 if (!cli_close(cli
, fnum1
)) {
1473 printf("close1 failed (%s)\n", cli_errstr(cli
));
1477 if (!cli_close(cli
, fnum2
)) {
1478 printf("close2 failed (%s)\n", cli_errstr(cli
));
1482 if (!cli_close(cli
, fnum3
)) {
1483 printf("close3 failed (%s)\n", cli_errstr(cli
));
1487 if (!torture_close_connection(cli
)) {
1491 printf("locktest2 finished\n");
1498 This test checks that
1500 1) the server supports the full offset range in lock requests
1502 static bool run_locktest3(int dummy
)
1504 static struct cli_state
*cli1
, *cli2
;
1505 const char *fname
= "\\lockt3.lck";
1506 int fnum1
, fnum2
, i
;
1508 bool correct
= True
;
1510 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1512 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1515 cli_sockopt(cli1
, sockops
);
1516 cli_sockopt(cli2
, sockops
);
1518 printf("starting locktest3\n");
1520 cli_unlink(cli1
, fname
);
1522 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1524 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1527 fnum2
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
);
1529 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1533 for (offset
=i
=0;i
<torture_numops
;i
++) {
1535 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1536 printf("lock1 %d failed (%s)\n",
1542 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1543 printf("lock2 %d failed (%s)\n",
1550 for (offset
=i
=0;i
<torture_numops
;i
++) {
1553 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1554 printf("error: lock1 %d succeeded!\n", i
);
1558 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1559 printf("error: lock2 %d succeeded!\n", i
);
1563 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1564 printf("error: lock3 %d succeeded!\n", i
);
1568 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1569 printf("error: lock4 %d succeeded!\n", i
);
1574 for (offset
=i
=0;i
<torture_numops
;i
++) {
1577 if (!cli_unlock(cli1
, fnum1
, offset
-1, 1)) {
1578 printf("unlock1 %d failed (%s)\n",
1584 if (!cli_unlock(cli2
, fnum2
, offset
-2, 1)) {
1585 printf("unlock2 %d failed (%s)\n",
1592 if (!cli_close(cli1
, fnum1
)) {
1593 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1597 if (!cli_close(cli2
, fnum2
)) {
1598 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1602 if (!cli_unlink(cli1
, fname
)) {
1603 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1607 if (!torture_close_connection(cli1
)) {
1611 if (!torture_close_connection(cli2
)) {
1615 printf("finished locktest3\n");
1620 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1621 printf("** "); correct = False; \
1625 looks at overlapping locks
1627 static bool run_locktest4(int dummy
)
1629 static struct cli_state
*cli1
, *cli2
;
1630 const char *fname
= "\\lockt4.lck";
1631 int fnum1
, fnum2
, f
;
1634 bool correct
= True
;
1636 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1640 cli_sockopt(cli1
, sockops
);
1641 cli_sockopt(cli2
, sockops
);
1643 printf("starting locktest4\n");
1645 cli_unlink(cli1
, fname
);
1647 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1648 fnum2
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
);
1650 memset(buf
, 0, sizeof(buf
));
1652 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1653 printf("Failed to create file\n");
1658 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1659 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1660 EXPECTED(ret
, False
);
1661 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1663 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1664 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1665 EXPECTED(ret
, True
);
1666 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1668 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1669 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1670 EXPECTED(ret
, False
);
1671 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1673 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1674 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1675 EXPECTED(ret
, True
);
1676 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1678 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1679 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1680 EXPECTED(ret
, False
);
1681 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1683 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1684 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1685 EXPECTED(ret
, True
);
1686 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1688 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1689 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1690 EXPECTED(ret
, True
);
1691 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1693 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1694 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1695 EXPECTED(ret
, False
);
1696 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1698 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1699 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1700 EXPECTED(ret
, False
);
1701 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1703 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1704 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1705 EXPECTED(ret
, True
);
1706 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1708 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1709 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1710 EXPECTED(ret
, False
);
1711 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1713 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1714 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1715 cli_unlock(cli1
, fnum1
, 110, 6);
1716 EXPECTED(ret
, False
);
1717 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1720 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1721 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1722 EXPECTED(ret
, False
);
1723 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1725 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1726 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1727 EXPECTED(ret
, False
);
1728 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1731 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1732 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1733 cli_unlock(cli1
, fnum1
, 140, 4) &&
1734 cli_unlock(cli1
, fnum1
, 140, 4);
1735 EXPECTED(ret
, True
);
1736 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1739 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1740 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1741 cli_unlock(cli1
, fnum1
, 150, 4) &&
1742 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1743 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1744 cli_unlock(cli1
, fnum1
, 150, 4);
1745 EXPECTED(ret
, True
);
1746 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1748 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1749 cli_unlock(cli1
, fnum1
, 160, 4) &&
1750 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1751 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1752 EXPECTED(ret
, True
);
1753 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1755 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1756 cli_unlock(cli1
, fnum1
, 170, 4) &&
1757 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1758 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1759 EXPECTED(ret
, True
);
1760 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1762 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1763 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1764 cli_unlock(cli1
, fnum1
, 190, 4) &&
1765 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1766 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1767 EXPECTED(ret
, True
);
1768 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1770 cli_close(cli1
, fnum1
);
1771 cli_close(cli2
, fnum2
);
1772 fnum1
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1773 f
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1774 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1775 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1776 cli_close(cli1
, fnum1
) &&
1777 ((fnum1
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
)) != -1) &&
1778 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1780 cli_close(cli1
, fnum1
);
1781 EXPECTED(ret
, True
);
1782 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1785 cli_close(cli1
, fnum1
);
1786 cli_close(cli2
, fnum2
);
1787 cli_unlink(cli1
, fname
);
1788 torture_close_connection(cli1
);
1789 torture_close_connection(cli2
);
1791 printf("finished locktest4\n");
1796 looks at lock upgrade/downgrade.
1798 static bool run_locktest5(int dummy
)
1800 static struct cli_state
*cli1
, *cli2
;
1801 const char *fname
= "\\lockt5.lck";
1802 int fnum1
, fnum2
, fnum3
;
1805 bool correct
= True
;
1807 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1811 cli_sockopt(cli1
, sockops
);
1812 cli_sockopt(cli2
, sockops
);
1814 printf("starting locktest5\n");
1816 cli_unlink(cli1
, fname
);
1818 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1819 fnum2
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
);
1820 fnum3
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1822 memset(buf
, 0, sizeof(buf
));
1824 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1825 printf("Failed to create file\n");
1830 /* Check for NT bug... */
1831 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1832 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1833 cli_close(cli1
, fnum1
);
1834 fnum1
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1835 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1836 EXPECTED(ret
, True
);
1837 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1838 cli_close(cli1
, fnum1
);
1839 fnum1
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
1840 cli_unlock(cli1
, fnum3
, 0, 1);
1842 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1843 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1844 EXPECTED(ret
, True
);
1845 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1847 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1848 EXPECTED(ret
, False
);
1850 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1852 /* Unlock the process 2 lock. */
1853 cli_unlock(cli2
, fnum2
, 0, 4);
1855 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1856 EXPECTED(ret
, False
);
1858 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1860 /* Unlock the process 1 fnum3 lock. */
1861 cli_unlock(cli1
, fnum3
, 0, 4);
1863 /* Stack 2 more locks here. */
1864 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1865 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1867 EXPECTED(ret
, True
);
1868 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
1870 /* Unlock the first process lock, then check this was the WRITE lock that was
1873 ret
= cli_unlock(cli1
, fnum1
, 0, 4) &&
1874 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1876 EXPECTED(ret
, True
);
1877 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
1879 /* Unlock the process 2 lock. */
1880 cli_unlock(cli2
, fnum2
, 0, 4);
1882 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1884 ret
= cli_unlock(cli1
, fnum1
, 1, 1) &&
1885 cli_unlock(cli1
, fnum1
, 0, 4) &&
1886 cli_unlock(cli1
, fnum1
, 0, 4);
1888 EXPECTED(ret
, True
);
1889 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
1891 /* Ensure the next unlock fails. */
1892 ret
= cli_unlock(cli1
, fnum1
, 0, 4);
1893 EXPECTED(ret
, False
);
1894 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
1896 /* Ensure connection 2 can get a write lock. */
1897 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1898 EXPECTED(ret
, True
);
1900 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
1904 cli_close(cli1
, fnum1
);
1905 cli_close(cli2
, fnum2
);
1906 cli_unlink(cli1
, fname
);
1907 if (!torture_close_connection(cli1
)) {
1910 if (!torture_close_connection(cli2
)) {
1914 printf("finished locktest5\n");
1920 tries the unusual lockingX locktype bits
1922 static bool run_locktest6(int dummy
)
1924 static struct cli_state
*cli
;
1925 const char *fname
[1] = { "\\lock6.txt" };
1930 if (!torture_open_connection(&cli
, 0)) {
1934 cli_sockopt(cli
, sockops
);
1936 printf("starting locktest6\n");
1939 printf("Testing %s\n", fname
[i
]);
1941 cli_unlink(cli
, fname
[i
]);
1943 fnum
= cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1944 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
1945 cli_close(cli
, fnum
);
1946 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
1948 fnum
= cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
);
1949 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
1950 cli_close(cli
, fnum
);
1951 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
1953 cli_unlink(cli
, fname
[i
]);
1956 torture_close_connection(cli
);
1958 printf("finished locktest6\n");
1962 static bool run_locktest7(int dummy
)
1964 struct cli_state
*cli1
;
1965 const char *fname
= "\\lockt7.lck";
1968 bool correct
= False
;
1970 if (!torture_open_connection(&cli1
, 0)) {
1974 cli_sockopt(cli1
, sockops
);
1976 printf("starting locktest7\n");
1978 cli_unlink(cli1
, fname
);
1980 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1982 memset(buf
, 0, sizeof(buf
));
1984 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1985 printf("Failed to create file\n");
1989 cli_setpid(cli1
, 1);
1991 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
1992 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
1995 printf("pid1 successfully locked range 130:4 for READ\n");
1998 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
1999 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2002 printf("pid1 successfully read the range 130:4\n");
2005 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2006 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2007 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2008 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2012 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2016 cli_setpid(cli1
, 2);
2018 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2019 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2021 printf("pid2 successfully read the range 130:4\n");
2024 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2025 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2026 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2027 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2031 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2035 cli_setpid(cli1
, 1);
2036 cli_unlock(cli1
, fnum1
, 130, 4);
2038 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2039 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2042 printf("pid1 successfully locked range 130:4 for WRITE\n");
2045 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2046 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2049 printf("pid1 successfully read the range 130:4\n");
2052 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2053 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2056 printf("pid1 successfully wrote to the range 130:4\n");
2059 cli_setpid(cli1
, 2);
2061 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2062 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2063 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2064 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2068 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2072 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2073 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2074 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2075 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2079 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2083 cli_unlock(cli1
, fnum1
, 130, 0);
2087 cli_close(cli1
, fnum1
);
2088 cli_unlink(cli1
, fname
);
2089 torture_close_connection(cli1
);
2091 printf("finished locktest7\n");
2096 test whether fnums and tids open on one VC are available on another (a major
2099 static bool run_fdpasstest(int dummy
)
2101 struct cli_state
*cli1
, *cli2
;
2102 const char *fname
= "\\fdpass.tst";
2106 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2109 cli_sockopt(cli1
, sockops
);
2110 cli_sockopt(cli2
, sockops
);
2112 printf("starting fdpasstest\n");
2114 cli_unlink(cli1
, fname
);
2116 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2118 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2122 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2123 printf("write failed (%s)\n", cli_errstr(cli1
));
2127 cli2
->vuid
= cli1
->vuid
;
2128 cli2
->cnum
= cli1
->cnum
;
2129 cli2
->pid
= cli1
->pid
;
2131 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2132 printf("read succeeded! nasty security hole [%s]\n",
2137 cli_close(cli1
, fnum1
);
2138 cli_unlink(cli1
, fname
);
2140 torture_close_connection(cli1
);
2141 torture_close_connection(cli2
);
2143 printf("finished fdpasstest\n");
2147 static bool run_fdsesstest(int dummy
)
2149 struct cli_state
*cli
;
2154 const char *fname
= "\\fdsess.tst";
2155 const char *fname1
= "\\fdsess1.tst";
2161 if (!torture_open_connection(&cli
, 0))
2163 cli_sockopt(cli
, sockops
);
2165 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2168 saved_cnum
= cli
->cnum
;
2169 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2171 new_cnum
= cli
->cnum
;
2172 cli
->cnum
= saved_cnum
;
2174 printf("starting fdsesstest\n");
2176 cli_unlink(cli
, fname
);
2177 cli_unlink(cli
, fname1
);
2179 fnum1
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2181 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2185 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2186 printf("write failed (%s)\n", cli_errstr(cli
));
2190 saved_vuid
= cli
->vuid
;
2191 cli
->vuid
= new_vuid
;
2193 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2194 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2198 /* Try to open a file with different vuid, samba cnum. */
2199 fnum2
= cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2201 printf("create with different vuid, same cnum succeeded.\n");
2202 cli_close(cli
, fnum2
);
2203 cli_unlink(cli
, fname1
);
2205 printf("create with different vuid, same cnum failed.\n");
2206 printf("This will cause problems with service clients.\n");
2210 cli
->vuid
= saved_vuid
;
2212 /* Try with same vuid, different cnum. */
2213 cli
->cnum
= new_cnum
;
2215 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2216 printf("read succeeded with different cnum![%s]\n",
2221 cli
->cnum
= saved_cnum
;
2222 cli_close(cli
, fnum1
);
2223 cli_unlink(cli
, fname
);
2225 torture_close_connection(cli
);
2227 printf("finished fdsesstest\n");
2232 This test checks that
2234 1) the server does not allow an unlink on a file that is open
2236 static bool run_unlinktest(int dummy
)
2238 struct cli_state
*cli
;
2239 const char *fname
= "\\unlink.tst";
2241 bool correct
= True
;
2243 if (!torture_open_connection(&cli
, 0)) {
2247 cli_sockopt(cli
, sockops
);
2249 printf("starting unlink test\n");
2251 cli_unlink(cli
, fname
);
2255 fnum
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2257 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2261 if (cli_unlink(cli
, fname
)) {
2262 printf("error: server allowed unlink on an open file\n");
2265 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2266 NT_STATUS_SHARING_VIOLATION
);
2269 cli_close(cli
, fnum
);
2270 cli_unlink(cli
, fname
);
2272 if (!torture_close_connection(cli
)) {
2276 printf("unlink test finished\n");
2283 test how many open files this server supports on the one socket
2285 static bool run_maxfidtest(int dummy
)
2287 struct cli_state
*cli
;
2288 const char *ftemplate
= "\\maxfid.%d.%d";
2290 int fnums
[0x11000], i
;
2292 bool correct
= True
;
2297 printf("failed to connect\n");
2301 cli_sockopt(cli
, sockops
);
2303 for (i
=0; i
<0x11000; i
++) {
2304 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2305 if ((fnums
[i
] = cli_open(cli
, fname
,
2306 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
)) ==
2308 printf("open of %s failed (%s)\n",
2309 fname
, cli_errstr(cli
));
2310 printf("maximum fnum is %d\n", i
);
2318 printf("cleaning up\n");
2320 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2321 cli_close(cli
, fnums
[i
]);
2322 if (!cli_unlink(cli
, fname
)) {
2323 printf("unlink of %s failed (%s)\n",
2324 fname
, cli_errstr(cli
));
2331 printf("maxfid test finished\n");
2332 if (!torture_close_connection(cli
)) {
2338 /* generate a random buffer */
2339 static void rand_buf(char *buf
, int len
)
2342 *buf
= (char)sys_random();
2347 /* send smb negprot commands, not reading the response */
2348 static bool run_negprot_nowait(int dummy
)
2351 static struct cli_state
*cli
;
2352 bool correct
= True
;
2354 printf("starting negprot nowait test\n");
2356 if (!(cli
= open_nbt_connection())) {
2360 for (i
=0;i
<50000;i
++) {
2361 cli_negprot_sendsync(cli
);
2364 if (!torture_close_connection(cli
)) {
2368 printf("finished negprot nowait test\n");
2374 /* send random IPC commands */
2375 static bool run_randomipc(int dummy
)
2377 char *rparam
= NULL
;
2379 unsigned int rdrcnt
,rprcnt
;
2381 int api
, param_len
, i
;
2382 struct cli_state
*cli
;
2383 bool correct
= True
;
2386 printf("starting random ipc test\n");
2388 if (!torture_open_connection(&cli
, 0)) {
2392 for (i
=0;i
<count
;i
++) {
2393 api
= sys_random() % 500;
2394 param_len
= (sys_random() % 64);
2396 rand_buf(param
, param_len
);
2401 param
, param_len
, 8,
2402 NULL
, 0, BUFFER_SIZE
,
2406 printf("%d/%d\r", i
,count
);
2409 printf("%d/%d\n", i
, count
);
2411 if (!torture_close_connection(cli
)) {
2415 printf("finished random ipc test\n");
2422 static void browse_callback(const char *sname
, uint32 stype
,
2423 const char *comment
, void *state
)
2425 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2431 This test checks the browse list code
2434 static bool run_browsetest(int dummy
)
2436 static struct cli_state
*cli
;
2437 bool correct
= True
;
2439 printf("starting browse test\n");
2441 if (!torture_open_connection(&cli
, 0)) {
2445 printf("domain list:\n");
2446 cli_NetServerEnum(cli
, cli
->server_domain
,
2447 SV_TYPE_DOMAIN_ENUM
,
2448 browse_callback
, NULL
);
2450 printf("machine list:\n");
2451 cli_NetServerEnum(cli
, cli
->server_domain
,
2453 browse_callback
, NULL
);
2455 if (!torture_close_connection(cli
)) {
2459 printf("browse test finished\n");
2467 This checks how the getatr calls works
2469 static bool run_attrtest(int dummy
)
2471 struct cli_state
*cli
;
2474 const char *fname
= "\\attrib123456789.tst";
2475 bool correct
= True
;
2477 printf("starting attrib test\n");
2479 if (!torture_open_connection(&cli
, 0)) {
2483 cli_unlink(cli
, fname
);
2484 fnum
= cli_open(cli
, fname
,
2485 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
2486 cli_close(cli
, fnum
);
2487 if (!cli_getatr(cli
, fname
, NULL
, NULL
, &t
)) {
2488 printf("getatr failed (%s)\n", cli_errstr(cli
));
2492 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2493 printf("ERROR: SMBgetatr bug. time is %s",
2499 t2
= t
-60*60*24; /* 1 day ago */
2501 if (!cli_setatr(cli
, fname
, 0, t2
)) {
2502 printf("setatr failed (%s)\n", cli_errstr(cli
));
2506 if (!cli_getatr(cli
, fname
, NULL
, NULL
, &t
)) {
2507 printf("getatr failed (%s)\n", cli_errstr(cli
));
2512 printf("ERROR: getatr/setatr bug. times are\n%s",
2514 printf("%s", ctime(&t2
));
2518 cli_unlink(cli
, fname
);
2520 if (!torture_close_connection(cli
)) {
2524 printf("attrib test finished\n");
2531 This checks a couple of trans2 calls
2533 static bool run_trans2test(int dummy
)
2535 struct cli_state
*cli
;
2538 time_t c_time
, a_time
, m_time
;
2539 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
2540 const char *fname
= "\\trans2.tst";
2541 const char *dname
= "\\trans2";
2542 const char *fname2
= "\\trans2\\trans2.tst";
2544 bool correct
= True
;
2546 printf("starting trans2 test\n");
2548 if (!torture_open_connection(&cli
, 0)) {
2552 cli_unlink(cli
, fname
);
2553 fnum
= cli_open(cli
, fname
,
2554 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
2555 if (!cli_qfileinfo(cli
, fnum
, NULL
, &size
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2556 &m_time_ts
, NULL
)) {
2557 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
2561 if (!cli_qfilename(cli
, fnum
, pname
, sizeof(pname
))) {
2562 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
2566 if (strcmp(pname
, fname
)) {
2567 printf("qfilename gave different name? [%s] [%s]\n",
2572 cli_close(cli
, fnum
);
2576 cli_unlink(cli
, fname
);
2577 fnum
= cli_open(cli
, fname
,
2578 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
2580 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2583 cli_close(cli
, fnum
);
2585 if (!cli_qpathinfo(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
)) {
2586 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli
));
2589 if (c_time
!= m_time
) {
2590 printf("create time=%s", ctime(&c_time
));
2591 printf("modify time=%s", ctime(&m_time
));
2592 printf("This system appears to have sticky create times\n");
2594 if (a_time
% (60*60) == 0) {
2595 printf("access time=%s", ctime(&a_time
));
2596 printf("This system appears to set a midnight access time\n");
2600 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
2601 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
2607 cli_unlink(cli
, fname
);
2608 fnum
= cli_open(cli
, fname
,
2609 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
2610 cli_close(cli
, fnum
);
2611 if (!cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2612 &m_time_ts
, &size
, NULL
, NULL
)) {
2613 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2616 if (w_time_ts
.tv_sec
< 60*60*24*2) {
2617 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
2618 printf("This system appears to set a initial 0 write time\n");
2623 cli_unlink(cli
, fname
);
2626 /* check if the server updates the directory modification time
2627 when creating a new file */
2628 if (!cli_mkdir(cli
, dname
)) {
2629 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
2633 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2634 &m_time_ts
, &size
, NULL
, NULL
)) {
2635 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2639 fnum
= cli_open(cli
, fname2
,
2640 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
2641 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
2642 cli_close(cli
, fnum
);
2643 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2644 &m_time2_ts
, &size
, NULL
, NULL
)) {
2645 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2648 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
2650 printf("This system does not update directory modification times\n");
2654 cli_unlink(cli
, fname2
);
2655 cli_rmdir(cli
, dname
);
2657 if (!torture_close_connection(cli
)) {
2661 printf("trans2 test finished\n");
2667 This checks new W2K calls.
2670 static bool new_trans(struct cli_state
*pcli
, int fnum
, int level
)
2674 bool correct
= True
;
2676 if (!cli_qfileinfo_test(pcli
, fnum
, level
, &buf
, &len
)) {
2677 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
, cli_errstr(pcli
));
2680 printf("qfileinfo: level %d, len = %u\n", level
, len
);
2681 dump_data(0, (uint8
*)buf
, len
);
2688 static bool run_w2ktest(int dummy
)
2690 struct cli_state
*cli
;
2692 const char *fname
= "\\w2ktest\\w2k.tst";
2694 bool correct
= True
;
2696 printf("starting w2k test\n");
2698 if (!torture_open_connection(&cli
, 0)) {
2702 fnum
= cli_open(cli
, fname
,
2703 O_RDWR
| O_CREAT
, DENY_NONE
);
2705 for (level
= 1004; level
< 1040; level
++) {
2706 new_trans(cli
, fnum
, level
);
2709 cli_close(cli
, fnum
);
2711 if (!torture_close_connection(cli
)) {
2715 printf("w2k test finished\n");
2722 this is a harness for some oplock tests
2724 static bool run_oplock1(int dummy
)
2726 struct cli_state
*cli1
;
2727 const char *fname
= "\\lockt1.lck";
2729 bool correct
= True
;
2731 printf("starting oplock test 1\n");
2733 if (!torture_open_connection(&cli1
, 0)) {
2737 cli_unlink(cli1
, fname
);
2739 cli_sockopt(cli1
, sockops
);
2741 cli1
->use_oplocks
= True
;
2743 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2745 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2749 cli1
->use_oplocks
= False
;
2751 cli_unlink(cli1
, fname
);
2752 cli_unlink(cli1
, fname
);
2754 if (!cli_close(cli1
, fnum1
)) {
2755 printf("close2 failed (%s)\n", cli_errstr(cli1
));
2759 if (!cli_unlink(cli1
, fname
)) {
2760 printf("unlink failed (%s)\n", cli_errstr(cli1
));
2764 if (!torture_close_connection(cli1
)) {
2768 printf("finished oplock test 1\n");
2773 static bool run_oplock2(int dummy
)
2775 struct cli_state
*cli1
, *cli2
;
2776 const char *fname
= "\\lockt2.lck";
2778 int saved_use_oplocks
= use_oplocks
;
2780 bool correct
= True
;
2781 volatile bool *shared_correct
;
2783 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
2784 *shared_correct
= True
;
2786 use_level_II_oplocks
= True
;
2789 printf("starting oplock test 2\n");
2791 if (!torture_open_connection(&cli1
, 0)) {
2792 use_level_II_oplocks
= False
;
2793 use_oplocks
= saved_use_oplocks
;
2797 cli1
->use_oplocks
= True
;
2798 cli1
->use_level_II_oplocks
= True
;
2800 if (!torture_open_connection(&cli2
, 1)) {
2801 use_level_II_oplocks
= False
;
2802 use_oplocks
= saved_use_oplocks
;
2806 cli2
->use_oplocks
= True
;
2807 cli2
->use_level_II_oplocks
= True
;
2809 cli_unlink(cli1
, fname
);
2811 cli_sockopt(cli1
, sockops
);
2812 cli_sockopt(cli2
, sockops
);
2814 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
2816 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2820 /* Don't need the globals any more. */
2821 use_level_II_oplocks
= False
;
2822 use_oplocks
= saved_use_oplocks
;
2826 fnum2
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
);
2828 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2829 *shared_correct
= False
;
2835 if (!cli_close(cli2
, fnum2
)) {
2836 printf("close2 failed (%s)\n", cli_errstr(cli1
));
2837 *shared_correct
= False
;
2845 /* Ensure cli1 processes the break. Empty file should always return 0
2848 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
2849 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
2853 /* Should now be at level II. */
2854 /* Test if sending a write locks causes a break to none. */
2856 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
2857 printf("lock failed (%s)\n", cli_errstr(cli1
));
2861 cli_unlock(cli1
, fnum1
, 0, 4);
2865 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
2866 printf("lock failed (%s)\n", cli_errstr(cli1
));
2870 cli_unlock(cli1
, fnum1
, 0, 4);
2874 cli_read(cli1
, fnum1
, buf
, 0, 4);
2877 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
2878 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
2883 if (!cli_close(cli1
, fnum1
)) {
2884 printf("close1 failed (%s)\n", cli_errstr(cli1
));
2890 if (!cli_unlink(cli1
, fname
)) {
2891 printf("unlink failed (%s)\n", cli_errstr(cli1
));
2895 if (!torture_close_connection(cli1
)) {
2899 if (!*shared_correct
) {
2903 printf("finished oplock test 2\n");
2908 /* handler for oplock 3 tests */
2909 static bool oplock3_handler(struct cli_state
*cli
, int fnum
, unsigned char level
)
2911 printf("got oplock break fnum=%d level=%d\n",
2913 return cli_oplock_ack(cli
, fnum
, level
);
2916 static bool run_oplock3(int dummy
)
2918 struct cli_state
*cli
;
2919 const char *fname
= "\\oplockt3.dat";
2921 char buf
[4] = "abcd";
2922 bool correct
= True
;
2923 volatile bool *shared_correct
;
2925 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
2926 *shared_correct
= True
;
2928 printf("starting oplock test 3\n");
2933 use_level_II_oplocks
= True
;
2934 if (!torture_open_connection(&cli
, 0)) {
2935 *shared_correct
= False
;
2939 /* try to trigger a oplock break in parent */
2940 fnum
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
);
2941 cli_write(cli
, fnum
, 0, buf
, 0, 4);
2947 use_level_II_oplocks
= True
;
2948 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
2951 cli_oplock_handler(cli
, oplock3_handler
);
2952 fnum
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
2953 cli_write(cli
, fnum
, 0, buf
, 0, 4);
2954 cli_close(cli
, fnum
);
2955 fnum
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
);
2956 cli
->timeout
= 20000;
2957 cli_receive_smb(cli
);
2958 printf("finished oplock test 3\n");
2960 return (correct
&& *shared_correct
);
2962 /* What are we looking for here? What's sucess and what's FAILURE? */
2968 Test delete on close semantics.
2970 static bool run_deletetest(int dummy
)
2972 struct cli_state
*cli1
= NULL
;
2973 struct cli_state
*cli2
= NULL
;
2974 const char *fname
= "\\delete.file";
2977 bool correct
= True
;
2979 printf("starting delete test\n");
2981 if (!torture_open_connection(&cli1
, 0)) {
2985 cli_sockopt(cli1
, sockops
);
2987 /* Test 1 - this should delete the file on close. */
2989 cli_setatr(cli1
, fname
, 0, 0);
2990 cli_unlink(cli1
, fname
);
2992 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
2993 0, FILE_OVERWRITE_IF
,
2994 FILE_DELETE_ON_CLOSE
, 0);
2997 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3004 uint32
*accinfo
= NULL
;
3006 cli_qfileinfo_test(cli1
, fnum1
, SMB_FILE_ACCESS_INFORMATION
, (char **)&accinfo
, &len
);
3008 printf("access mode = 0x%lx\n", *accinfo
);
3013 if (!cli_close(cli1
, fnum1
)) {
3014 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3019 fnum1
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
);
3021 printf("[1] open of %s succeeded (should fail)\n", fname
);
3026 printf("first delete on close test succeeded.\n");
3028 /* Test 2 - this should delete the file on close. */
3030 cli_setatr(cli1
, fname
, 0, 0);
3031 cli_unlink(cli1
, fname
);
3033 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3034 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3035 FILE_OVERWRITE_IF
, 0, 0);
3038 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3043 if (!cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3044 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3049 if (!cli_close(cli1
, fnum1
)) {
3050 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3055 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
);
3057 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3058 if (!cli_close(cli1
, fnum1
)) {
3059 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3063 cli_unlink(cli1
, fname
);
3065 printf("second delete on close test succeeded.\n");
3068 cli_setatr(cli1
, fname
, 0, 0);
3069 cli_unlink(cli1
, fname
);
3071 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3072 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0);
3075 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3080 /* This should fail with a sharing violation - open for delete is only compatible
3081 with SHARE_DELETE. */
3083 fnum2
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3084 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0);
3087 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3092 /* This should succeed. */
3094 fnum2
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3095 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0);
3098 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3103 if (!cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3104 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3109 if (!cli_close(cli1
, fnum1
)) {
3110 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3115 if (!cli_close(cli1
, fnum2
)) {
3116 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3121 /* This should fail - file should no longer be there. */
3123 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
);
3125 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3126 if (!cli_close(cli1
, fnum1
)) {
3127 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3129 cli_unlink(cli1
, fname
);
3133 printf("third delete on close test succeeded.\n");
3136 cli_setatr(cli1
, fname
, 0, 0);
3137 cli_unlink(cli1
, fname
);
3139 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3140 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0);
3143 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3148 /* This should succeed. */
3149 fnum2
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3150 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0);
3152 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3157 if (!cli_close(cli1
, fnum2
)) {
3158 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3163 if (!cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3164 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3169 /* This should fail - no more opens once delete on close set. */
3170 fnum2
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3171 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3174 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3178 printf("fourth delete on close test succeeded.\n");
3180 if (!cli_close(cli1
, fnum1
)) {
3181 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3187 cli_setatr(cli1
, fname
, 0, 0);
3188 cli_unlink(cli1
, fname
);
3190 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
3192 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3197 /* This should fail - only allowed on NT opens with DELETE access. */
3199 if (cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3200 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3205 if (!cli_close(cli1
, fnum1
)) {
3206 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3211 printf("fifth delete on close test succeeded.\n");
3214 cli_setatr(cli1
, fname
, 0, 0);
3215 cli_unlink(cli1
, fname
);
3217 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3218 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3219 FILE_OVERWRITE_IF
, 0, 0);
3222 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3227 /* This should fail - only allowed on NT opens with DELETE access. */
3229 if (cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3230 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3235 if (!cli_close(cli1
, fnum1
)) {
3236 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3241 printf("sixth delete on close test succeeded.\n");
3244 cli_setatr(cli1
, fname
, 0, 0);
3245 cli_unlink(cli1
, fname
);
3247 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3248 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0);
3251 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3256 if (!cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3257 printf("[7] setting delete_on_close on file failed !\n");
3262 if (!cli_nt_delete_on_close(cli1
, fnum1
, False
)) {
3263 printf("[7] unsetting delete_on_close on file failed !\n");
3268 if (!cli_close(cli1
, fnum1
)) {
3269 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3274 /* This next open should succeed - we reset the flag. */
3276 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
);
3278 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3283 if (!cli_close(cli1
, fnum1
)) {
3284 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3289 printf("seventh delete on close test succeeded.\n");
3292 cli_setatr(cli1
, fname
, 0, 0);
3293 cli_unlink(cli1
, fname
);
3295 if (!torture_open_connection(&cli2
, 1)) {
3296 printf("[8] failed to open second connection.\n");
3301 cli_sockopt(cli1
, sockops
);
3303 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3304 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3305 FILE_OVERWRITE_IF
, 0, 0);
3308 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3313 fnum2
= cli_nt_create_full(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3314 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3318 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3323 if (!cli_nt_delete_on_close(cli1
, fnum1
, True
)) {
3324 printf("[8] setting delete_on_close on file failed !\n");
3329 if (!cli_close(cli1
, fnum1
)) {
3330 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3335 if (!cli_close(cli2
, fnum2
)) {
3336 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3341 /* This should fail.. */
3342 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
);
3344 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3348 printf("eighth delete on close test succeeded.\n");
3350 /* This should fail - we need to set DELETE_ACCESS. */
3351 fnum1
= cli_nt_create_full(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3352 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0);
3355 printf("[9] open of %s succeeded should have failed!\n", fname
);
3360 printf("ninth delete on close test succeeded.\n");
3362 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3363 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0);
3365 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3370 /* This should delete the file. */
3371 if (!cli_close(cli1
, fnum1
)) {
3372 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3377 /* This should fail.. */
3378 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
);
3380 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3384 printf("tenth delete on close test succeeded.\n");
3386 cli_setatr(cli1
, fname
, 0, 0);
3387 cli_unlink(cli1
, fname
);
3389 /* What error do we get when attempting to open a read-only file with
3392 /* Create a readonly file. */
3393 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3394 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3396 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3401 if (!cli_close(cli1
, fnum1
)) {
3402 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3407 /* Now try open for delete access. */
3408 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3409 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3410 FILE_OVERWRITE_IF
, 0, 0);
3413 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3414 cli_close(cli1
, fnum1
);
3418 NTSTATUS nterr
= cli_nt_error(cli1
);
3419 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
3420 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
3424 printf("eleventh delete on close test succeeded.\n");
3428 printf("finished delete test\n");
3431 /* FIXME: This will crash if we aborted before cli2 got
3432 * intialized, because these functions don't handle
3433 * uninitialized connections. */
3435 if (fnum1
!= -1) cli_close(cli1
, fnum1
);
3436 if (fnum2
!= -1) cli_close(cli1
, fnum2
);
3437 cli_setatr(cli1
, fname
, 0, 0);
3438 cli_unlink(cli1
, fname
);
3440 if (cli1
&& !torture_close_connection(cli1
)) {
3443 if (cli2
&& !torture_close_connection(cli2
)) {
3451 print out server properties
3453 static bool run_properties(int dummy
)
3455 static struct cli_state
*cli
;
3456 bool correct
= True
;
3458 printf("starting properties test\n");
3462 if (!torture_open_connection(&cli
, 0)) {
3466 cli_sockopt(cli
, sockops
);
3468 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
3470 if (!torture_close_connection(cli
)) {
3479 /* FIRST_DESIRED_ACCESS 0xf019f */
3480 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3481 FILE_READ_EA| /* 0xf */ \
3482 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3483 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3484 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3485 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3486 /* SECOND_DESIRED_ACCESS 0xe0080 */
3487 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3488 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3489 WRITE_OWNER_ACCESS /* 0xe0000 */
3492 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3493 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3495 WRITE_OWNER_ACCESS /* */
3499 Test ntcreate calls made by xcopy
3501 static bool run_xcopy(int dummy
)
3503 static struct cli_state
*cli1
;
3504 const char *fname
= "\\test.txt";
3505 bool correct
= True
;
3508 printf("starting xcopy test\n");
3510 if (!torture_open_connection(&cli1
, 0)) {
3514 fnum1
= cli_nt_create_full(cli1
, fname
, 0,
3515 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
3516 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
3520 printf("First open failed - %s\n", cli_errstr(cli1
));
3524 fnum2
= cli_nt_create_full(cli1
, fname
, 0,
3525 SECOND_DESIRED_ACCESS
, 0,
3526 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
3529 printf("second open failed - %s\n", cli_errstr(cli1
));
3533 if (!torture_close_connection(cli1
)) {
3541 Test rename on files open with share delete and no share delete.
3543 static bool run_rename(int dummy
)
3545 static struct cli_state
*cli1
;
3546 const char *fname
= "\\test.txt";
3547 const char *fname1
= "\\test1.txt";
3548 bool correct
= True
;
3551 printf("starting rename test\n");
3553 if (!torture_open_connection(&cli1
, 0)) {
3557 cli_unlink(cli1
, fname
);
3558 cli_unlink(cli1
, fname1
);
3559 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3560 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0);
3563 printf("First open failed - %s\n", cli_errstr(cli1
));
3567 if (!cli_rename(cli1
, fname
, fname1
)) {
3568 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
3570 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3574 if (!cli_close(cli1
, fnum1
)) {
3575 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
3579 cli_unlink(cli1
, fname
);
3580 cli_unlink(cli1
, fname1
);
3581 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3583 FILE_SHARE_DELETE
|FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3585 FILE_SHARE_DELETE
|FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0);
3589 printf("Second open failed - %s\n", cli_errstr(cli1
));
3593 if (!cli_rename(cli1
, fname
, fname1
)) {
3594 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
3597 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3600 if (!cli_close(cli1
, fnum1
)) {
3601 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
3605 cli_unlink(cli1
, fname
);
3606 cli_unlink(cli1
, fname1
);
3608 fnum1
= cli_nt_create_full(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3609 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3612 printf("Third open failed - %s\n", cli_errstr(cli1
));
3621 fnum2
= cli_nt_create_full(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3622 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3625 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3628 if (!cli_nt_delete_on_close(cli1
, fnum2
, True
)) {
3629 printf("[8] setting delete_on_close on file failed !\n");
3633 if (!cli_close(cli1
, fnum2
)) {
3634 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3640 if (!cli_rename(cli1
, fname
, fname1
)) {
3641 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
3644 printf("Third rename succeeded (SHARE_NONE)\n");
3647 if (!cli_close(cli1
, fnum1
)) {
3648 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
3652 cli_unlink(cli1
, fname
);
3653 cli_unlink(cli1
, fname1
);
3657 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3658 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0);
3661 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3665 if (!cli_rename(cli1
, fname
, fname1
)) {
3666 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
3668 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3672 if (!cli_close(cli1
, fnum1
)) {
3673 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3677 cli_unlink(cli1
, fname
);
3678 cli_unlink(cli1
, fname1
);
3682 fnum1
= cli_nt_create_full(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3683 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0);
3686 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
3690 if (!cli_rename(cli1
, fname
, fname1
)) {
3691 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3695 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
3699 * Now check if the first name still exists ...
3702 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3703 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3706 printf("Opening original file after rename of open file fails: %s\n",
3710 printf("Opening original file after rename of open file works ...\n");
3711 (void)cli_close(cli1, fnum2);
3717 if (!cli_close(cli1
, fnum1
)) {
3718 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
3722 cli_unlink(cli1
, fname
);
3723 cli_unlink(cli1
, fname1
);
3725 if (!torture_close_connection(cli1
)) {
3732 static bool run_pipe_number(int dummy
)
3734 struct cli_state
*cli1
;
3735 const char *pipe_name
= "\\SPOOLSS";
3739 printf("starting pipenumber test\n");
3740 if (!torture_open_connection(&cli1
, 0)) {
3744 cli_sockopt(cli1
, sockops
);
3746 fnum
= cli_nt_create_full(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
3747 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0);
3750 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
3754 printf("\r%6d", num_pipes
);
3757 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
3758 torture_close_connection(cli1
);
3763 Test open mode returns on read-only files.
3765 static bool run_opentest(int dummy
)
3767 static struct cli_state
*cli1
;
3768 static struct cli_state
*cli2
;
3769 const char *fname
= "\\readonly.file";
3773 bool correct
= True
;
3776 printf("starting open test\n");
3778 if (!torture_open_connection(&cli1
, 0)) {
3782 cli_setatr(cli1
, fname
, 0, 0);
3783 cli_unlink(cli1
, fname
);
3785 cli_sockopt(cli1
, sockops
);
3787 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3789 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3793 if (!cli_close(cli1
, fnum1
)) {
3794 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3798 if (!cli_setatr(cli1
, fname
, aRONLY
, 0)) {
3799 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
3803 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
);
3805 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3809 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3810 fnum2
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
);
3812 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
3813 NT_STATUS_ACCESS_DENIED
)) {
3814 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3817 printf("finished open test 1\n");
3819 cli_close(cli1
, fnum1
);
3821 /* Now try not readonly and ensure ERRbadshare is returned. */
3823 cli_setatr(cli1
, fname
, 0, 0);
3825 fnum1
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
);
3827 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3831 /* This will fail - but the error should be ERRshare. */
3832 fnum2
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
);
3834 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
3835 NT_STATUS_SHARING_VIOLATION
)) {
3836 printf("correct error code ERRDOS/ERRbadshare returned\n");
3839 if (!cli_close(cli1
, fnum1
)) {
3840 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3844 cli_unlink(cli1
, fname
);
3846 printf("finished open test 2\n");
3848 /* Test truncate open disposition on file opened for read. */
3850 fnum1
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3852 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3856 /* write 20 bytes. */
3858 memset(buf
, '\0', 20);
3860 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
3861 printf("write failed (%s)\n", cli_errstr(cli1
));
3865 if (!cli_close(cli1
, fnum1
)) {
3866 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
3870 /* Ensure size == 20. */
3871 if (!cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
)) {
3872 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
3877 printf("(3) file size != 20\n");
3881 /* Now test if we can truncate a file opened for readonly. */
3883 fnum1
= cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
3885 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3889 if (!cli_close(cli1
, fnum1
)) {
3890 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3894 /* Ensure size == 0. */
3895 if (!cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
)) {
3896 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
3901 printf("(3) file size != 0\n");
3904 printf("finished open test 3\n");
3906 cli_unlink(cli1
, fname
);
3909 printf("testing ctemp\n");
3910 fnum1
= cli_ctemp(cli1
, "\\", &tmp_path
);
3912 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
3915 printf("ctemp gave path %s\n", tmp_path
);
3916 if (!cli_close(cli1
, fnum1
)) {
3917 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
3919 if (!cli_unlink(cli1
, tmp_path
)) {
3920 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
3923 /* Test the non-io opens... */
3925 if (!torture_open_connection(&cli2
, 1)) {
3929 cli_setatr(cli2
, fname
, 0, 0);
3930 cli_unlink(cli2
, fname
);
3932 cli_sockopt(cli2
, sockops
);
3934 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3936 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
3937 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3940 printf("test 1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3944 fnum2
= cli_nt_create_full(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
3945 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0);
3948 printf("test 1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3952 if (!cli_close(cli1
, fnum1
)) {
3953 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3956 if (!cli_close(cli2
, fnum2
)) {
3957 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3961 printf("non-io open test #1 passed.\n");
3963 cli_unlink(cli1
, fname
);
3965 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3967 fnum1
= cli_nt_create_full(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
3968 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
3971 printf("test 2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3975 fnum2
= cli_nt_create_full(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
3976 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0);
3979 printf("test 2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3983 if (!cli_close(cli1
, fnum1
)) {
3984 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3987 if (!cli_close(cli2
, fnum2
)) {
3988 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3992 printf("non-io open test #2 passed.\n");
3994 cli_unlink(cli1
, fname
);
3996 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3998 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
3999 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
4002 printf("test 3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4006 fnum2
= cli_nt_create_full(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4007 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0);
4010 printf("test 3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4014 if (!cli_close(cli1
, fnum1
)) {
4015 printf("test 3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4018 if (!cli_close(cli2
, fnum2
)) {
4019 printf("test 3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4023 printf("non-io open test #3 passed.\n");
4025 cli_unlink(cli1
, fname
);
4027 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4029 fnum1
= cli_nt_create_full(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4030 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
4033 printf("test 4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4037 fnum2
= cli_nt_create_full(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4038 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0);
4041 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4045 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4047 if (!cli_close(cli1
, fnum1
)) {
4048 printf("test 4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4052 printf("non-io open test #4 passed.\n");
4054 cli_unlink(cli1
, fname
);
4056 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4058 fnum1
= cli_nt_create_full(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4059 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0);
4062 printf("test 5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4066 fnum2
= cli_nt_create_full(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4067 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0);
4070 printf("test 5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4074 if (!cli_close(cli1
, fnum1
)) {
4075 printf("test 5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4079 if (!cli_close(cli2
, fnum2
)) {
4080 printf("test 5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4084 printf("non-io open test #5 passed.\n");
4086 printf("TEST #6 testing 1 non-io open, one io open\n");
4088 cli_unlink(cli1
, fname
);
4090 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4091 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
4094 printf("test 6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4098 fnum2
= cli_nt_create_full(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4099 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0);
4102 printf("test 6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4106 if (!cli_close(cli1
, fnum1
)) {
4107 printf("test 6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4111 if (!cli_close(cli2
, fnum2
)) {
4112 printf("test 6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4116 printf("non-io open test #6 passed.\n");
4118 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4120 cli_unlink(cli1
, fname
);
4122 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4123 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
4126 printf("test 7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4130 fnum2
= cli_nt_create_full(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4131 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0);
4134 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4138 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4140 if (!cli_close(cli1
, fnum1
)) {
4141 printf("test 7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4145 printf("non-io open test #7 passed.\n");
4147 cli_unlink(cli1
, fname
);
4149 if (!torture_close_connection(cli1
)) {
4152 if (!torture_close_connection(cli2
)) {
4160 Test POSIX open /mkdir calls.
4162 static bool run_simple_posix_open_test(int dummy
)
4164 static struct cli_state
*cli1
;
4165 const char *fname
= "\\posix:file";
4166 const char *dname
= "\\posix:dir";
4167 uint16 major
, minor
;
4168 uint32 caplow
, caphigh
;
4170 bool correct
= false;
4172 printf("Starting simple POSIX open test\n");
4174 if (!torture_open_connection(&cli1
, 0)) {
4178 cli_sockopt(cli1
, sockops
);
4180 if (!SERVER_HAS_UNIX_CIFS(cli1
)) {
4181 printf("Server doesn't support UNIX CIFS extensions.\n");
4185 if (!cli_unix_extensions_version(cli1
, &major
,
4186 &minor
, &caplow
, &caphigh
)) {
4187 printf("Server didn't return UNIX CIFS extensions.\n");
4191 if (!cli_set_unix_extensions_capabilities(cli1
,
4192 major
, minor
, caplow
, caphigh
)) {
4193 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4197 cli_setatr(cli1
, fname
, 0, 0);
4198 cli_posix_unlink(cli1
, fname
);
4199 cli_setatr(cli1
, dname
, 0, 0);
4200 cli_posix_rmdir(cli1
, dname
);
4202 /* Create a directory. */
4203 if (cli_posix_mkdir(cli1
, dname
, 0777) == -1) {
4204 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4208 fnum1
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600);
4210 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4214 if (!cli_close(cli1
, fnum1
)) {
4215 printf("close failed (%s)\n", cli_errstr(cli1
));
4219 /* Now open the file again for read only. */
4220 fnum1
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0);
4222 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4226 /* Now unlink while open. */
4227 if (!cli_posix_unlink(cli1
, fname
)) {
4228 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4232 if (!cli_close(cli1
, fnum1
)) {
4233 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4237 /* Ensure the file has gone. */
4238 fnum1
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0);
4240 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4244 if (!cli_posix_rmdir(cli1
, dname
)) {
4245 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
4249 printf("Simple POSIX open test passed\n");
4255 cli_close(cli1
, fnum1
);
4259 cli_setatr(cli1
, fname
, 0, 0);
4260 cli_posix_unlink(cli1
, fname
);
4261 cli_setatr(cli1
, dname
, 0, 0);
4262 cli_posix_rmdir(cli1
, dname
);
4264 if (!torture_close_connection(cli1
)) {
4272 static uint32 open_attrs_table
[] = {
4273 FILE_ATTRIBUTE_NORMAL
,
4274 FILE_ATTRIBUTE_ARCHIVE
,
4275 FILE_ATTRIBUTE_READONLY
,
4276 FILE_ATTRIBUTE_HIDDEN
,
4277 FILE_ATTRIBUTE_SYSTEM
,
4279 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
4280 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
4281 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
4282 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4283 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4284 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4286 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4287 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4288 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4289 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
4292 struct trunc_open_results
{
4299 static struct trunc_open_results attr_results
[] = {
4300 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4301 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4302 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4303 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4304 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4305 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4306 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4307 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4308 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4309 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4310 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4311 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
4312 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4313 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4314 { 104, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4315 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4316 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4317 { 121, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
4318 { 170, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
|FILE_ATTRIBUTE_HIDDEN
},
4319 { 173, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
},
4320 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4321 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4322 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4323 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4324 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4325 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
4328 static bool run_openattrtest(int dummy
)
4330 static struct cli_state
*cli1
;
4331 const char *fname
= "\\openattr.file";
4333 bool correct
= True
;
4335 unsigned int i
, j
, k
, l
;
4337 printf("starting open attr test\n");
4339 if (!torture_open_connection(&cli1
, 0)) {
4343 cli_sockopt(cli1
, sockops
);
4345 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
4346 cli_setatr(cli1
, fname
, 0, 0);
4347 cli_unlink(cli1
, fname
);
4348 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
4349 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0);
4352 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4356 if (!cli_close(cli1
, fnum1
)) {
4357 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4361 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
4362 fnum1
= cli_nt_create_full(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
4363 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0);
4366 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4367 if (attr_results
[l
].num
== k
) {
4368 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4369 k
, open_attrs_table
[i
],
4370 open_attrs_table
[j
],
4371 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
4375 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
4376 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4377 k
, open_attrs_table
[i
], open_attrs_table
[j
],
4382 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
4388 if (!cli_close(cli1
, fnum1
)) {
4389 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
4393 if (!cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
)) {
4394 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
4399 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4400 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
4403 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4404 if (attr_results
[l
].num
== k
) {
4405 if (attr
!= attr_results
[l
].result_attr
||
4406 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
4407 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
4408 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4409 open_attrs_table
[i
],
4410 open_attrs_table
[j
],
4412 attr_results
[l
].result_attr
);
4422 cli_setatr(cli1
, fname
, 0, 0);
4423 cli_unlink(cli1
, fname
);
4425 printf("open attr test %s.\n", correct
? "passed" : "failed");
4427 if (!torture_close_connection(cli1
)) {
4433 static void list_fn(const char *mnt
, file_info
*finfo
, const char *name
, void *state
)
4439 test directory listing speed
4441 static bool run_dirtest(int dummy
)
4444 static struct cli_state
*cli
;
4447 bool correct
= True
;
4449 printf("starting directory test\n");
4451 if (!torture_open_connection(&cli
, 0)) {
4455 cli_sockopt(cli
, sockops
);
4458 for (i
=0;i
<torture_numops
;i
++) {
4460 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4461 fnum
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
4463 fprintf(stderr
,"Failed to open %s\n", fname
);
4466 cli_close(cli
, fnum
);
4471 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
4472 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
4473 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
4475 printf("dirtest core %g seconds\n", end_timer() - t1
);
4478 for (i
=0;i
<torture_numops
;i
++) {
4480 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4481 cli_unlink(cli
, fname
);
4484 if (!torture_close_connection(cli
)) {
4488 printf("finished dirtest\n");
4493 static void del_fn(const char *mnt
, file_info
*finfo
, const char *mask
, void *state
)
4495 struct cli_state
*pcli
= (struct cli_state
*)state
;
4497 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
4499 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
4502 if (finfo
->mode
& aDIR
) {
4503 if (!cli_rmdir(pcli
, fname
))
4504 printf("del_fn: failed to rmdir %s\n,", fname
);
4506 if (!cli_unlink(pcli
, fname
))
4507 printf("del_fn: failed to unlink %s\n,", fname
);
4513 sees what IOCTLs are supported
4515 bool torture_ioctl_test(int dummy
)
4517 static struct cli_state
*cli
;
4518 uint16 device
, function
;
4520 const char *fname
= "\\ioctl.dat";
4524 if (!torture_open_connection(&cli
, 0)) {
4528 printf("starting ioctl test\n");
4530 cli_unlink(cli
, fname
);
4532 fnum
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4534 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4538 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
4539 printf("ioctl device info: %s\n", cli_errstr(cli
));
4541 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
4542 printf("ioctl job info: %s\n", cli_errstr(cli
));
4544 for (device
=0;device
<0x100;device
++) {
4545 printf("testing device=0x%x\n", device
);
4546 for (function
=0;function
<0x100;function
++) {
4547 uint32 code
= (device
<<16) | function
;
4549 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
4551 if (NT_STATUS_IS_OK(status
)) {
4552 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
4554 data_blob_free(&blob
);
4559 if (!torture_close_connection(cli
)) {
4568 tries varients of chkpath
4570 bool torture_chkpath_test(int dummy
)
4572 static struct cli_state
*cli
;
4576 if (!torture_open_connection(&cli
, 0)) {
4580 printf("starting chkpath test\n");
4582 /* cleanup from an old run */
4583 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4584 cli_unlink(cli
, "\\chkpath.dir\\*");
4585 cli_rmdir(cli
, "\\chkpath.dir");
4587 if (!cli_mkdir(cli
, "\\chkpath.dir")) {
4588 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
4592 if (!cli_mkdir(cli
, "\\chkpath.dir\\dir2")) {
4593 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
4597 fnum
= cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4599 printf("open1 failed (%s)\n", cli_errstr(cli
));
4602 cli_close(cli
, fnum
);
4604 if (!cli_chkpath(cli
, "\\chkpath.dir")) {
4605 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
4609 if (!cli_chkpath(cli
, "\\chkpath.dir\\dir2")) {
4610 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
4614 if (!cli_chkpath(cli
, "\\chkpath.dir\\foo.txt")) {
4615 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4616 NT_STATUS_NOT_A_DIRECTORY
);
4618 printf("* chkpath on a file should fail\n");
4622 if (!cli_chkpath(cli
, "\\chkpath.dir\\bar.txt")) {
4623 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
4624 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
4626 printf("* chkpath on a non existant file should fail\n");
4630 if (!cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt")) {
4631 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4632 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
4634 printf("* chkpath on a non existent component should fail\n");
4638 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4639 cli_unlink(cli
, "\\chkpath.dir\\*");
4640 cli_rmdir(cli
, "\\chkpath.dir");
4642 if (!torture_close_connection(cli
)) {
4649 static bool run_eatest(int dummy
)
4651 static struct cli_state
*cli
;
4652 const char *fname
= "\\eatest.txt";
4653 bool correct
= True
;
4656 struct ea_struct
*ea_list
= NULL
;
4657 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
4659 printf("starting eatest\n");
4661 if (!torture_open_connection(&cli
, 0)) {
4662 talloc_destroy(mem_ctx
);
4666 cli_unlink(cli
, fname
);
4667 fnum
= cli_nt_create_full(cli
, fname
, 0,
4668 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
4669 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
4673 printf("open failed - %s\n", cli_errstr(cli
));
4674 talloc_destroy(mem_ctx
);
4678 for (i
= 0; i
< 10; i
++) {
4679 fstring ea_name
, ea_val
;
4681 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
4682 memset(ea_val
, (char)i
+1, i
+1);
4683 if (!cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1)) {
4684 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
4685 talloc_destroy(mem_ctx
);
4690 cli_close(cli
, fnum
);
4691 for (i
= 0; i
< 10; i
++) {
4692 fstring ea_name
, ea_val
;
4694 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
4695 memset(ea_val
, (char)i
+1, i
+1);
4696 if (!cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1)) {
4697 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
4698 talloc_destroy(mem_ctx
);
4703 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
4704 printf("ea_get list failed - %s\n", cli_errstr(cli
));
4708 printf("num_eas = %d\n", (int)num_eas
);
4710 if (num_eas
!= 20) {
4711 printf("Should be 20 EA's stored... failing.\n");
4715 for (i
= 0; i
< num_eas
; i
++) {
4716 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
4717 dump_data(0, ea_list
[i
].value
.data
,
4718 ea_list
[i
].value
.length
);
4721 /* Setting EA's to zero length deletes them. Test this */
4722 printf("Now deleting all EA's - case indepenent....\n");
4725 cli_set_ea_path(cli
, fname
, "", "", 0);
4727 for (i
= 0; i
< 20; i
++) {
4729 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
4730 if (!cli_set_ea_path(cli
, fname
, ea_name
, "", 0)) {
4731 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
4732 talloc_destroy(mem_ctx
);
4738 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
4739 printf("ea_get list failed - %s\n", cli_errstr(cli
));
4743 printf("num_eas = %d\n", (int)num_eas
);
4744 for (i
= 0; i
< num_eas
; i
++) {
4745 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
4746 dump_data(0, ea_list
[i
].value
.data
,
4747 ea_list
[i
].value
.length
);
4751 printf("deleting EA's failed.\n");
4755 /* Try and delete a non existant EA. */
4756 if (!cli_set_ea_path(cli
, fname
, "foo", "", 0)) {
4757 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli
));
4761 talloc_destroy(mem_ctx
);
4762 if (!torture_close_connection(cli
)) {
4769 static bool run_dirtest1(int dummy
)
4772 static struct cli_state
*cli
;
4774 bool correct
= True
;
4776 printf("starting directory test\n");
4778 if (!torture_open_connection(&cli
, 0)) {
4782 cli_sockopt(cli
, sockops
);
4784 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
4785 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
4786 cli_rmdir(cli
, "\\LISTDIR");
4787 cli_mkdir(cli
, "\\LISTDIR");
4789 /* Create 1000 files and 1000 directories. */
4790 for (i
=0;i
<1000;i
++) {
4792 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
4793 fnum
= cli_nt_create_full(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
4794 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0);
4796 fprintf(stderr
,"Failed to open %s\n", fname
);
4799 cli_close(cli
, fnum
);
4801 for (i
=0;i
<1000;i
++) {
4803 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
4804 if (!cli_mkdir(cli
, fname
)) {
4805 fprintf(stderr
,"Failed to open %s\n", fname
);
4810 /* Now ensure that doing an old list sees both files and directories. */
4811 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, NULL
);
4812 printf("num_seen = %d\n", num_seen
);
4813 /* We should see 100 files + 1000 directories + . and .. */
4814 if (num_seen
!= 2002)
4817 /* Ensure if we have the "must have" bits we only see the
4820 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, NULL
);
4821 printf("num_seen = %d\n", num_seen
);
4822 if (num_seen
!= 1002)
4825 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, NULL
);
4826 printf("num_seen = %d\n", num_seen
);
4827 if (num_seen
!= 1000)
4830 /* Delete everything. */
4831 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
4832 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
4833 cli_rmdir(cli
, "\\LISTDIR");
4836 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
4837 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
4838 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
4841 if (!torture_close_connection(cli
)) {
4845 printf("finished dirtest1\n");
4850 static bool run_error_map_extract(int dummy
) {
4852 static struct cli_state
*c_dos
;
4853 static struct cli_state
*c_nt
;
4858 uint32 flgs2
, errnum
;
4865 /* NT-Error connection */
4867 if (!(c_nt
= open_nbt_connection())) {
4871 c_nt
->use_spnego
= False
;
4873 status
= cli_negprot(c_nt
);
4875 if (!NT_STATUS_IS_OK(status
)) {
4876 printf("%s rejected the NT-error negprot (%s)\n", host
,
4882 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
4884 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
4888 /* DOS-Error connection */
4890 if (!(c_dos
= open_nbt_connection())) {
4894 c_dos
->use_spnego
= False
;
4895 c_dos
->force_dos_errors
= True
;
4897 status
= cli_negprot(c_dos
);
4898 if (!NT_STATUS_IS_OK(status
)) {
4899 printf("%s rejected the DOS-error negprot (%s)\n", host
,
4901 cli_shutdown(c_dos
);
4905 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
4907 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
4911 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
4912 fstr_sprintf(user
, "%X", error
);
4914 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
4915 password
, strlen(password
),
4916 password
, strlen(password
),
4918 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4921 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
4923 /* Case #1: 32-bit NT errors */
4924 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
4925 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
4927 printf("/** Dos error on NT connection! (%s) */\n",
4929 nt_status
= NT_STATUS(0xc0000000);
4932 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
4933 password
, strlen(password
),
4934 password
, strlen(password
),
4936 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4938 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
4940 /* Case #1: 32-bit NT errors */
4941 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
4942 printf("/** NT error on DOS connection! (%s) */\n",
4944 errnum
= errclass
= 0;
4946 cli_dos_error(c_dos
, &errclass
, &errnum
);
4949 if (NT_STATUS_V(nt_status
) != error
) {
4950 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4951 get_nt_error_c_code(NT_STATUS(error
)),
4952 get_nt_error_c_code(nt_status
));
4955 printf("\t{%s,\t%s,\t%s},\n",
4956 smb_dos_err_class(errclass
),
4957 smb_dos_err_name(errclass
, errnum
),
4958 get_nt_error_c_code(NT_STATUS(error
)));
4963 static bool run_sesssetup_bench(int dummy
)
4965 static struct cli_state
*c
;
4966 const char *fname
= "\\file.dat";
4971 if (!torture_open_connection(&c
, 0)) {
4975 fnum
= cli_nt_create_full(
4976 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
4977 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4978 FILE_DELETE_ON_CLOSE
, 0);
4980 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
4984 for (i
=0; i
<torture_numops
; i
++) {
4985 status
= cli_session_setup(
4987 password
, strlen(password
),
4988 password
, strlen(password
),
4990 if (!NT_STATUS_IS_OK(status
)) {
4991 d_printf("(%s) cli_session_setup failed: %s\n",
4992 __location__
, nt_errstr(status
));
4996 d_printf("\r%d ", (int)c
->vuid
);
4998 if (!cli_ulogoff(c
)) {
4999 d_printf("(%s) cli_ulogoff failed: %s\n",
5000 __location__
, cli_errstr(c
));
5009 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5010 uid_t uid
, gid_t gid
, const char *expected
)
5015 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5017 if (strcmp(subst
, expected
) != 0) {
5018 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5019 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5028 static void chain1_open_completion(struct tevent_req
*req
)
5032 status
= cli_open_recv(req
, &fnum
);
5035 d_printf("cli_open_recv returned %s: %d\n",
5037 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5040 static void chain1_write_completion(struct tevent_req
*req
)
5044 status
= cli_write_andx_recv(req
, &written
);
5047 d_printf("cli_write_andx_recv returned %s: %d\n",
5049 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5052 static void chain1_close_completion(struct tevent_req
*req
)
5055 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5057 status
= cli_close_recv(req
);
5062 d_printf("cli_close returned %s\n", nt_errstr(status
));
5065 static bool run_chain1(int dummy
)
5067 struct cli_state
*cli1
;
5068 struct event_context
*evt
= event_context_init(NULL
);
5069 struct tevent_req
*reqs
[3], *smbreqs
[3];
5071 const char *str
= "foobar";
5073 printf("starting chain1 test\n");
5074 if (!torture_open_connection(&cli1
, 0)) {
5078 cli_sockopt(cli1
, sockops
);
5080 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5081 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5082 if (reqs
[0] == NULL
) return false;
5083 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5086 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5087 (uint8_t *)str
, 0, strlen(str
)+1,
5088 smbreqs
, 1, &smbreqs
[1]);
5089 if (reqs
[1] == NULL
) return false;
5090 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5092 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5093 if (reqs
[2] == NULL
) return false;
5094 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5096 if (!cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
))) {
5101 event_loop_once(evt
);
5104 torture_close_connection(cli1
);
5108 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
5110 size_t *to_pull
= (size_t *)priv
;
5111 size_t thistime
= *to_pull
;
5113 thistime
= MIN(thistime
, n
);
5114 if (thistime
== 0) {
5118 memset(buf
, 0, thistime
);
5119 *to_pull
-= thistime
;
5123 static bool run_windows_write(int dummy
)
5125 struct cli_state
*cli1
;
5129 const char *fname
= "\\writetest.txt";
5133 printf("starting windows_write test\n");
5134 if (!torture_open_connection(&cli1
, 0)) {
5138 fnum
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
5140 printf("open failed (%s)\n", cli_errstr(cli1
));
5144 cli_sockopt(cli1
, sockops
);
5148 for (i
=0; i
<torture_numops
; i
++) {
5150 off_t start
= i
* torture_blocksize
;
5152 size_t to_pull
= torture_blocksize
- 1;
5154 if (cli_write(cli1
, fnum
, 0, &c
,
5155 start
+ torture_blocksize
- 1, 1) != 1) {
5156 printf("cli_write failed: %s\n", cli_errstr(cli1
));
5160 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
5161 null_source
, &to_pull
);
5162 if (!NT_STATUS_IS_OK(status
)) {
5163 printf("cli_push returned: %s\n", nt_errstr(status
));
5168 seconds
= end_timer();
5169 kbytes
= (double)torture_blocksize
* torture_numops
;
5172 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
5173 (double)seconds
, (int)(kbytes
/seconds
));
5177 cli_close(cli1
, fnum
);
5178 cli_unlink(cli1
, fname
);
5179 torture_close_connection(cli1
);
5183 static bool run_cli_echo(int dummy
)
5185 struct cli_state
*cli
;
5188 printf("starting cli_echo test\n");
5189 if (!torture_open_connection(&cli
, 0)) {
5192 cli_sockopt(cli
, sockops
);
5194 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
5196 d_printf("cli_echo returned %s\n", nt_errstr(status
));
5198 torture_close_connection(cli
);
5199 return NT_STATUS_IS_OK(status
);
5202 static bool run_local_substitute(int dummy
)
5206 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
5207 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5208 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5209 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5210 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
5211 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
5212 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5213 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5215 /* Different captialization rules in sub_basic... */
5217 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5223 static bool run_local_gencache(int dummy
)
5229 if (!gencache_init()) {
5230 d_printf("%s: gencache_init() failed\n", __location__
);
5234 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
5235 d_printf("%s: gencache_set() failed\n", __location__
);
5239 if (!gencache_get("foo", &val
, &tm
)) {
5240 d_printf("%s: gencache_get() failed\n", __location__
);
5244 if (strcmp(val
, "bar") != 0) {
5245 d_printf("%s: gencache_get() returned %s, expected %s\n",
5246 __location__
, val
, "bar");
5253 if (!gencache_del("foo")) {
5254 d_printf("%s: gencache_del() failed\n", __location__
);
5257 if (gencache_del("foo")) {
5258 d_printf("%s: second gencache_del() succeeded\n",
5263 if (gencache_get("foo", &val
, &tm
)) {
5264 d_printf("%s: gencache_get() on deleted entry "
5265 "succeeded\n", __location__
);
5269 blob
= data_blob_string_const_null("bar");
5272 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
5273 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
5277 data_blob_free(&blob
);
5279 if (!gencache_get_data_blob("foo", &blob
, NULL
)) {
5280 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
5284 if (strcmp((const char *)blob
.data
, "bar") != 0) {
5285 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5286 __location__
, (const char *)blob
.data
, "bar");
5287 data_blob_free(&blob
);
5291 data_blob_free(&blob
);
5293 if (!gencache_del("foo")) {
5294 d_printf("%s: gencache_del() failed\n", __location__
);
5297 if (gencache_del("foo")) {
5298 d_printf("%s: second gencache_del() succeeded\n",
5303 if (gencache_get_data_blob("foo", &blob
, NULL
)) {
5304 d_printf("%s: gencache_get_data_blob() on deleted entry "
5305 "succeeded\n", __location__
);
5309 if (!gencache_shutdown()) {
5310 d_printf("%s: gencache_shutdown() failed\n", __location__
);
5314 if (gencache_shutdown()) {
5315 d_printf("%s: second gencache_shutdown() succeeded\n",
5323 static bool rbt_testval(struct db_context
*db
, const char *key
,
5326 struct db_record
*rec
;
5327 TDB_DATA data
= string_tdb_data(value
);
5331 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
5333 d_fprintf(stderr
, "fetch_locked failed\n");
5336 status
= rec
->store(rec
, data
, 0);
5337 if (!NT_STATUS_IS_OK(status
)) {
5338 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
5343 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
5345 d_fprintf(stderr
, "second fetch_locked failed\n");
5348 if ((rec
->value
.dsize
!= data
.dsize
)
5349 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
5350 d_fprintf(stderr
, "Got wrong data back\n");
5360 static bool run_local_rbtree(int dummy
)
5362 struct db_context
*db
;
5366 db
= db_open_rbt(NULL
);
5369 d_fprintf(stderr
, "db_open_rbt failed\n");
5373 for (i
=0; i
<1000; i
++) {
5376 if (asprintf(&key
, "key%ld", random()) == -1) {
5379 if (asprintf(&value
, "value%ld", random()) == -1) {
5384 if (!rbt_testval(db
, key
, value
)) {
5391 if (asprintf(&value
, "value%ld", random()) == -1) {
5396 if (!rbt_testval(db
, key
, value
)) {
5413 static bool test_stream_name(const char *fname
, const char *expected_base
,
5414 const char *expected_stream
,
5415 NTSTATUS expected_status
)
5419 char *stream
= NULL
;
5421 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
5422 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
5426 if (!NT_STATUS_IS_OK(status
)) {
5430 if (base
== NULL
) goto error
;
5432 if (strcmp(expected_base
, base
) != 0) goto error
;
5434 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
5435 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
5437 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
5441 TALLOC_FREE(stream
);
5445 d_fprintf(stderr
, "test_stream(%s, %s, %s, %s)\n",
5446 fname
, expected_base
? expected_base
: "<NULL>",
5447 expected_stream
? expected_stream
: "<NULL>",
5448 nt_errstr(expected_status
));
5449 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
5450 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
5453 TALLOC_FREE(stream
);
5457 static bool run_local_stream_name(int dummy
)
5461 ret
&= test_stream_name(
5462 "bla", "bla", NULL
, NT_STATUS_OK
);
5463 ret
&= test_stream_name(
5464 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
5465 ret
&= test_stream_name(
5466 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
5467 ret
&= test_stream_name(
5468 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
5469 ret
&= test_stream_name(
5470 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
5471 ret
&= test_stream_name(
5472 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
5473 ret
&= test_stream_name(
5474 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
5475 ret
&= test_stream_name(
5476 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
5481 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
5483 if (a
.length
!= b
.length
) {
5484 printf("a.length=%d != b.length=%d\n",
5485 (int)a
.length
, (int)b
.length
);
5488 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
5489 printf("a.data and b.data differ\n");
5495 static bool run_local_memcache(int dummy
)
5497 struct memcache
*cache
;
5499 DATA_BLOB d1
, d2
, d3
;
5500 DATA_BLOB v1
, v2
, v3
;
5502 TALLOC_CTX
*mem_ctx
;
5504 size_t size1
, size2
;
5507 cache
= memcache_init(NULL
, 100);
5509 if (cache
== NULL
) {
5510 printf("memcache_init failed\n");
5514 d1
= data_blob_const("d1", 2);
5515 d2
= data_blob_const("d2", 2);
5516 d3
= data_blob_const("d3", 2);
5518 k1
= data_blob_const("d1", 2);
5519 k2
= data_blob_const("d2", 2);
5521 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
5522 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
5524 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
5525 printf("could not find k1\n");
5528 if (!data_blob_equal(d1
, v1
)) {
5532 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
5533 printf("could not find k2\n");
5536 if (!data_blob_equal(d2
, v2
)) {
5540 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
5542 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
5543 printf("could not find replaced k1\n");
5546 if (!data_blob_equal(d3
, v3
)) {
5550 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
5552 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
5553 printf("Did find k2, should have been purged\n");
5559 cache
= memcache_init(NULL
, 0);
5561 mem_ctx
= talloc_init("foo");
5563 str1
= talloc_strdup(mem_ctx
, "string1");
5564 str2
= talloc_strdup(mem_ctx
, "string2");
5566 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
5567 data_blob_string_const("torture"), &str1
);
5568 size1
= talloc_total_size(cache
);
5570 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
5571 data_blob_string_const("torture"), &str2
);
5572 size2
= talloc_total_size(cache
);
5574 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
5576 if (size2
> size1
) {
5577 printf("memcache leaks memory!\n");
5587 static void wbclient_done(struct tevent_req
*req
)
5590 struct winbindd_response
*wb_resp
;
5591 int *i
= (int *)tevent_req_callback_data_void(req
);
5593 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
5596 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
5599 static bool run_local_wbclient(int dummy
)
5601 struct event_context
*ev
;
5602 struct wb_context
**wb_ctx
;
5603 struct winbindd_request wb_req
;
5604 bool result
= false;
5607 BlockSignals(True
, SIGPIPE
);
5609 ev
= event_context_init(talloc_tos());
5614 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, torture_numops
);
5615 if (wb_ctx
== NULL
) {
5619 ZERO_STRUCT(wb_req
);
5620 wb_req
.cmd
= WINBINDD_PING
;
5622 for (i
=0; i
<torture_numops
; i
++) {
5623 wb_ctx
[i
] = wb_context_init(ev
);
5624 if (wb_ctx
[i
] == NULL
) {
5627 for (j
=0; j
<5; j
++) {
5628 struct tevent_req
*req
;
5629 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
5630 (j
% 2) == 0, &wb_req
);
5634 tevent_req_set_callback(req
, wbclient_done
, &i
);
5640 while (i
< 5 * torture_numops
) {
5641 event_loop_once(ev
);
5650 static double create_procs(bool (*fn
)(int), bool *result
)
5653 volatile pid_t
*child_status
;
5654 volatile bool *child_status_out
;
5660 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
5661 if (!child_status
) {
5662 printf("Failed to setup shared memory\n");
5666 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
5667 if (!child_status_out
) {
5668 printf("Failed to setup result status shared memory\n");
5672 for (i
= 0; i
< nprocs
; i
++) {
5673 child_status
[i
] = 0;
5674 child_status_out
[i
] = True
;
5679 for (i
=0;i
<nprocs
;i
++) {
5682 pid_t mypid
= getpid();
5683 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
5685 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
5688 if (torture_open_connection(¤t_cli
, i
)) break;
5690 printf("pid %d failed to start\n", (int)getpid());
5696 child_status
[i
] = getpid();
5698 while (child_status
[i
] && end_timer() < 5) smb_msleep(2);
5700 child_status_out
[i
] = fn(i
);
5707 for (i
=0;i
<nprocs
;i
++) {
5708 if (child_status
[i
]) synccount
++;
5710 if (synccount
== nprocs
) break;
5712 } while (end_timer() < 30);
5714 if (synccount
!= nprocs
) {
5715 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
5720 /* start the client load */
5723 for (i
=0;i
<nprocs
;i
++) {
5724 child_status
[i
] = 0;
5727 printf("%d clients started\n", nprocs
);
5729 for (i
=0;i
<nprocs
;i
++) {
5730 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
5735 for (i
=0;i
<nprocs
;i
++) {
5736 if (!child_status_out
[i
]) {
5743 #define FLAG_MULTIPROC 1
5750 {"FDPASS", run_fdpasstest
, 0},
5751 {"LOCK1", run_locktest1
, 0},
5752 {"LOCK2", run_locktest2
, 0},
5753 {"LOCK3", run_locktest3
, 0},
5754 {"LOCK4", run_locktest4
, 0},
5755 {"LOCK5", run_locktest5
, 0},
5756 {"LOCK6", run_locktest6
, 0},
5757 {"LOCK7", run_locktest7
, 0},
5758 {"UNLINK", run_unlinktest
, 0},
5759 {"BROWSE", run_browsetest
, 0},
5760 {"ATTR", run_attrtest
, 0},
5761 {"TRANS2", run_trans2test
, 0},
5762 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
5763 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
5764 {"RANDOMIPC", run_randomipc
, 0},
5765 {"NEGNOWAIT", run_negprot_nowait
, 0},
5766 {"NBENCH", run_nbench
, 0},
5767 {"OPLOCK1", run_oplock1
, 0},
5768 {"OPLOCK2", run_oplock2
, 0},
5769 {"OPLOCK3", run_oplock3
, 0},
5770 {"DIR", run_dirtest
, 0},
5771 {"DIR1", run_dirtest1
, 0},
5772 {"DENY1", torture_denytest1
, 0},
5773 {"DENY2", torture_denytest2
, 0},
5774 {"TCON", run_tcon_test
, 0},
5775 {"TCONDEV", run_tcon_devtype_test
, 0},
5776 {"RW1", run_readwritetest
, 0},
5777 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
5778 {"RW3", run_readwritelarge
, 0},
5779 {"OPEN", run_opentest
, 0},
5780 {"POSIX", run_simple_posix_open_test
, 0},
5782 {"OPENATTR", run_openattrtest
, 0},
5784 {"XCOPY", run_xcopy
, 0},
5785 {"RENAME", run_rename
, 0},
5786 {"DELETE", run_deletetest
, 0},
5787 {"PROPERTIES", run_properties
, 0},
5788 {"MANGLE", torture_mangle
, 0},
5789 {"W2K", run_w2ktest
, 0},
5790 {"TRANS2SCAN", torture_trans2_scan
, 0},
5791 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
5792 {"UTABLE", torture_utable
, 0},
5793 {"CASETABLE", torture_casetable
, 0},
5794 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
5795 {"PIPE_NUMBER", run_pipe_number
, 0},
5796 {"TCON2", run_tcon2_test
, 0},
5797 {"IOCTL", torture_ioctl_test
, 0},
5798 {"CHKPATH", torture_chkpath_test
, 0},
5799 {"FDSESS", run_fdsesstest
, 0},
5800 { "EATEST", run_eatest
, 0},
5801 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
5802 { "CHAIN1", run_chain1
, 0},
5803 { "WINDOWS-WRITE", run_windows_write
, 0},
5804 { "CLI_ECHO", run_cli_echo
, 0},
5805 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
5806 { "LOCAL-GENCACHE", run_local_gencache
, 0},
5807 { "LOCAL-RBTREE", run_local_rbtree
, 0},
5808 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
5809 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
5810 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
5815 /****************************************************************************
5816 run a specified test or "ALL"
5817 ****************************************************************************/
5818 static bool run_test(const char *name
)
5825 if (strequal(name
,"ALL")) {
5826 for (i
=0;torture_ops
[i
].name
;i
++) {
5827 run_test(torture_ops
[i
].name
);
5832 for (i
=0;torture_ops
[i
].name
;i
++) {
5833 fstr_sprintf(randomfname
, "\\XX%x",
5834 (unsigned)random());
5836 if (strequal(name
, torture_ops
[i
].name
)) {
5838 printf("Running %s\n", name
);
5839 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
5840 t
= create_procs(torture_ops
[i
].fn
, &result
);
5843 printf("TEST %s FAILED!\n", name
);
5848 if (!torture_ops
[i
].fn(0)) {
5850 printf("TEST %s FAILED!\n", name
);
5854 printf("%s took %g secs\n\n", name
, t
);
5859 printf("Did not find a test named %s\n", name
);
5867 static void usage(void)
5871 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5872 printf("Please use samba4 torture.\n\n");
5874 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5876 printf("\t-d debuglevel\n");
5877 printf("\t-U user%%pass\n");
5878 printf("\t-k use kerberos\n");
5879 printf("\t-N numprocs\n");
5880 printf("\t-n my_netbios_name\n");
5881 printf("\t-W workgroup\n");
5882 printf("\t-o num_operations\n");
5883 printf("\t-O socket_options\n");
5884 printf("\t-m maximum protocol\n");
5885 printf("\t-L use oplocks\n");
5886 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5887 printf("\t-A showall\n");
5888 printf("\t-p port\n");
5889 printf("\t-s seed\n");
5890 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5893 printf("tests are:");
5894 for (i
=0;torture_ops
[i
].name
;i
++) {
5895 printf(" %s", torture_ops
[i
].name
);
5899 printf("default test is ALL\n");
5904 /****************************************************************************
5906 ****************************************************************************/
5907 int main(int argc
,char *argv
[])
5913 bool correct
= True
;
5914 TALLOC_CTX
*frame
= talloc_stackframe();
5915 int seed
= time(NULL
);
5919 #ifdef HAVE_SETBUFFER
5920 setbuffer(stdout
, NULL
, 0);
5925 if (is_default_dyn_CONFIGFILE()) {
5926 if(getenv("SMB_CONF_PATH")) {
5927 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
5930 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
5937 for(p
= argv
[1]; *p
; p
++)
5941 if (strncmp(argv
[1], "//", 2)) {
5945 fstrcpy(host
, &argv
[1][2]);
5946 p
= strchr_m(&host
[2],'/');
5951 fstrcpy(share
, p
+1);
5953 fstrcpy(myname
, get_myname(talloc_tos()));
5955 fprintf(stderr
, "Failed to get my hostname.\n");
5959 if (*username
== 0 && getenv("LOGNAME")) {
5960 fstrcpy(username
,getenv("LOGNAME"));
5966 fstrcpy(workgroup
, lp_workgroup());
5968 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF
) {
5971 port_to_use
= atoi(optarg
);
5974 seed
= atoi(optarg
);
5977 fstrcpy(workgroup
,optarg
);
5980 max_protocol
= interpret_protocol(optarg
, max_protocol
);
5983 nprocs
= atoi(optarg
);
5986 torture_numops
= atoi(optarg
);
5989 DEBUGLEVEL
= atoi(optarg
);
5998 torture_showall
= True
;
6001 fstrcpy(myname
, optarg
);
6004 client_txt
= optarg
;
6011 use_kerberos
= True
;
6013 d_printf("No kerberos support compiled in\n");
6019 fstrcpy(username
,optarg
);
6020 p
= strchr_m(username
,'%');
6023 fstrcpy(password
, p
+1);
6028 fstrcpy(multishare_conn_fname
, optarg
);
6029 use_multishare_conn
= True
;
6032 torture_blocksize
= atoi(optarg
);
6035 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
6040 d_printf("using seed %d\n", seed
);
6044 if(use_kerberos
&& !gotuser
) gotpass
= True
;
6047 p
= getpass("Password:");
6049 fstrcpy(password
, p
);
6054 printf("host=%s share=%s user=%s myname=%s\n",
6055 host
, share
, username
, myname
);
6057 if (argc
== optind
) {
6058 correct
= run_test("ALL");
6060 for (i
=optind
;i
<argc
;i
++) {
6061 if (!run_test(argv
[i
])) {