2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
29 #include "nsswitch/winbind_client.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
37 static fstring host
, workgroup
, share
, password
, username
, myname
;
38 static int max_protocol
= PROTOCOL_NT1
;
39 static const char *sockops
="TCP_NODELAY";
41 static int port_to_use
=0;
42 int torture_numops
=100;
43 int torture_blocksize
=1024*1024;
44 static int procnum
; /* records process count number when forking */
45 static struct cli_state
*current_cli
;
46 static fstring randomfname
;
47 static bool use_oplocks
;
48 static bool use_level_II_oplocks
;
49 static const char *client_txt
= "client_oplocks.txt";
50 static bool use_kerberos
;
51 static fstring multishare_conn_fname
;
52 static bool use_multishare_conn
= False
;
53 static bool do_encrypt
;
54 static const char *local_path
= NULL
;
56 bool torture_showall
= False
;
58 static double create_procs(bool (*fn
)(int), bool *result
);
61 /* return a pointer to a anonymous shared memory segment of size "size"
62 which will persist across fork() but will disappear when all processes
65 The memory is not zeroed
67 This function uses system5 shared memory. It takes advantage of a property
68 that the memory is not destroyed if it is attached when the id is removed
70 void *shm_setup(int size
)
76 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
78 printf("can't get shared memory\n");
81 shm_unlink("private");
82 if (ftruncate(shmid
, size
) == -1) {
83 printf("can't set shared memory size\n");
86 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
87 if (ret
== MAP_FAILED
) {
88 printf("can't map shared memory\n");
92 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
94 printf("can't get shared memory\n");
97 ret
= (void *)shmat(shmid
, 0, 0);
98 if (!ret
|| ret
== (void *)-1) {
99 printf("can't attach to shared memory\n");
102 /* the following releases the ipc, but note that this process
103 and all its children will still have access to the memory, its
104 just that the shmid is no longer valid for other shm calls. This
105 means we don't leave behind lots of shm segments after we exit
107 See Stevens "advanced programming in unix env" for details
109 shmctl(shmid
, IPC_RMID
, 0);
115 /********************************************************************
116 Ensure a connection is encrypted.
117 ********************************************************************/
119 static bool force_cli_encryption(struct cli_state
*c
,
120 const char *sharename
)
123 uint32 caplow
, caphigh
;
126 if (!SERVER_HAS_UNIX_CIFS(c
)) {
127 d_printf("Encryption required and "
128 "server that doesn't support "
129 "UNIX extensions - failing connect\n");
133 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
135 if (!NT_STATUS_IS_OK(status
)) {
136 d_printf("Encryption required and "
137 "can't get UNIX CIFS extensions "
138 "version from server: %s\n", nt_errstr(status
));
142 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
143 d_printf("Encryption required and "
144 "share %s doesn't support "
145 "encryption.\n", sharename
);
149 if (c
->use_kerberos
) {
150 status
= cli_gss_smb_encryption_start(c
);
152 status
= cli_raw_ntlm_smb_encryption_start(c
,
158 if (!NT_STATUS_IS_OK(status
)) {
159 d_printf("Encryption required and "
160 "setup failed with error %s.\n",
169 static struct cli_state
*open_nbt_connection(void)
171 struct nmb_name called
, calling
;
172 struct sockaddr_storage ss
;
176 make_nmb_name(&calling
, myname
, 0x0);
177 make_nmb_name(&called
, host
, 0x20);
181 if (!(c
= cli_initialise())) {
182 printf("Failed initialize cli_struct to connect with %s\n", host
);
186 c
->port
= port_to_use
;
188 status
= cli_connect(c
, host
, &ss
);
189 if (!NT_STATUS_IS_OK(status
)) {
190 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
194 c
->use_kerberos
= use_kerberos
;
196 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
197 if (use_oplocks
) c
->use_oplocks
= True
;
198 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
200 if (!cli_session_request(c
, &calling
, &called
)) {
202 * Well, that failed, try *SMBSERVER ...
203 * However, we must reconnect as well ...
205 status
= cli_connect(c
, host
, &ss
);
206 if (!NT_STATUS_IS_OK(status
)) {
207 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
211 make_nmb_name(&called
, "*SMBSERVER", 0x20);
212 if (!cli_session_request(c
, &calling
, &called
)) {
213 printf("%s rejected the session\n",host
);
214 printf("We tried with a called name of %s & %s\n",
224 /****************************************************************************
225 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
226 ****************************************************************************/
228 static bool cli_bad_session_request(struct cli_state
*cli
,
229 struct nmb_name
*calling
, struct nmb_name
*called
)
236 memcpy(&(cli
->calling
), calling
, sizeof(*calling
));
237 memcpy(&(cli
->called
), called
, sizeof(*called
));
239 /* put in the destination name */
241 tmp
= name_mangle(talloc_tos(), cli
->called
.name
,
242 cli
->called
.name_type
);
248 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
250 memcpy(p
, tmp
, namelen
);
255 /* Deliberately corrupt the name len (first byte) */
260 tmp
= name_mangle(talloc_tos(), cli
->calling
.name
,
261 cli
->calling
.name_type
);
267 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
269 memcpy(p
, tmp
, namelen
);
273 /* Deliberately corrupt the name len (first byte) */
276 /* send a session request (RFC 1002) */
277 /* setup the packet length
278 * Remove four bytes from the length count, since the length
279 * field in the NBT Session Service header counts the number
280 * of bytes which follow. The cli_send_smb() function knows
281 * about this and accounts for those four bytes.
285 _smb_setlen(cli
->outbuf
,len
);
286 SCVAL(cli
->outbuf
,0,0x81);
289 DEBUG(5,("Sent session request\n"));
291 if (!cli_receive_smb(cli
))
294 if (CVAL(cli
->inbuf
,0) != 0x82) {
295 /* This is the wrong place to put the error... JRA. */
296 cli
->rap_error
= CVAL(cli
->inbuf
,4);
302 static struct cli_state
*open_bad_nbt_connection(void)
304 struct nmb_name called
, calling
;
305 struct sockaddr_storage ss
;
309 make_nmb_name(&calling
, myname
, 0x0);
310 make_nmb_name(&called
, host
, 0x20);
314 if (!(c
= cli_initialise())) {
315 printf("Failed initialize cli_struct to connect with %s\n", host
);
321 status
= cli_connect(c
, host
, &ss
);
322 if (!NT_STATUS_IS_OK(status
)) {
323 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
327 c
->timeout
= 4000; /* set a short timeout (4 seconds) */
329 if (!cli_bad_session_request(c
, &calling
, &called
)) {
330 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
338 /* Insert a NULL at the first separator of the given path and return a pointer
339 * to the remainder of the string.
342 terminate_path_at_separator(char * path
)
350 if ((p
= strchr_m(path
, '/'))) {
355 if ((p
= strchr_m(path
, '\\'))) {
365 parse a //server/share type UNC name
367 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
368 char **hostname
, char **sharename
)
372 *hostname
= *sharename
= NULL
;
374 if (strncmp(unc_name
, "\\\\", 2) &&
375 strncmp(unc_name
, "//", 2)) {
379 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
380 p
= terminate_path_at_separator(*hostname
);
383 *sharename
= talloc_strdup(mem_ctx
, p
);
384 terminate_path_at_separator(*sharename
);
387 if (*hostname
&& *sharename
) {
391 TALLOC_FREE(*hostname
);
392 TALLOC_FREE(*sharename
);
396 static bool torture_open_connection_share(struct cli_state
**c
,
397 const char *hostname
,
398 const char *sharename
)
405 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
407 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
408 if (use_level_II_oplocks
)
409 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
411 status
= cli_full_connection(c
, myname
,
412 hostname
, NULL
, port_to_use
,
415 password
, flags
, Undefined
, &retry
);
416 if (!NT_STATUS_IS_OK(status
)) {
417 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418 hostname
, sharename
, port_to_use
, nt_errstr(status
));
422 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
425 return force_cli_encryption(*c
,
431 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
433 char **unc_list
= NULL
;
434 int num_unc_names
= 0;
437 if (use_multishare_conn
==True
) {
439 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
440 if (!unc_list
|| num_unc_names
<= 0) {
441 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
445 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
447 printf("Failed to parse UNC name %s\n",
448 unc_list
[conn_index
% num_unc_names
]);
449 TALLOC_FREE(unc_list
);
453 result
= torture_open_connection_share(c
, h
, s
);
455 /* h, s were copied earlier */
456 TALLOC_FREE(unc_list
);
460 return torture_open_connection_share(c
, host
, share
);
463 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
465 uint16 old_vuid
= cli
->vuid
;
466 fstring old_user_name
;
467 size_t passlen
= strlen(password
);
471 fstrcpy(old_user_name
, cli
->user_name
);
473 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
477 *new_vuid
= cli
->vuid
;
478 cli
->vuid
= old_vuid
;
479 status
= cli_set_username(cli
, old_user_name
);
480 if (!NT_STATUS_IS_OK(status
)) {
487 bool torture_close_connection(struct cli_state
*c
)
492 status
= cli_tdis(c
);
493 if (!NT_STATUS_IS_OK(status
)) {
494 printf("tdis failed (%s)\n", nt_errstr(status
));
504 /* check if the server produced the expected error code */
505 static bool check_error(int line
, struct cli_state
*c
,
506 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
508 if (cli_is_dos_error(c
)) {
512 /* Check DOS error */
514 cli_dos_error(c
, &cclass
, &num
);
516 if (eclass
!= cclass
|| ecode
!= num
) {
517 printf("unexpected error code class=%d code=%d\n",
518 (int)cclass
, (int)num
);
519 printf(" expected %d/%d %s (line=%d)\n",
520 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
529 status
= cli_nt_error(c
);
531 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
532 printf("unexpected error code %s\n", nt_errstr(status
));
533 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
542 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
544 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
545 if (!check_error(__LINE__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
551 static bool rw_torture(struct cli_state
*c
)
553 const char *lockfname
= "\\torture.lck";
557 pid_t pid2
, pid
= getpid();
563 memset(buf
, '\0', sizeof(buf
));
565 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
567 if (!NT_STATUS_IS_OK(status
)) {
568 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
570 if (!NT_STATUS_IS_OK(status
)) {
571 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
575 for (i
=0;i
<torture_numops
;i
++) {
576 unsigned n
= (unsigned)sys_random()%10;
578 printf("%d\r", i
); fflush(stdout
);
580 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
582 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
586 if (!NT_STATUS_IS_OK(cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
, &fnum
))) {
587 printf("open failed (%s)\n", cli_errstr(c
));
592 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
593 printf("write failed (%s)\n", cli_errstr(c
));
598 if (cli_write(c
, fnum
, 0, (char *)buf
,
599 sizeof(pid
)+(j
*sizeof(buf
)),
600 sizeof(buf
)) != sizeof(buf
)) {
601 printf("write failed (%s)\n", cli_errstr(c
));
608 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
609 printf("read failed (%s)\n", cli_errstr(c
));
614 printf("data corruption!\n");
618 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
619 printf("close failed (%s)\n", cli_errstr(c
));
623 if (!NT_STATUS_IS_OK(cli_unlink(c
, fname
, aSYSTEM
| aHIDDEN
))) {
624 printf("unlink failed (%s)\n", cli_errstr(c
));
628 if (!NT_STATUS_IS_OK(cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int)))) {
629 printf("unlock failed (%s)\n", cli_errstr(c
));
635 cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
);
642 static bool run_torture(int dummy
)
644 struct cli_state
*cli
;
649 cli_sockopt(cli
, sockops
);
651 ret
= rw_torture(cli
);
653 if (!torture_close_connection(cli
)) {
660 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
662 uint16_t fnum
= (uint16_t)-1;
667 unsigned countprev
= 0;
673 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
675 SIVAL(buf
, i
, sys_random());
680 if (!NT_STATUS_IS_OK(cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
681 DENY_NONE
, &fnum
))) {
682 printf("first open read/write of %s failed (%s)\n",
683 lockfname
, cli_errstr(c
));
689 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
691 status
= cli_open(c
, lockfname
, O_RDONLY
,
693 if (!NT_STATUS_IS_OK(status
)) {
698 if (!NT_STATUS_IS_OK(status
)) {
699 printf("second open read-only of %s failed (%s)\n",
700 lockfname
, cli_errstr(c
));
706 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
708 if (count
>= countprev
) {
709 printf("%d %8d\r", i
, count
);
712 countprev
+= (sizeof(buf
) / 20);
717 sent
= ((unsigned)sys_random()%(20))+ 1;
718 if (sent
> sizeof(buf
) - count
)
720 sent
= sizeof(buf
) - count
;
723 if (cli_write(c
, fnum
, 0, buf
+count
, count
, (size_t)sent
) != sent
) {
724 printf("write failed (%s)\n", cli_errstr(c
));
730 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
734 printf("read failed offset:%d size:%ld (%s)\n",
735 count
, (unsigned long)sizeof(buf
)-count
,
742 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
744 printf("read/write compare failed\n");
745 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
754 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
755 printf("close failed (%s)\n", cli_errstr(c
));
762 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
764 const char *lockfname
= "\\torture2.lck";
773 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
774 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
777 if (!NT_STATUS_IS_OK(cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
778 DENY_NONE
, &fnum1
))) {
779 printf("first open read/write of %s failed (%s)\n",
780 lockfname
, cli_errstr(c1
));
783 if (!NT_STATUS_IS_OK(cli_open(c2
, lockfname
, O_RDONLY
,
784 DENY_NONE
, &fnum2
))) {
785 printf("second open read-only of %s failed (%s)\n",
786 lockfname
, cli_errstr(c2
));
787 cli_close(c1
, fnum1
);
791 for (i
=0;i
<torture_numops
;i
++)
793 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
795 printf("%d\r", i
); fflush(stdout
);
798 generate_random_buffer((unsigned char *)buf
, buf_size
);
800 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
801 printf("write failed (%s)\n", cli_errstr(c1
));
806 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
807 printf("read failed (%s)\n", cli_errstr(c2
));
808 printf("read %d, expected %ld\n", (int)bytes_read
,
809 (unsigned long)buf_size
);
814 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
816 printf("read/write compare failed\n");
822 if (!NT_STATUS_IS_OK(cli_close(c2
, fnum2
))) {
823 printf("close failed (%s)\n", cli_errstr(c2
));
826 if (!NT_STATUS_IS_OK(cli_close(c1
, fnum1
))) {
827 printf("close failed (%s)\n", cli_errstr(c1
));
831 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
832 printf("unlink failed (%s)\n", cli_errstr(c1
));
839 static bool run_readwritetest(int dummy
)
841 struct cli_state
*cli1
, *cli2
;
842 bool test1
, test2
= False
;
844 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
847 cli_sockopt(cli1
, sockops
);
848 cli_sockopt(cli2
, sockops
);
850 printf("starting readwritetest\n");
852 test1
= rw_torture2(cli1
, cli2
);
853 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
856 test2
= rw_torture2(cli1
, cli1
);
857 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
860 if (!torture_close_connection(cli1
)) {
864 if (!torture_close_connection(cli2
)) {
868 return (test1
&& test2
);
871 static bool run_readwritemulti(int dummy
)
873 struct cli_state
*cli
;
878 cli_sockopt(cli
, sockops
);
880 printf("run_readwritemulti: fname %s\n", randomfname
);
881 test
= rw_torture3(cli
, randomfname
);
883 if (!torture_close_connection(cli
)) {
890 static bool run_readwritelarge(int dummy
)
892 static struct cli_state
*cli1
;
894 const char *lockfname
= "\\large.dat";
899 if (!torture_open_connection(&cli1
, 0)) {
902 cli_sockopt(cli1
, sockops
);
903 memset(buf
,'\0',sizeof(buf
));
905 cli1
->max_xmit
= 128*1024;
907 printf("starting readwritelarge\n");
909 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
911 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
912 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
916 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
918 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
919 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
920 NULL
, NULL
, NULL
))) {
921 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
925 if (fsize
== sizeof(buf
))
926 printf("readwritelarge test 1 succeeded (size = %lx)\n",
927 (unsigned long)fsize
);
929 printf("readwritelarge test 1 failed (size = %lx)\n",
930 (unsigned long)fsize
);
934 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
935 printf("close failed (%s)\n", cli_errstr(cli1
));
939 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
940 printf("unlink failed (%s)\n", cli_errstr(cli1
));
944 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
945 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
949 cli1
->max_xmit
= 4*1024;
951 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
));
953 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
954 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
955 NULL
, NULL
, NULL
))) {
956 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
960 if (fsize
== sizeof(buf
))
961 printf("readwritelarge test 2 succeeded (size = %lx)\n",
962 (unsigned long)fsize
);
964 printf("readwritelarge test 2 failed (size = %lx)\n",
965 (unsigned long)fsize
);
970 /* ToDo - set allocation. JRA */
971 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
972 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
975 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
977 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
981 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
984 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
985 printf("close failed (%s)\n", cli_errstr(cli1
));
989 if (!torture_close_connection(cli1
)) {
998 #define ival(s) strtol(s, NULL, 0)
1000 /* run a test that simulates an approximate netbench client load */
1001 static bool run_netbench(int client
)
1003 struct cli_state
*cli
;
1008 const char *params
[20];
1009 bool correct
= True
;
1015 cli_sockopt(cli
, sockops
);
1019 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1021 f
= fopen(client_txt
, "r");
1028 while (fgets(line
, sizeof(line
)-1, f
)) {
1032 line
[strlen(line
)-1] = 0;
1034 /* printf("[%d] %s\n", line_count, line); */
1036 all_string_sub(line
,"client1", cname
, sizeof(line
));
1038 /* parse the command parameters */
1039 params
[0] = strtok_r(line
, " ", &saveptr
);
1041 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1045 if (i
< 2) continue;
1047 if (!strncmp(params
[0],"SMB", 3)) {
1048 printf("ERROR: You are using a dbench 1 load file\n");
1052 if (!strcmp(params
[0],"NTCreateX")) {
1053 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1055 } else if (!strcmp(params
[0],"Close")) {
1056 nb_close(ival(params
[1]));
1057 } else if (!strcmp(params
[0],"Rename")) {
1058 nb_rename(params
[1], params
[2]);
1059 } else if (!strcmp(params
[0],"Unlink")) {
1060 nb_unlink(params
[1]);
1061 } else if (!strcmp(params
[0],"Deltree")) {
1062 nb_deltree(params
[1]);
1063 } else if (!strcmp(params
[0],"Rmdir")) {
1064 nb_rmdir(params
[1]);
1065 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1066 nb_qpathinfo(params
[1]);
1067 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1068 nb_qfileinfo(ival(params
[1]));
1069 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1070 nb_qfsinfo(ival(params
[1]));
1071 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1072 nb_findfirst(params
[1]);
1073 } else if (!strcmp(params
[0],"WriteX")) {
1074 nb_writex(ival(params
[1]),
1075 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1076 } else if (!strcmp(params
[0],"ReadX")) {
1077 nb_readx(ival(params
[1]),
1078 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1079 } else if (!strcmp(params
[0],"Flush")) {
1080 nb_flush(ival(params
[1]));
1082 printf("Unknown operation %s\n", params
[0]);
1090 if (!torture_close_connection(cli
)) {
1098 /* run a test that simulates an approximate netbench client load */
1099 static bool run_nbench(int dummy
)
1102 bool correct
= True
;
1108 signal(SIGALRM
, nb_alarm
);
1110 t
= create_procs(run_netbench
, &correct
);
1113 printf("\nThroughput %g MB/sec\n",
1114 1.0e-6 * nbio_total() / t
);
1120 This test checks for two things:
1122 1) correct support for retaining locks over a close (ie. the server
1123 must not use posix semantics)
1124 2) support for lock timeouts
1126 static bool run_locktest1(int dummy
)
1128 struct cli_state
*cli1
, *cli2
;
1129 const char *fname
= "\\lockt1.lck";
1130 uint16_t fnum1
, fnum2
, fnum3
;
1132 unsigned lock_timeout
;
1134 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1137 cli_sockopt(cli1
, sockops
);
1138 cli_sockopt(cli2
, sockops
);
1140 printf("starting locktest1\n");
1142 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1144 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1145 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1148 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1149 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1152 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1153 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1157 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1158 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1163 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1164 printf("lock2 succeeded! This is a locking bug\n");
1167 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1168 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1172 lock_timeout
= (1 + (random() % 20));
1173 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1175 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1176 printf("lock3 succeeded! This is a locking bug\n");
1179 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1180 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1184 if (ABS(t2
- t1
) < lock_timeout
-1) {
1185 printf("error: This server appears not to support timed lock requests\n");
1188 printf("server slept for %u seconds for a %u second timeout\n",
1189 (unsigned int)(t2
-t1
), lock_timeout
);
1191 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1192 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1196 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1197 printf("lock4 succeeded! This is a locking bug\n");
1200 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1201 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1204 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1205 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1209 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1210 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1214 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1215 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1220 if (!torture_close_connection(cli1
)) {
1224 if (!torture_close_connection(cli2
)) {
1228 printf("Passed locktest1\n");
1233 this checks to see if a secondary tconx can use open files from an
1236 static bool run_tcon_test(int dummy
)
1238 static struct cli_state
*cli
;
1239 const char *fname
= "\\tcontest.tmp";
1241 uint16 cnum1
, cnum2
, cnum3
;
1242 uint16 vuid1
, vuid2
;
1247 memset(buf
, '\0', sizeof(buf
));
1249 if (!torture_open_connection(&cli
, 0)) {
1252 cli_sockopt(cli
, sockops
);
1254 printf("starting tcontest\n");
1256 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1258 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1259 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1266 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1267 printf("initial write failed (%s)", cli_errstr(cli
));
1271 status
= cli_tcon_andx(cli
, share
, "?????",
1272 password
, strlen(password
)+1);
1273 if (!NT_STATUS_IS_OK(status
)) {
1274 printf("%s refused 2nd tree connect (%s)\n", host
,
1281 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1282 vuid2
= cli
->vuid
+ 1;
1284 /* try a write with the wrong tid */
1287 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1288 printf("* server allows write with wrong TID\n");
1291 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1295 /* try a write with an invalid tid */
1298 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1299 printf("* server allows write with invalid TID\n");
1302 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1305 /* try a write with an invalid vuid */
1309 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1310 printf("* server allows write with invalid VUID\n");
1313 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1319 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1320 printf("close failed (%s)\n", cli_errstr(cli
));
1326 status
= cli_tdis(cli
);
1327 if (!NT_STATUS_IS_OK(status
)) {
1328 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1334 if (!torture_close_connection(cli
)) {
1343 checks for old style tcon support
1345 static bool run_tcon2_test(int dummy
)
1347 static struct cli_state
*cli
;
1348 uint16 cnum
, max_xmit
;
1352 if (!torture_open_connection(&cli
, 0)) {
1355 cli_sockopt(cli
, sockops
);
1357 printf("starting tcon2 test\n");
1359 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1363 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1365 if (!NT_STATUS_IS_OK(status
)) {
1366 printf("tcon2 failed : %s\n", cli_errstr(cli
));
1368 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1369 (int)max_xmit
, (int)cnum
, SVAL(cli
->inbuf
, smb_tid
));
1372 if (!torture_close_connection(cli
)) {
1376 printf("Passed tcon2 test\n");
1380 static bool tcon_devtest(struct cli_state
*cli
,
1381 const char *myshare
, const char *devtype
,
1382 const char *return_devtype
,
1383 NTSTATUS expected_error
)
1388 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1389 password
, strlen(password
)+1);
1391 if (NT_STATUS_IS_OK(expected_error
)) {
1392 if (NT_STATUS_IS_OK(status
)) {
1393 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1396 printf("tconX to share %s with type %s "
1397 "succeeded but returned the wrong "
1398 "device type (got [%s] but should have got [%s])\n",
1399 myshare
, devtype
, cli
->dev
, return_devtype
);
1403 printf("tconX to share %s with type %s "
1404 "should have succeeded but failed\n",
1410 if (NT_STATUS_IS_OK(status
)) {
1411 printf("tconx to share %s with type %s "
1412 "should have failed but succeeded\n",
1416 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1420 printf("Returned unexpected error\n");
1429 checks for correct tconX support
1431 static bool run_tcon_devtype_test(int dummy
)
1433 static struct cli_state
*cli1
= NULL
;
1439 status
= cli_full_connection(&cli1
, myname
,
1440 host
, NULL
, port_to_use
,
1442 username
, workgroup
,
1443 password
, flags
, Undefined
, &retry
);
1445 if (!NT_STATUS_IS_OK(status
)) {
1446 printf("could not open connection\n");
1450 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1453 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1456 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1459 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1462 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1465 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1468 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1471 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1474 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1477 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1483 printf("Passed tcondevtest\n");
1490 This test checks that
1492 1) the server supports multiple locking contexts on the one SMB
1493 connection, distinguished by PID.
1495 2) the server correctly fails overlapping locks made by the same PID (this
1496 goes against POSIX behaviour, which is why it is tricky to implement)
1498 3) the server denies unlock requests by an incorrect client PID
1500 static bool run_locktest2(int dummy
)
1502 static struct cli_state
*cli
;
1503 const char *fname
= "\\lockt2.lck";
1504 uint16_t fnum1
, fnum2
, fnum3
;
1505 bool correct
= True
;
1507 if (!torture_open_connection(&cli
, 0)) {
1511 cli_sockopt(cli
, sockops
);
1513 printf("starting locktest2\n");
1515 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1519 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1520 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1524 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1525 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1531 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1532 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1538 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1539 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1543 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1544 printf("WRITE lock1 succeeded! This is a locking bug\n");
1547 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1548 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1551 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1552 printf("WRITE lock2 succeeded! This is a locking bug\n");
1555 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1556 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1559 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1560 printf("READ lock2 succeeded! This is a locking bug\n");
1563 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1564 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1567 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1568 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1571 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1572 printf("unlock at 100 succeeded! This is a locking bug\n");
1576 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1577 printf("unlock1 succeeded! This is a locking bug\n");
1580 if (!check_error(__LINE__
, cli
,
1582 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1585 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1586 printf("unlock2 succeeded! This is a locking bug\n");
1589 if (!check_error(__LINE__
, cli
,
1591 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1594 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1595 printf("lock3 succeeded! This is a locking bug\n");
1598 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1603 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1604 printf("close1 failed (%s)\n", cli_errstr(cli
));
1608 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1609 printf("close2 failed (%s)\n", cli_errstr(cli
));
1613 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1614 printf("close3 failed (%s)\n", cli_errstr(cli
));
1618 if (!torture_close_connection(cli
)) {
1622 printf("locktest2 finished\n");
1629 This test checks that
1631 1) the server supports the full offset range in lock requests
1633 static bool run_locktest3(int dummy
)
1635 static struct cli_state
*cli1
, *cli2
;
1636 const char *fname
= "\\lockt3.lck";
1637 uint16_t fnum1
, fnum2
;
1640 bool correct
= True
;
1642 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1644 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1647 cli_sockopt(cli1
, sockops
);
1648 cli_sockopt(cli2
, sockops
);
1650 printf("starting locktest3\n");
1652 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1654 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1655 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1658 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1659 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1663 for (offset
=i
=0;i
<torture_numops
;i
++) {
1665 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1666 printf("lock1 %d failed (%s)\n",
1672 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1673 printf("lock2 %d failed (%s)\n",
1680 for (offset
=i
=0;i
<torture_numops
;i
++) {
1683 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1684 printf("error: lock1 %d succeeded!\n", i
);
1688 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1689 printf("error: lock2 %d succeeded!\n", i
);
1693 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1694 printf("error: lock3 %d succeeded!\n", i
);
1698 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1699 printf("error: lock4 %d succeeded!\n", i
);
1704 for (offset
=i
=0;i
<torture_numops
;i
++) {
1707 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1708 printf("unlock1 %d failed (%s)\n",
1714 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1715 printf("unlock2 %d failed (%s)\n",
1722 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1723 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1727 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1728 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1732 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1733 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1737 if (!torture_close_connection(cli1
)) {
1741 if (!torture_close_connection(cli2
)) {
1745 printf("finished locktest3\n");
1750 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1751 printf("** "); correct = False; \
1755 looks at overlapping locks
1757 static bool run_locktest4(int dummy
)
1759 static struct cli_state
*cli1
, *cli2
;
1760 const char *fname
= "\\lockt4.lck";
1761 uint16_t fnum1
, fnum2
, f
;
1764 bool correct
= True
;
1766 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1770 cli_sockopt(cli1
, sockops
);
1771 cli_sockopt(cli2
, sockops
);
1773 printf("starting locktest4\n");
1775 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1777 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1778 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1780 memset(buf
, 0, sizeof(buf
));
1782 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1783 printf("Failed to create file\n");
1788 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1789 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1790 EXPECTED(ret
, False
);
1791 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1793 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1794 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1795 EXPECTED(ret
, True
);
1796 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1798 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1799 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1800 EXPECTED(ret
, False
);
1801 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1803 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1804 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1805 EXPECTED(ret
, True
);
1806 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1808 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1809 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1810 EXPECTED(ret
, False
);
1811 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1813 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1814 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1815 EXPECTED(ret
, True
);
1816 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1818 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1819 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1820 EXPECTED(ret
, True
);
1821 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1823 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1824 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1825 EXPECTED(ret
, False
);
1826 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1828 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1829 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1830 EXPECTED(ret
, False
);
1831 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1833 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1834 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1835 EXPECTED(ret
, True
);
1836 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1838 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1839 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1840 EXPECTED(ret
, False
);
1841 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1843 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1844 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1845 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1846 EXPECTED(ret
, False
);
1847 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1850 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1851 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1852 EXPECTED(ret
, False
);
1853 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1855 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1856 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1857 EXPECTED(ret
, False
);
1858 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1861 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1862 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1863 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1864 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1865 EXPECTED(ret
, True
);
1866 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1869 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1870 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1871 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1872 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1873 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1874 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1875 EXPECTED(ret
, True
);
1876 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1878 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1879 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1880 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1881 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1882 EXPECTED(ret
, True
);
1883 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1885 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1886 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1887 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1888 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1889 EXPECTED(ret
, True
);
1890 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1892 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1893 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1895 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1896 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1897 EXPECTED(ret
, True
);
1898 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1900 cli_close(cli1
, fnum1
);
1901 cli_close(cli2
, fnum2
);
1902 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1903 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1904 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1905 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1906 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1907 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1908 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1910 cli_close(cli1
, fnum1
);
1911 EXPECTED(ret
, True
);
1912 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1915 cli_close(cli1
, fnum1
);
1916 cli_close(cli2
, fnum2
);
1917 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1918 torture_close_connection(cli1
);
1919 torture_close_connection(cli2
);
1921 printf("finished locktest4\n");
1926 looks at lock upgrade/downgrade.
1928 static bool run_locktest5(int dummy
)
1930 static struct cli_state
*cli1
, *cli2
;
1931 const char *fname
= "\\lockt5.lck";
1932 uint16_t fnum1
, fnum2
, fnum3
;
1935 bool correct
= True
;
1937 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1941 cli_sockopt(cli1
, sockops
);
1942 cli_sockopt(cli2
, sockops
);
1944 printf("starting locktest5\n");
1946 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1948 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1949 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1950 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1952 memset(buf
, 0, sizeof(buf
));
1954 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1955 printf("Failed to create file\n");
1960 /* Check for NT bug... */
1961 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1962 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1963 cli_close(cli1
, fnum1
);
1964 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1965 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1966 EXPECTED(ret
, True
);
1967 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1968 cli_close(cli1
, fnum1
);
1969 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1970 cli_unlock(cli1
, fnum3
, 0, 1);
1972 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1973 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1974 EXPECTED(ret
, True
);
1975 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1977 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1978 EXPECTED(ret
, False
);
1980 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1982 /* Unlock the process 2 lock. */
1983 cli_unlock(cli2
, fnum2
, 0, 4);
1985 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1986 EXPECTED(ret
, False
);
1988 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1990 /* Unlock the process 1 fnum3 lock. */
1991 cli_unlock(cli1
, fnum3
, 0, 4);
1993 /* Stack 2 more locks here. */
1994 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1995 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1997 EXPECTED(ret
, True
);
1998 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2000 /* Unlock the first process lock, then check this was the WRITE lock that was
2003 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2004 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2006 EXPECTED(ret
, True
);
2007 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2009 /* Unlock the process 2 lock. */
2010 cli_unlock(cli2
, fnum2
, 0, 4);
2012 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2014 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2015 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2016 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2018 EXPECTED(ret
, True
);
2019 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2021 /* Ensure the next unlock fails. */
2022 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2023 EXPECTED(ret
, False
);
2024 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2026 /* Ensure connection 2 can get a write lock. */
2027 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2028 EXPECTED(ret
, True
);
2030 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2034 cli_close(cli1
, fnum1
);
2035 cli_close(cli2
, fnum2
);
2036 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2037 if (!torture_close_connection(cli1
)) {
2040 if (!torture_close_connection(cli2
)) {
2044 printf("finished locktest5\n");
2050 tries the unusual lockingX locktype bits
2052 static bool run_locktest6(int dummy
)
2054 static struct cli_state
*cli
;
2055 const char *fname
[1] = { "\\lock6.txt" };
2060 if (!torture_open_connection(&cli
, 0)) {
2064 cli_sockopt(cli
, sockops
);
2066 printf("starting locktest6\n");
2069 printf("Testing %s\n", fname
[i
]);
2071 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2073 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2074 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2075 cli_close(cli
, fnum
);
2076 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2078 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2079 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2080 cli_close(cli
, fnum
);
2081 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2083 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2086 torture_close_connection(cli
);
2088 printf("finished locktest6\n");
2092 static bool run_locktest7(int dummy
)
2094 struct cli_state
*cli1
;
2095 const char *fname
= "\\lockt7.lck";
2098 bool correct
= False
;
2100 if (!torture_open_connection(&cli1
, 0)) {
2104 cli_sockopt(cli1
, sockops
);
2106 printf("starting locktest7\n");
2108 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2110 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2112 memset(buf
, 0, sizeof(buf
));
2114 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
2115 printf("Failed to create file\n");
2119 cli_setpid(cli1
, 1);
2121 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
2122 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2125 printf("pid1 successfully locked range 130:4 for READ\n");
2128 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2129 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2132 printf("pid1 successfully read the range 130:4\n");
2135 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2136 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2137 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2138 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2142 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2146 cli_setpid(cli1
, 2);
2148 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2149 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2151 printf("pid2 successfully read the range 130:4\n");
2154 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2155 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2156 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2157 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2161 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2165 cli_setpid(cli1
, 1);
2166 cli_unlock(cli1
, fnum1
, 130, 4);
2168 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2169 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2172 printf("pid1 successfully locked range 130:4 for WRITE\n");
2175 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2176 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2179 printf("pid1 successfully read the range 130:4\n");
2182 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2183 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2186 printf("pid1 successfully wrote to the range 130:4\n");
2189 cli_setpid(cli1
, 2);
2191 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2192 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2193 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2194 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2198 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2202 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2203 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2204 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2205 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2209 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2213 cli_unlock(cli1
, fnum1
, 130, 0);
2217 cli_close(cli1
, fnum1
);
2218 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2219 torture_close_connection(cli1
);
2221 printf("finished locktest7\n");
2226 * This demonstrates a problem with our use of GPFS share modes: A file
2227 * descriptor sitting in the pending close queue holding a GPFS share mode
2228 * blocks opening a file another time. Happens with Word 2007 temp files.
2229 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2230 * open is denied with NT_STATUS_SHARING_VIOLATION.
2233 static bool run_locktest8(int dummy
)
2235 struct cli_state
*cli1
;
2236 const char *fname
= "\\lockt8.lck";
2237 uint16_t fnum1
, fnum2
;
2239 bool correct
= False
;
2242 if (!torture_open_connection(&cli1
, 0)) {
2246 cli_sockopt(cli1
, sockops
);
2248 printf("starting locktest8\n");
2250 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2252 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2254 if (!NT_STATUS_IS_OK(status
)) {
2255 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2259 memset(buf
, 0, sizeof(buf
));
2261 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2262 if (!NT_STATUS_IS_OK(status
)) {
2263 d_fprintf(stderr
, "cli_open second time returned %s\n",
2268 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2269 printf("Unable to apply read lock on range 1:1, error was "
2270 "%s\n", cli_errstr(cli1
));
2274 status
= cli_close(cli1
, fnum1
);
2275 if (!NT_STATUS_IS_OK(status
)) {
2276 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2280 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2281 if (!NT_STATUS_IS_OK(status
)) {
2282 d_fprintf(stderr
, "cli_open third time returned %s\n",
2290 cli_close(cli1
, fnum1
);
2291 cli_close(cli1
, fnum2
);
2292 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2293 torture_close_connection(cli1
);
2295 printf("finished locktest8\n");
2300 * This test is designed to be run in conjunction with
2301 * external NFS or POSIX locks taken in the filesystem.
2302 * It checks that the smbd server will block until the
2303 * lock is released and then acquire it. JRA.
2306 static bool got_alarm
;
2307 static int alarm_fd
;
2309 static void alarm_handler(int dummy
)
2314 static void alarm_handler_parent(int dummy
)
2319 static void do_local_lock(int read_fd
, int write_fd
)
2324 const char *local_pathname
= NULL
;
2327 local_pathname
= talloc_asprintf(talloc_tos(),
2328 "%s/lockt9.lck", local_path
);
2329 if (!local_pathname
) {
2330 printf("child: alloc fail\n");
2334 unlink(local_pathname
);
2335 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2337 printf("child: open of %s failed %s.\n",
2338 local_pathname
, strerror(errno
));
2342 /* Now take a fcntl lock. */
2343 lock
.l_type
= F_WRLCK
;
2344 lock
.l_whence
= SEEK_SET
;
2347 lock
.l_pid
= getpid();
2349 ret
= fcntl(fd
,F_SETLK
,&lock
);
2351 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2352 local_pathname
, strerror(errno
));
2355 printf("child: got lock 0:4 on file %s.\n",
2360 CatchSignal(SIGALRM
, alarm_handler
);
2362 /* Signal the parent. */
2363 if (write(write_fd
, &c
, 1) != 1) {
2364 printf("child: start signal fail %s.\n",
2371 /* Wait for the parent to be ready. */
2372 if (read(read_fd
, &c
, 1) != 1) {
2373 printf("child: reply signal fail %s.\n",
2381 printf("child: released lock 0:4 on file %s.\n",
2387 static bool run_locktest9(int dummy
)
2389 struct cli_state
*cli1
;
2390 const char *fname
= "\\lockt9.lck";
2392 bool correct
= False
;
2393 int pipe_in
[2], pipe_out
[2];
2397 struct timeval start
;
2401 printf("starting locktest9\n");
2403 if (local_path
== NULL
) {
2404 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2408 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2413 if (child_pid
== -1) {
2417 if (child_pid
== 0) {
2419 do_local_lock(pipe_out
[0], pipe_in
[1]);
2429 ret
= read(pipe_in
[0], &c
, 1);
2431 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2436 if (!torture_open_connection(&cli1
, 0)) {
2440 cli_sockopt(cli1
, sockops
);
2442 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2444 if (!NT_STATUS_IS_OK(status
)) {
2445 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2449 /* Ensure the child has the lock. */
2450 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2451 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2454 d_printf("Child has the lock.\n");
2457 /* Tell the child to wait 5 seconds then exit. */
2458 ret
= write(pipe_out
[1], &c
, 1);
2460 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2465 /* Wait 20 seconds for the lock. */
2466 alarm_fd
= cli1
->fd
;
2467 CatchSignal(SIGALRM
, alarm_handler_parent
);
2470 start
= timeval_current();
2472 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2473 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2474 "%s\n", cli_errstr(cli1
));
2479 seconds
= timeval_elapsed(&start
);
2481 printf("Parent got the lock after %.2f seconds.\n",
2484 status
= cli_close(cli1
, fnum
);
2485 if (!NT_STATUS_IS_OK(status
)) {
2486 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2493 cli_close(cli1
, fnum
);
2494 torture_close_connection(cli1
);
2498 printf("finished locktest9\n");
2503 test whether fnums and tids open on one VC are available on another (a major
2506 static bool run_fdpasstest(int dummy
)
2508 struct cli_state
*cli1
, *cli2
;
2509 const char *fname
= "\\fdpass.tst";
2513 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2516 cli_sockopt(cli1
, sockops
);
2517 cli_sockopt(cli2
, sockops
);
2519 printf("starting fdpasstest\n");
2521 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2523 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2524 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2528 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2529 printf("write failed (%s)\n", cli_errstr(cli1
));
2533 cli2
->vuid
= cli1
->vuid
;
2534 cli2
->cnum
= cli1
->cnum
;
2535 cli2
->pid
= cli1
->pid
;
2537 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2538 printf("read succeeded! nasty security hole [%s]\n",
2543 cli_close(cli1
, fnum1
);
2544 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2546 torture_close_connection(cli1
);
2547 torture_close_connection(cli2
);
2549 printf("finished fdpasstest\n");
2553 static bool run_fdsesstest(int dummy
)
2555 struct cli_state
*cli
;
2560 const char *fname
= "\\fdsess.tst";
2561 const char *fname1
= "\\fdsess1.tst";
2567 if (!torture_open_connection(&cli
, 0))
2569 cli_sockopt(cli
, sockops
);
2571 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2574 saved_cnum
= cli
->cnum
;
2575 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2577 new_cnum
= cli
->cnum
;
2578 cli
->cnum
= saved_cnum
;
2580 printf("starting fdsesstest\n");
2582 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2583 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2585 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2586 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2590 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2591 printf("write failed (%s)\n", cli_errstr(cli
));
2595 saved_vuid
= cli
->vuid
;
2596 cli
->vuid
= new_vuid
;
2598 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2599 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2603 /* Try to open a file with different vuid, samba cnum. */
2604 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2605 printf("create with different vuid, same cnum succeeded.\n");
2606 cli_close(cli
, fnum2
);
2607 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2609 printf("create with different vuid, same cnum failed.\n");
2610 printf("This will cause problems with service clients.\n");
2614 cli
->vuid
= saved_vuid
;
2616 /* Try with same vuid, different cnum. */
2617 cli
->cnum
= new_cnum
;
2619 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2620 printf("read succeeded with different cnum![%s]\n",
2625 cli
->cnum
= saved_cnum
;
2626 cli_close(cli
, fnum1
);
2627 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2629 torture_close_connection(cli
);
2631 printf("finished fdsesstest\n");
2636 This test checks that
2638 1) the server does not allow an unlink on a file that is open
2640 static bool run_unlinktest(int dummy
)
2642 struct cli_state
*cli
;
2643 const char *fname
= "\\unlink.tst";
2645 bool correct
= True
;
2647 if (!torture_open_connection(&cli
, 0)) {
2651 cli_sockopt(cli
, sockops
);
2653 printf("starting unlink test\n");
2655 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2659 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2660 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2664 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2665 printf("error: server allowed unlink on an open file\n");
2668 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2669 NT_STATUS_SHARING_VIOLATION
);
2672 cli_close(cli
, fnum
);
2673 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2675 if (!torture_close_connection(cli
)) {
2679 printf("unlink test finished\n");
2686 test how many open files this server supports on the one socket
2688 static bool run_maxfidtest(int dummy
)
2690 struct cli_state
*cli
;
2691 const char *ftemplate
= "\\maxfid.%d.%d";
2693 uint16_t fnums
[0x11000];
2696 bool correct
= True
;
2701 printf("failed to connect\n");
2705 cli_sockopt(cli
, sockops
);
2707 for (i
=0; i
<0x11000; i
++) {
2708 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2709 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2710 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2711 printf("open of %s failed (%s)\n",
2712 fname
, cli_errstr(cli
));
2713 printf("maximum fnum is %d\n", i
);
2721 printf("cleaning up\n");
2723 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2724 cli_close(cli
, fnums
[i
]);
2725 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2726 printf("unlink of %s failed (%s)\n",
2727 fname
, cli_errstr(cli
));
2734 printf("maxfid test finished\n");
2735 if (!torture_close_connection(cli
)) {
2741 /* generate a random buffer */
2742 static void rand_buf(char *buf
, int len
)
2745 *buf
= (char)sys_random();
2750 /* send smb negprot commands, not reading the response */
2751 static bool run_negprot_nowait(int dummy
)
2754 static struct cli_state
*cli
;
2755 bool correct
= True
;
2757 printf("starting negprot nowait test\n");
2759 if (!(cli
= open_nbt_connection())) {
2763 for (i
=0;i
<50000;i
++) {
2764 cli_negprot_sendsync(cli
);
2767 if (!torture_close_connection(cli
)) {
2771 printf("finished negprot nowait test\n");
2776 /* send smb negprot commands, not reading the response */
2777 static bool run_bad_nbt_session(int dummy
)
2779 static struct cli_state
*cli
;
2781 printf("starting bad nbt session test\n");
2783 if (!(cli
= open_bad_nbt_connection())) {
2788 printf("finished bad nbt session test\n");
2792 /* send random IPC commands */
2793 static bool run_randomipc(int dummy
)
2795 char *rparam
= NULL
;
2797 unsigned int rdrcnt
,rprcnt
;
2799 int api
, param_len
, i
;
2800 struct cli_state
*cli
;
2801 bool correct
= True
;
2804 printf("starting random ipc test\n");
2806 if (!torture_open_connection(&cli
, 0)) {
2810 for (i
=0;i
<count
;i
++) {
2811 api
= sys_random() % 500;
2812 param_len
= (sys_random() % 64);
2814 rand_buf(param
, param_len
);
2819 param
, param_len
, 8,
2820 NULL
, 0, BUFFER_SIZE
,
2824 printf("%d/%d\r", i
,count
);
2827 printf("%d/%d\n", i
, count
);
2829 if (!torture_close_connection(cli
)) {
2833 printf("finished random ipc test\n");
2840 static void browse_callback(const char *sname
, uint32 stype
,
2841 const char *comment
, void *state
)
2843 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2849 This test checks the browse list code
2852 static bool run_browsetest(int dummy
)
2854 static struct cli_state
*cli
;
2855 bool correct
= True
;
2857 printf("starting browse test\n");
2859 if (!torture_open_connection(&cli
, 0)) {
2863 printf("domain list:\n");
2864 cli_NetServerEnum(cli
, cli
->server_domain
,
2865 SV_TYPE_DOMAIN_ENUM
,
2866 browse_callback
, NULL
);
2868 printf("machine list:\n");
2869 cli_NetServerEnum(cli
, cli
->server_domain
,
2871 browse_callback
, NULL
);
2873 if (!torture_close_connection(cli
)) {
2877 printf("browse test finished\n");
2885 This checks how the getatr calls works
2887 static bool run_attrtest(int dummy
)
2889 struct cli_state
*cli
;
2892 const char *fname
= "\\attrib123456789.tst";
2893 bool correct
= True
;
2895 printf("starting attrib test\n");
2897 if (!torture_open_connection(&cli
, 0)) {
2901 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2902 cli_open(cli
, fname
,
2903 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2904 cli_close(cli
, fnum
);
2905 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2906 printf("getatr failed (%s)\n", cli_errstr(cli
));
2910 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2911 printf("ERROR: SMBgetatr bug. time is %s",
2917 t2
= t
-60*60*24; /* 1 day ago */
2919 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
2920 printf("setatr failed (%s)\n", cli_errstr(cli
));
2924 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2925 printf("getatr failed (%s)\n", cli_errstr(cli
));
2930 printf("ERROR: getatr/setatr bug. times are\n%s",
2932 printf("%s", ctime(&t2
));
2936 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2938 if (!torture_close_connection(cli
)) {
2942 printf("attrib test finished\n");
2949 This checks a couple of trans2 calls
2951 static bool run_trans2test(int dummy
)
2953 struct cli_state
*cli
;
2956 time_t c_time
, a_time
, m_time
;
2957 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
2958 const char *fname
= "\\trans2.tst";
2959 const char *dname
= "\\trans2";
2960 const char *fname2
= "\\trans2\\trans2.tst";
2962 bool correct
= True
;
2966 printf("starting trans2 test\n");
2968 if (!torture_open_connection(&cli
, 0)) {
2972 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
2973 if (!NT_STATUS_IS_OK(status
)) {
2974 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2979 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2980 cli_open(cli
, fname
,
2981 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2982 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
2983 cli
, fnum
, NULL
, &size
, &c_time_ts
,
2984 &a_time_ts
, &w_time_ts
,
2985 &m_time_ts
, NULL
))) {
2986 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
2990 if (!NT_STATUS_IS_OK(cli_qfilename(cli
, fnum
, pname
, sizeof(pname
)))) {
2991 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
2995 if (strcmp(pname
, fname
)) {
2996 printf("qfilename gave different name? [%s] [%s]\n",
3001 cli_close(cli
, fnum
);
3005 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3006 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
3007 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
3008 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
3011 cli_close(cli
, fnum
);
3013 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3015 if (!NT_STATUS_IS_OK(status
)) {
3016 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3019 if (c_time
!= m_time
) {
3020 printf("create time=%s", ctime(&c_time
));
3021 printf("modify time=%s", ctime(&m_time
));
3022 printf("This system appears to have sticky create times\n");
3024 if (a_time
% (60*60) == 0) {
3025 printf("access time=%s", ctime(&a_time
));
3026 printf("This system appears to set a midnight access time\n");
3030 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3031 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3037 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3038 cli_open(cli
, fname
,
3039 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3040 cli_close(cli
, fnum
);
3041 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3042 &m_time_ts
, &size
, NULL
, NULL
);
3043 if (!NT_STATUS_IS_OK(status
)) {
3044 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3047 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3048 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3049 printf("This system appears to set a initial 0 write time\n");
3054 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3057 /* check if the server updates the directory modification time
3058 when creating a new file */
3059 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
3060 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
3064 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3065 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3066 if (!NT_STATUS_IS_OK(status
)) {
3067 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3071 cli_open(cli
, fname2
,
3072 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3073 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
3074 cli_close(cli
, fnum
);
3075 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3076 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3077 if (!NT_STATUS_IS_OK(status
)) {
3078 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3081 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3083 printf("This system does not update directory modification times\n");
3087 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
3088 cli_rmdir(cli
, dname
);
3090 if (!torture_close_connection(cli
)) {
3094 printf("trans2 test finished\n");
3100 This checks new W2K calls.
3103 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3105 uint8_t *buf
= NULL
;
3109 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3110 pcli
->max_xmit
, &buf
, &len
);
3111 if (!NT_STATUS_IS_OK(status
)) {
3112 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3115 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3116 dump_data(0, (uint8
*)buf
, len
);
3123 static bool run_w2ktest(int dummy
)
3125 struct cli_state
*cli
;
3127 const char *fname
= "\\w2ktest\\w2k.tst";
3129 bool correct
= True
;
3131 printf("starting w2k test\n");
3133 if (!torture_open_connection(&cli
, 0)) {
3137 cli_open(cli
, fname
,
3138 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3140 for (level
= 1004; level
< 1040; level
++) {
3141 new_trans(cli
, fnum
, level
);
3144 cli_close(cli
, fnum
);
3146 if (!torture_close_connection(cli
)) {
3150 printf("w2k test finished\n");
3157 this is a harness for some oplock tests
3159 static bool run_oplock1(int dummy
)
3161 struct cli_state
*cli1
;
3162 const char *fname
= "\\lockt1.lck";
3164 bool correct
= True
;
3166 printf("starting oplock test 1\n");
3168 if (!torture_open_connection(&cli1
, 0)) {
3172 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3174 cli_sockopt(cli1
, sockops
);
3176 cli1
->use_oplocks
= True
;
3178 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3179 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3183 cli1
->use_oplocks
= False
;
3185 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3186 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3188 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3189 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3193 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3194 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3198 if (!torture_close_connection(cli1
)) {
3202 printf("finished oplock test 1\n");
3207 static bool run_oplock2(int dummy
)
3209 struct cli_state
*cli1
, *cli2
;
3210 const char *fname
= "\\lockt2.lck";
3211 uint16_t fnum1
, fnum2
;
3212 int saved_use_oplocks
= use_oplocks
;
3214 bool correct
= True
;
3215 volatile bool *shared_correct
;
3217 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3218 *shared_correct
= True
;
3220 use_level_II_oplocks
= True
;
3223 printf("starting oplock test 2\n");
3225 if (!torture_open_connection(&cli1
, 0)) {
3226 use_level_II_oplocks
= False
;
3227 use_oplocks
= saved_use_oplocks
;
3231 cli1
->use_oplocks
= True
;
3232 cli1
->use_level_II_oplocks
= True
;
3234 if (!torture_open_connection(&cli2
, 1)) {
3235 use_level_II_oplocks
= False
;
3236 use_oplocks
= saved_use_oplocks
;
3240 cli2
->use_oplocks
= True
;
3241 cli2
->use_level_II_oplocks
= True
;
3243 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3245 cli_sockopt(cli1
, sockops
);
3246 cli_sockopt(cli2
, sockops
);
3248 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3249 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3253 /* Don't need the globals any more. */
3254 use_level_II_oplocks
= False
;
3255 use_oplocks
= saved_use_oplocks
;
3259 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3260 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3261 *shared_correct
= False
;
3267 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3268 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3269 *shared_correct
= False
;
3277 /* Ensure cli1 processes the break. Empty file should always return 0
3280 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3281 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3285 /* Should now be at level II. */
3286 /* Test if sending a write locks causes a break to none. */
3288 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3289 printf("lock failed (%s)\n", cli_errstr(cli1
));
3293 cli_unlock(cli1
, fnum1
, 0, 4);
3297 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3298 printf("lock failed (%s)\n", cli_errstr(cli1
));
3302 cli_unlock(cli1
, fnum1
, 0, 4);
3306 cli_read(cli1
, fnum1
, buf
, 0, 4);
3309 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3310 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
3315 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3316 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3322 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3323 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3327 if (!torture_close_connection(cli1
)) {
3331 if (!*shared_correct
) {
3335 printf("finished oplock test 2\n");
3340 /* handler for oplock 3 tests */
3341 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3343 printf("got oplock break fnum=%d level=%d\n",
3345 return cli_oplock_ack(cli
, fnum
, level
);
3348 static bool run_oplock3(int dummy
)
3350 struct cli_state
*cli
;
3351 const char *fname
= "\\oplockt3.dat";
3353 char buf
[4] = "abcd";
3354 bool correct
= True
;
3355 volatile bool *shared_correct
;
3357 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3358 *shared_correct
= True
;
3360 printf("starting oplock test 3\n");
3365 use_level_II_oplocks
= True
;
3366 if (!torture_open_connection(&cli
, 0)) {
3367 *shared_correct
= False
;
3371 /* try to trigger a oplock break in parent */
3372 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3373 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3379 use_level_II_oplocks
= True
;
3380 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3383 cli_oplock_handler(cli
, oplock3_handler
);
3384 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3385 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3386 cli_close(cli
, fnum
);
3387 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3388 cli
->timeout
= 20000;
3389 cli_receive_smb(cli
);
3390 printf("finished oplock test 3\n");
3392 return (correct
&& *shared_correct
);
3394 /* What are we looking for here? What's sucess and what's FAILURE? */
3400 Test delete on close semantics.
3402 static bool run_deletetest(int dummy
)
3404 struct cli_state
*cli1
= NULL
;
3405 struct cli_state
*cli2
= NULL
;
3406 const char *fname
= "\\delete.file";
3407 uint16_t fnum1
= (uint16_t)-1;
3408 uint16_t fnum2
= (uint16_t)-1;
3409 bool correct
= True
;
3411 printf("starting delete test\n");
3413 if (!torture_open_connection(&cli1
, 0)) {
3417 cli_sockopt(cli1
, sockops
);
3419 /* Test 1 - this should delete the file on close. */
3421 cli_setatr(cli1
, fname
, 0, 0);
3422 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3424 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3425 0, FILE_OVERWRITE_IF
,
3426 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3427 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3432 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3433 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3438 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3439 printf("[1] open of %s succeeded (should fail)\n", fname
);
3444 printf("first delete on close test succeeded.\n");
3446 /* Test 2 - this should delete the file on close. */
3448 cli_setatr(cli1
, fname
, 0, 0);
3449 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3452 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3453 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3454 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3459 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3460 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3465 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3466 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3471 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3472 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3473 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3474 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3478 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3480 printf("second delete on close test succeeded.\n");
3483 cli_setatr(cli1
, fname
, 0, 0);
3484 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3486 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3487 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3488 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3493 /* This should fail with a sharing violation - open for delete is only compatible
3494 with SHARE_DELETE. */
3496 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3497 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3498 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3503 /* This should succeed. */
3505 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3506 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3507 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3512 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3513 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3518 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3519 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3524 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3525 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3530 /* This should fail - file should no longer be there. */
3532 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3533 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3534 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3535 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3537 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3541 printf("third delete on close test succeeded.\n");
3544 cli_setatr(cli1
, fname
, 0, 0);
3545 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3547 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3548 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3549 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3554 /* This should succeed. */
3555 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3556 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3557 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3562 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3563 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3568 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3569 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3574 /* This should fail - no more opens once delete on close set. */
3575 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3576 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3577 FILE_OPEN
, 0, 0, &fnum2
))) {
3578 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3582 printf("fourth delete on close test succeeded.\n");
3584 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3585 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3591 cli_setatr(cli1
, fname
, 0, 0);
3592 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3594 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3595 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3600 /* This should fail - only allowed on NT opens with DELETE access. */
3602 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3603 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3608 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3609 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3614 printf("fifth delete on close test succeeded.\n");
3617 cli_setatr(cli1
, fname
, 0, 0);
3618 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3620 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3621 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3622 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3623 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3628 /* This should fail - only allowed on NT opens with DELETE access. */
3630 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3631 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3636 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3637 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3642 printf("sixth delete on close test succeeded.\n");
3645 cli_setatr(cli1
, fname
, 0, 0);
3646 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3648 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3649 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3650 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3655 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3656 printf("[7] setting delete_on_close on file failed !\n");
3661 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3662 printf("[7] unsetting delete_on_close on file failed !\n");
3667 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3668 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3673 /* This next open should succeed - we reset the flag. */
3675 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3676 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3681 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3682 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3687 printf("seventh delete on close test succeeded.\n");
3690 cli_setatr(cli1
, fname
, 0, 0);
3691 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3693 if (!torture_open_connection(&cli2
, 1)) {
3694 printf("[8] failed to open second connection.\n");
3699 cli_sockopt(cli1
, sockops
);
3701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3702 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3703 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3704 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3709 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3710 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3711 FILE_OPEN
, 0, 0, &fnum2
))) {
3712 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3717 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3718 printf("[8] setting delete_on_close on file failed !\n");
3723 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3724 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3729 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3730 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3735 /* This should fail.. */
3736 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3737 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3741 printf("eighth delete on close test succeeded.\n");
3743 /* This should fail - we need to set DELETE_ACCESS. */
3744 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3745 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3746 printf("[9] open of %s succeeded should have failed!\n", fname
);
3751 printf("ninth delete on close test succeeded.\n");
3753 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3754 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3755 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3760 /* This should delete the file. */
3761 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3762 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3767 /* This should fail.. */
3768 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3769 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3773 printf("tenth delete on close test succeeded.\n");
3775 cli_setatr(cli1
, fname
, 0, 0);
3776 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3778 /* What error do we get when attempting to open a read-only file with
3781 /* Create a readonly file. */
3782 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3783 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3784 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3789 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3790 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3795 /* Now try open for delete access. */
3796 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3797 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3798 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3799 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3800 cli_close(cli1
, fnum1
);
3804 NTSTATUS nterr
= cli_nt_error(cli1
);
3805 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
3806 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
3810 printf("eleventh delete on close test succeeded.\n");
3814 printf("finished delete test\n");
3817 /* FIXME: This will crash if we aborted before cli2 got
3818 * intialized, because these functions don't handle
3819 * uninitialized connections. */
3821 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
3822 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
3823 cli_setatr(cli1
, fname
, 0, 0);
3824 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3826 if (cli1
&& !torture_close_connection(cli1
)) {
3829 if (cli2
&& !torture_close_connection(cli2
)) {
3837 print out server properties
3839 static bool run_properties(int dummy
)
3841 struct cli_state
*cli
;
3842 bool correct
= True
;
3844 printf("starting properties test\n");
3848 if (!torture_open_connection(&cli
, 0)) {
3852 cli_sockopt(cli
, sockops
);
3854 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
3856 if (!torture_close_connection(cli
)) {
3865 /* FIRST_DESIRED_ACCESS 0xf019f */
3866 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3867 FILE_READ_EA| /* 0xf */ \
3868 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3869 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3870 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3871 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3872 /* SECOND_DESIRED_ACCESS 0xe0080 */
3873 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3874 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3875 WRITE_OWNER_ACCESS /* 0xe0000 */
3878 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3879 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3881 WRITE_OWNER_ACCESS /* */
3885 Test ntcreate calls made by xcopy
3887 static bool run_xcopy(int dummy
)
3889 static struct cli_state
*cli1
;
3890 const char *fname
= "\\test.txt";
3891 bool correct
= True
;
3892 uint16_t fnum1
, fnum2
;
3894 printf("starting xcopy test\n");
3896 if (!torture_open_connection(&cli1
, 0)) {
3900 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3901 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
3902 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
3903 0x4044, 0, &fnum1
))) {
3904 printf("First open failed - %s\n", cli_errstr(cli1
));
3908 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3909 SECOND_DESIRED_ACCESS
, 0,
3910 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
3911 0x200000, 0, &fnum2
))) {
3912 printf("second open failed - %s\n", cli_errstr(cli1
));
3916 if (!torture_close_connection(cli1
)) {
3924 Test rename on files open with share delete and no share delete.
3926 static bool run_rename(int dummy
)
3928 static struct cli_state
*cli1
;
3929 const char *fname
= "\\test.txt";
3930 const char *fname1
= "\\test1.txt";
3931 bool correct
= True
;
3936 printf("starting rename test\n");
3938 if (!torture_open_connection(&cli1
, 0)) {
3942 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3943 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3944 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3945 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3946 printf("First open failed - %s\n", cli_errstr(cli1
));
3950 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3951 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
3953 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3957 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3958 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
3962 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3963 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3964 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3966 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
3968 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
3970 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3971 if (!NT_STATUS_IS_OK(status
)) {
3972 printf("Second open failed - %s\n", cli_errstr(cli1
));
3976 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3977 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
3980 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3983 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3984 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
3988 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3989 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3991 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3992 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3993 printf("Third open failed - %s\n", cli_errstr(cli1
));
4002 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4003 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4004 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4007 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4008 printf("[8] setting delete_on_close on file failed !\n");
4012 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4013 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4019 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4020 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
4023 printf("Third rename succeeded (SHARE_NONE)\n");
4026 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4027 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
4031 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4032 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4036 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4037 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4038 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4042 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4043 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
4045 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4049 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4050 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4054 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4055 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4059 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4060 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4061 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
4065 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4066 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4070 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
4074 * Now check if the first name still exists ...
4077 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4078 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4079 printf("Opening original file after rename of open file fails: %s\n",
4083 printf("Opening original file after rename of open file works ...\n");
4084 (void)cli_close(cli1, fnum2);
4088 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4089 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
4093 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4094 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
))) {
4095 printf("getatr on file %s failed - %s ! \n",
4100 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4101 printf("Renamed file %s has wrong attr 0x%x "
4102 "(should be 0x%x)\n",
4105 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4108 printf("Renamed file %s has archive bit set\n", fname1
);
4112 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4113 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4115 if (!torture_close_connection(cli1
)) {
4122 static bool run_pipe_number(int dummy
)
4124 struct cli_state
*cli1
;
4125 const char *pipe_name
= "\\SPOOLSS";
4129 printf("starting pipenumber test\n");
4130 if (!torture_open_connection(&cli1
, 0)) {
4134 cli_sockopt(cli1
, sockops
);
4136 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4137 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
4138 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
4142 printf("\r%6d", num_pipes
);
4145 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4146 torture_close_connection(cli1
);
4151 Test open mode returns on read-only files.
4153 static bool run_opentest(int dummy
)
4155 static struct cli_state
*cli1
;
4156 static struct cli_state
*cli2
;
4157 const char *fname
= "\\readonly.file";
4158 uint16_t fnum1
, fnum2
;
4161 bool correct
= True
;
4164 printf("starting open test\n");
4166 if (!torture_open_connection(&cli1
, 0)) {
4170 cli_setatr(cli1
, fname
, 0, 0);
4171 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4173 cli_sockopt(cli1
, sockops
);
4175 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4176 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4180 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4181 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4185 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4186 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
4190 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4191 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4195 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4196 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4198 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4199 NT_STATUS_ACCESS_DENIED
)) {
4200 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4203 printf("finished open test 1\n");
4205 cli_close(cli1
, fnum1
);
4207 /* Now try not readonly and ensure ERRbadshare is returned. */
4209 cli_setatr(cli1
, fname
, 0, 0);
4211 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4212 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4216 /* This will fail - but the error should be ERRshare. */
4217 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4219 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4220 NT_STATUS_SHARING_VIOLATION
)) {
4221 printf("correct error code ERRDOS/ERRbadshare returned\n");
4224 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4225 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4229 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4231 printf("finished open test 2\n");
4233 /* Test truncate open disposition on file opened for read. */
4235 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4236 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4240 /* write 20 bytes. */
4242 memset(buf
, '\0', 20);
4244 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4245 printf("write failed (%s)\n", cli_errstr(cli1
));
4249 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4250 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4254 /* Ensure size == 20. */
4255 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4256 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4261 printf("(3) file size != 20\n");
4265 /* Now test if we can truncate a file opened for readonly. */
4267 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4268 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4272 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4273 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4277 /* Ensure size == 0. */
4278 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4279 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4284 printf("(3) file size != 0\n");
4287 printf("finished open test 3\n");
4289 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4291 printf("Do ctemp tests\n");
4292 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4293 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4296 printf("ctemp gave path %s\n", tmp_path
);
4297 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4298 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4300 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4301 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4304 /* Test the non-io opens... */
4306 if (!torture_open_connection(&cli2
, 1)) {
4310 cli_setatr(cli2
, fname
, 0, 0);
4311 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4313 cli_sockopt(cli2
, sockops
);
4315 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4317 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4318 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4319 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4323 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4324 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4325 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4329 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4330 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4333 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4334 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4338 printf("non-io open test #1 passed.\n");
4340 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4342 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4344 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4345 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4346 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4350 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4351 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4352 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4356 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4357 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4360 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4361 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4365 printf("non-io open test #2 passed.\n");
4367 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4369 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4371 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4372 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4373 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4377 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4378 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4379 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4383 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4384 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4387 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4388 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4392 printf("non-io open test #3 passed.\n");
4394 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4396 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4398 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4399 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4400 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4404 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4405 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4406 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4410 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4412 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4413 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4417 printf("non-io open test #4 passed.\n");
4419 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4421 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4423 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4424 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4425 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4429 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4430 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4431 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4435 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4436 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4440 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4441 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4445 printf("non-io open test #5 passed.\n");
4447 printf("TEST #6 testing 1 non-io open, one io open\n");
4449 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4452 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4453 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4457 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4458 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4459 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4463 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4464 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4468 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4469 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4473 printf("non-io open test #6 passed.\n");
4475 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4477 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4479 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4480 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4481 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4485 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4486 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4487 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4491 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4493 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4494 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4498 printf("non-io open test #7 passed.\n");
4500 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4502 if (!torture_close_connection(cli1
)) {
4505 if (!torture_close_connection(cli2
)) {
4512 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4514 uint16 major
, minor
;
4515 uint32 caplow
, caphigh
;
4518 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4519 printf("Server doesn't support UNIX CIFS extensions.\n");
4520 return NT_STATUS_NOT_SUPPORTED
;
4523 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4525 if (!NT_STATUS_IS_OK(status
)) {
4526 printf("Server didn't return UNIX CIFS extensions: %s\n",
4531 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4533 if (!NT_STATUS_IS_OK(status
)) {
4534 printf("Server doesn't support setting UNIX CIFS extensions: "
4535 "%s.\n", nt_errstr(status
));
4539 return NT_STATUS_OK
;
4543 Test POSIX open /mkdir calls.
4545 static bool run_simple_posix_open_test(int dummy
)
4547 static struct cli_state
*cli1
;
4548 const char *fname
= "posix:file";
4549 const char *hname
= "posix:hlink";
4550 const char *sname
= "posix:symlink";
4551 const char *dname
= "posix:dir";
4554 uint16_t fnum1
= (uint16_t)-1;
4555 SMB_STRUCT_STAT sbuf
;
4556 bool correct
= false;
4559 printf("Starting simple POSIX open test\n");
4561 if (!torture_open_connection(&cli1
, 0)) {
4565 cli_sockopt(cli1
, sockops
);
4567 status
= torture_setup_unix_extensions(cli1
);
4568 if (!NT_STATUS_IS_OK(status
)) {
4572 cli_setatr(cli1
, fname
, 0, 0);
4573 cli_posix_unlink(cli1
, fname
);
4574 cli_setatr(cli1
, dname
, 0, 0);
4575 cli_posix_rmdir(cli1
, dname
);
4576 cli_setatr(cli1
, hname
, 0, 0);
4577 cli_posix_unlink(cli1
, hname
);
4578 cli_setatr(cli1
, sname
, 0, 0);
4579 cli_posix_unlink(cli1
, sname
);
4581 /* Create a directory. */
4582 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4583 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4587 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4588 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4592 /* Test ftruncate - set file size. */
4593 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4594 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4598 /* Ensure st_size == 1000 */
4599 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4600 printf("stat failed (%s)\n", cli_errstr(cli1
));
4604 if (sbuf
.st_ex_size
!= 1000) {
4605 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4609 /* Test ftruncate - set file size back to zero. */
4610 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4611 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4615 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4616 printf("close failed (%s)\n", cli_errstr(cli1
));
4620 /* Now open the file again for read only. */
4621 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4622 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4626 /* Now unlink while open. */
4627 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
4628 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4632 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4633 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4637 /* Ensure the file has gone. */
4638 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4639 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4643 /* What happens when we try and POSIX open a directory ? */
4644 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
4645 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
4648 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
4649 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4654 /* Create the file. */
4655 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4656 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4660 /* Write some data into it. */
4661 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4662 printf("cli_write failed: %s\n", cli_errstr(cli1
));
4666 cli_close(cli1
, fnum1
);
4668 /* Now create a hardlink. */
4669 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
4670 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4674 /* Now create a symlink. */
4675 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
4676 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
4680 /* Open the hardlink for read. */
4681 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
4682 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4686 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
4687 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4691 if (memcmp(buf
, "TEST DATA\n", 10)) {
4692 printf("invalid data read from hardlink\n");
4696 /* Do a POSIX lock/unlock. */
4697 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
4698 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
4702 /* Punch a hole in the locked area. */
4703 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
4704 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
4708 cli_close(cli1
, fnum1
);
4710 /* Open the symlink for read - this should fail. A POSIX
4711 client should not be doing opens on a symlink. */
4712 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
4713 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
4716 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
4717 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
4718 printf("POSIX open of %s should have failed "
4719 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4720 "failed with %s instead.\n",
4721 sname
, cli_errstr(cli1
));
4726 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
4727 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
4731 if (strcmp(namebuf
, fname
) != 0) {
4732 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4733 sname
, fname
, namebuf
);
4737 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
4738 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
4742 printf("Simple POSIX open test passed\n");
4747 if (fnum1
!= (uint16_t)-1) {
4748 cli_close(cli1
, fnum1
);
4749 fnum1
= (uint16_t)-1;
4752 cli_setatr(cli1
, sname
, 0, 0);
4753 cli_posix_unlink(cli1
, sname
);
4754 cli_setatr(cli1
, hname
, 0, 0);
4755 cli_posix_unlink(cli1
, hname
);
4756 cli_setatr(cli1
, fname
, 0, 0);
4757 cli_posix_unlink(cli1
, fname
);
4758 cli_setatr(cli1
, dname
, 0, 0);
4759 cli_posix_rmdir(cli1
, dname
);
4761 if (!torture_close_connection(cli1
)) {
4769 static uint32 open_attrs_table
[] = {
4770 FILE_ATTRIBUTE_NORMAL
,
4771 FILE_ATTRIBUTE_ARCHIVE
,
4772 FILE_ATTRIBUTE_READONLY
,
4773 FILE_ATTRIBUTE_HIDDEN
,
4774 FILE_ATTRIBUTE_SYSTEM
,
4776 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
4777 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
4778 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
4779 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4780 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4781 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4783 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4784 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4785 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4786 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
4789 struct trunc_open_results
{
4796 static struct trunc_open_results attr_results
[] = {
4797 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4798 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4799 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4800 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4801 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4802 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4803 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4804 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4805 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4806 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4807 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4808 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
4809 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4810 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4811 { 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
},
4812 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4813 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4814 { 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
},
4815 { 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
},
4816 { 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
},
4817 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4818 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4819 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4820 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4821 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4822 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
4825 static bool run_openattrtest(int dummy
)
4827 static struct cli_state
*cli1
;
4828 const char *fname
= "\\openattr.file";
4830 bool correct
= True
;
4832 unsigned int i
, j
, k
, l
;
4834 printf("starting open attr test\n");
4836 if (!torture_open_connection(&cli1
, 0)) {
4840 cli_sockopt(cli1
, sockops
);
4842 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
4843 cli_setatr(cli1
, fname
, 0, 0);
4844 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4845 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
4846 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4847 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4851 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4852 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4856 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
4857 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
4858 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
4859 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4860 if (attr_results
[l
].num
== k
) {
4861 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4862 k
, open_attrs_table
[i
],
4863 open_attrs_table
[j
],
4864 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
4868 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
4869 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4870 k
, open_attrs_table
[i
], open_attrs_table
[j
],
4875 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
4881 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4882 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
4886 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
4887 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
4892 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4893 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
4896 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4897 if (attr_results
[l
].num
== k
) {
4898 if (attr
!= attr_results
[l
].result_attr
||
4899 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
4900 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
4901 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4902 open_attrs_table
[i
],
4903 open_attrs_table
[j
],
4905 attr_results
[l
].result_attr
);
4915 cli_setatr(cli1
, fname
, 0, 0);
4916 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4918 printf("open attr test %s.\n", correct
? "passed" : "failed");
4920 if (!torture_close_connection(cli1
)) {
4926 static void list_fn(const char *mnt
, struct file_info
*finfo
,
4927 const char *name
, void *state
)
4929 int *matched
= (int *)state
;
4930 if (matched
!= NULL
) {
4936 test directory listing speed
4938 static bool run_dirtest(int dummy
)
4941 static struct cli_state
*cli
;
4943 struct timeval core_start
;
4944 bool correct
= True
;
4947 printf("starting directory test\n");
4949 if (!torture_open_connection(&cli
, 0)) {
4953 cli_sockopt(cli
, sockops
);
4956 for (i
=0;i
<torture_numops
;i
++) {
4958 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4959 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
4960 fprintf(stderr
,"Failed to open %s\n", fname
);
4963 cli_close(cli
, fnum
);
4966 core_start
= timeval_current();
4969 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
4970 printf("Matched %d\n", matched
);
4973 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
4974 printf("Matched %d\n", matched
);
4977 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
4978 printf("Matched %d\n", matched
);
4980 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
4983 for (i
=0;i
<torture_numops
;i
++) {
4985 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4986 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4989 if (!torture_close_connection(cli
)) {
4993 printf("finished dirtest\n");
4998 static void del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5001 struct cli_state
*pcli
= (struct cli_state
*)state
;
5003 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5005 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5008 if (finfo
->mode
& aDIR
) {
5009 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5010 printf("del_fn: failed to rmdir %s\n,", fname
);
5012 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
5013 printf("del_fn: failed to unlink %s\n,", fname
);
5019 sees what IOCTLs are supported
5021 bool torture_ioctl_test(int dummy
)
5023 static struct cli_state
*cli
;
5024 uint16_t device
, function
;
5026 const char *fname
= "\\ioctl.dat";
5030 if (!torture_open_connection(&cli
, 0)) {
5034 printf("starting ioctl test\n");
5036 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5038 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5039 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
5043 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5044 printf("ioctl device info: %s\n", nt_errstr(status
));
5046 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5047 printf("ioctl job info: %s\n", nt_errstr(status
));
5049 for (device
=0;device
<0x100;device
++) {
5050 printf("ioctl test with device = 0x%x\n", device
);
5051 for (function
=0;function
<0x100;function
++) {
5052 uint32 code
= (device
<<16) | function
;
5054 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5056 if (NT_STATUS_IS_OK(status
)) {
5057 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5059 data_blob_free(&blob
);
5064 if (!torture_close_connection(cli
)) {
5073 tries varients of chkpath
5075 bool torture_chkpath_test(int dummy
)
5077 static struct cli_state
*cli
;
5081 if (!torture_open_connection(&cli
, 0)) {
5085 printf("starting chkpath test\n");
5087 /* cleanup from an old run */
5088 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5089 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5090 cli_rmdir(cli
, "\\chkpath.dir");
5092 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
5093 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
5097 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
5098 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
5102 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5103 printf("open1 failed (%s)\n", cli_errstr(cli
));
5106 cli_close(cli
, fnum
);
5108 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
5109 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
5113 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
5114 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
5118 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
5119 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5120 NT_STATUS_NOT_A_DIRECTORY
);
5122 printf("* chkpath on a file should fail\n");
5126 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
5127 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
5128 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
5130 printf("* chkpath on a non existant file should fail\n");
5134 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5135 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5136 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
5138 printf("* chkpath on a non existent component should fail\n");
5142 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5143 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5144 cli_rmdir(cli
, "\\chkpath.dir");
5146 if (!torture_close_connection(cli
)) {
5153 static bool run_eatest(int dummy
)
5155 static struct cli_state
*cli
;
5156 const char *fname
= "\\eatest.txt";
5157 bool correct
= True
;
5161 struct ea_struct
*ea_list
= NULL
;
5162 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5165 printf("starting eatest\n");
5167 if (!torture_open_connection(&cli
, 0)) {
5168 talloc_destroy(mem_ctx
);
5172 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5173 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5174 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5175 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5176 0x4044, 0, &fnum
))) {
5177 printf("open failed - %s\n", cli_errstr(cli
));
5178 talloc_destroy(mem_ctx
);
5182 for (i
= 0; i
< 10; i
++) {
5183 fstring ea_name
, ea_val
;
5185 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5186 memset(ea_val
, (char)i
+1, i
+1);
5187 if (!cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1)) {
5188 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5189 talloc_destroy(mem_ctx
);
5194 cli_close(cli
, fnum
);
5195 for (i
= 0; i
< 10; i
++) {
5196 fstring ea_name
, ea_val
;
5198 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5199 memset(ea_val
, (char)i
+1, i
+1);
5200 if (!cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1)) {
5201 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5202 talloc_destroy(mem_ctx
);
5207 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5208 if (!NT_STATUS_IS_OK(status
)) {
5209 printf("ea_get list failed - %s\n", nt_errstr(status
));
5213 printf("num_eas = %d\n", (int)num_eas
);
5215 if (num_eas
!= 20) {
5216 printf("Should be 20 EA's stored... failing.\n");
5220 for (i
= 0; i
< num_eas
; i
++) {
5221 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5222 dump_data(0, ea_list
[i
].value
.data
,
5223 ea_list
[i
].value
.length
);
5226 /* Setting EA's to zero length deletes them. Test this */
5227 printf("Now deleting all EA's - case indepenent....\n");
5230 cli_set_ea_path(cli
, fname
, "", "", 0);
5232 for (i
= 0; i
< 20; i
++) {
5234 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5235 if (!cli_set_ea_path(cli
, fname
, ea_name
, "", 0)) {
5236 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5237 talloc_destroy(mem_ctx
);
5243 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5244 if (!NT_STATUS_IS_OK(status
)) {
5245 printf("ea_get list failed - %s\n", nt_errstr(status
));
5249 printf("num_eas = %d\n", (int)num_eas
);
5250 for (i
= 0; i
< num_eas
; i
++) {
5251 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5252 dump_data(0, ea_list
[i
].value
.data
,
5253 ea_list
[i
].value
.length
);
5257 printf("deleting EA's failed.\n");
5261 /* Try and delete a non existant EA. */
5262 if (!cli_set_ea_path(cli
, fname
, "foo", "", 0)) {
5263 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli
));
5267 talloc_destroy(mem_ctx
);
5268 if (!torture_close_connection(cli
)) {
5275 static bool run_dirtest1(int dummy
)
5278 static struct cli_state
*cli
;
5281 bool correct
= True
;
5283 printf("starting directory test\n");
5285 if (!torture_open_connection(&cli
, 0)) {
5289 cli_sockopt(cli
, sockops
);
5291 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5292 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5293 cli_rmdir(cli
, "\\LISTDIR");
5294 cli_mkdir(cli
, "\\LISTDIR");
5296 /* Create 1000 files and 1000 directories. */
5297 for (i
=0;i
<1000;i
++) {
5299 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5300 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5301 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5302 fprintf(stderr
,"Failed to open %s\n", fname
);
5305 cli_close(cli
, fnum
);
5307 for (i
=0;i
<1000;i
++) {
5309 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5310 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5311 fprintf(stderr
,"Failed to open %s\n", fname
);
5316 /* Now ensure that doing an old list sees both files and directories. */
5318 cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, &num_seen
);
5319 printf("num_seen = %d\n", num_seen
);
5320 /* We should see 100 files + 1000 directories + . and .. */
5321 if (num_seen
!= 2002)
5324 /* Ensure if we have the "must have" bits we only see the
5328 cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, &num_seen
);
5329 printf("num_seen = %d\n", num_seen
);
5330 if (num_seen
!= 1002)
5334 cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, &num_seen
);
5335 printf("num_seen = %d\n", num_seen
);
5336 if (num_seen
!= 1000)
5339 /* Delete everything. */
5340 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5341 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5342 cli_rmdir(cli
, "\\LISTDIR");
5345 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5346 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5347 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5350 if (!torture_close_connection(cli
)) {
5354 printf("finished dirtest1\n");
5359 static bool run_error_map_extract(int dummy
) {
5361 static struct cli_state
*c_dos
;
5362 static struct cli_state
*c_nt
;
5367 uint32 flgs2
, errnum
;
5374 /* NT-Error connection */
5376 if (!(c_nt
= open_nbt_connection())) {
5380 c_nt
->use_spnego
= False
;
5382 status
= cli_negprot(c_nt
);
5384 if (!NT_STATUS_IS_OK(status
)) {
5385 printf("%s rejected the NT-error negprot (%s)\n", host
,
5391 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5393 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5397 /* DOS-Error connection */
5399 if (!(c_dos
= open_nbt_connection())) {
5403 c_dos
->use_spnego
= False
;
5404 c_dos
->force_dos_errors
= True
;
5406 status
= cli_negprot(c_dos
);
5407 if (!NT_STATUS_IS_OK(status
)) {
5408 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5410 cli_shutdown(c_dos
);
5414 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5416 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5420 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5421 fstr_sprintf(user
, "%X", error
);
5423 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5424 password
, strlen(password
),
5425 password
, strlen(password
),
5427 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5430 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5432 /* Case #1: 32-bit NT errors */
5433 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5434 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5436 printf("/** Dos error on NT connection! (%s) */\n",
5438 nt_status
= NT_STATUS(0xc0000000);
5441 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5442 password
, strlen(password
),
5443 password
, strlen(password
),
5445 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5447 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5449 /* Case #1: 32-bit NT errors */
5450 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5451 printf("/** NT error on DOS connection! (%s) */\n",
5453 errnum
= errclass
= 0;
5455 cli_dos_error(c_dos
, &errclass
, &errnum
);
5458 if (NT_STATUS_V(nt_status
) != error
) {
5459 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5460 get_nt_error_c_code(NT_STATUS(error
)),
5461 get_nt_error_c_code(nt_status
));
5464 printf("\t{%s,\t%s,\t%s},\n",
5465 smb_dos_err_class(errclass
),
5466 smb_dos_err_name(errclass
, errnum
),
5467 get_nt_error_c_code(NT_STATUS(error
)));
5472 static bool run_sesssetup_bench(int dummy
)
5474 static struct cli_state
*c
;
5475 const char *fname
= "\\file.dat";
5480 if (!torture_open_connection(&c
, 0)) {
5484 if (!NT_STATUS_IS_OK(cli_ntcreate(
5485 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5486 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5487 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5488 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5492 for (i
=0; i
<torture_numops
; i
++) {
5493 status
= cli_session_setup(
5495 password
, strlen(password
),
5496 password
, strlen(password
),
5498 if (!NT_STATUS_IS_OK(status
)) {
5499 d_printf("(%s) cli_session_setup failed: %s\n",
5500 __location__
, nt_errstr(status
));
5504 d_printf("\r%d ", (int)c
->vuid
);
5506 status
= cli_ulogoff(c
);
5507 if (!NT_STATUS_IS_OK(status
)) {
5508 d_printf("(%s) cli_ulogoff failed: %s\n",
5509 __location__
, nt_errstr(status
));
5518 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5519 uid_t uid
, gid_t gid
, const char *expected
)
5524 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5526 if (strcmp(subst
, expected
) != 0) {
5527 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5528 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5537 static void chain1_open_completion(struct tevent_req
*req
)
5541 status
= cli_open_recv(req
, &fnum
);
5544 d_printf("cli_open_recv returned %s: %d\n",
5546 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5549 static void chain1_write_completion(struct tevent_req
*req
)
5553 status
= cli_write_andx_recv(req
, &written
);
5556 d_printf("cli_write_andx_recv returned %s: %d\n",
5558 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5561 static void chain1_close_completion(struct tevent_req
*req
)
5564 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5566 status
= cli_close_recv(req
);
5571 d_printf("cli_close returned %s\n", nt_errstr(status
));
5574 static bool run_chain1(int dummy
)
5576 struct cli_state
*cli1
;
5577 struct event_context
*evt
= event_context_init(NULL
);
5578 struct tevent_req
*reqs
[3], *smbreqs
[3];
5580 const char *str
= "foobar";
5583 printf("starting chain1 test\n");
5584 if (!torture_open_connection(&cli1
, 0)) {
5588 cli_sockopt(cli1
, sockops
);
5590 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5591 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5592 if (reqs
[0] == NULL
) return false;
5593 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5596 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5597 (uint8_t *)str
, 0, strlen(str
)+1,
5598 smbreqs
, 1, &smbreqs
[1]);
5599 if (reqs
[1] == NULL
) return false;
5600 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5602 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5603 if (reqs
[2] == NULL
) return false;
5604 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5606 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5607 if (!NT_STATUS_IS_OK(status
)) {
5612 event_loop_once(evt
);
5615 torture_close_connection(cli1
);
5619 static void chain2_sesssetup_completion(struct tevent_req
*req
)
5622 status
= cli_session_setup_guest_recv(req
);
5623 d_printf("sesssetup returned %s\n", nt_errstr(status
));
5626 static void chain2_tcon_completion(struct tevent_req
*req
)
5628 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5630 status
= cli_tcon_andx_recv(req
);
5631 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
5635 static bool run_chain2(int dummy
)
5637 struct cli_state
*cli1
;
5638 struct event_context
*evt
= event_context_init(NULL
);
5639 struct tevent_req
*reqs
[2], *smbreqs
[2];
5643 printf("starting chain2 test\n");
5644 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
5645 port_to_use
, Undefined
, 0, NULL
);
5646 if (!NT_STATUS_IS_OK(status
)) {
5650 cli_sockopt(cli1
, sockops
);
5652 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
5654 if (reqs
[0] == NULL
) return false;
5655 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
5657 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
5658 "?????", NULL
, 0, &smbreqs
[1]);
5659 if (reqs
[1] == NULL
) return false;
5660 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
5662 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5663 if (!NT_STATUS_IS_OK(status
)) {
5668 event_loop_once(evt
);
5671 torture_close_connection(cli1
);
5676 struct torture_createdel_state
{
5677 struct tevent_context
*ev
;
5678 struct cli_state
*cli
;
5681 static void torture_createdel_created(struct tevent_req
*subreq
);
5682 static void torture_createdel_closed(struct tevent_req
*subreq
);
5684 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
5685 struct tevent_context
*ev
,
5686 struct cli_state
*cli
,
5689 struct tevent_req
*req
, *subreq
;
5690 struct torture_createdel_state
*state
;
5692 req
= tevent_req_create(mem_ctx
, &state
,
5693 struct torture_createdel_state
);
5700 subreq
= cli_ntcreate_send(
5701 state
, ev
, cli
, name
, 0,
5702 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5703 FILE_ATTRIBUTE_NORMAL
,
5704 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5705 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
5707 if (tevent_req_nomem(subreq
, req
)) {
5708 return tevent_req_post(req
, ev
);
5710 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
5714 static void torture_createdel_created(struct tevent_req
*subreq
)
5716 struct tevent_req
*req
= tevent_req_callback_data(
5717 subreq
, struct tevent_req
);
5718 struct torture_createdel_state
*state
= tevent_req_data(
5719 req
, struct torture_createdel_state
);
5723 status
= cli_ntcreate_recv(subreq
, &fnum
);
5724 TALLOC_FREE(subreq
);
5725 if (!NT_STATUS_IS_OK(status
)) {
5726 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5727 nt_errstr(status
)));
5728 tevent_req_nterror(req
, status
);
5732 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
5733 if (tevent_req_nomem(subreq
, req
)) {
5736 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
5739 static void torture_createdel_closed(struct tevent_req
*subreq
)
5741 struct tevent_req
*req
= tevent_req_callback_data(
5742 subreq
, struct tevent_req
);
5745 status
= cli_close_recv(subreq
);
5746 if (!NT_STATUS_IS_OK(status
)) {
5747 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
5748 tevent_req_nterror(req
, status
);
5751 tevent_req_done(req
);
5754 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
5756 return tevent_req_simple_recv_ntstatus(req
);
5759 struct torture_createdels_state
{
5760 struct tevent_context
*ev
;
5761 struct cli_state
*cli
;
5762 const char *base_name
;
5766 struct tevent_req
**reqs
;
5769 static void torture_createdels_done(struct tevent_req
*subreq
);
5771 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
5772 struct tevent_context
*ev
,
5773 struct cli_state
*cli
,
5774 const char *base_name
,
5778 struct tevent_req
*req
;
5779 struct torture_createdels_state
*state
;
5782 req
= tevent_req_create(mem_ctx
, &state
,
5783 struct torture_createdels_state
);
5789 state
->base_name
= talloc_strdup(state
, base_name
);
5790 if (tevent_req_nomem(state
->base_name
, req
)) {
5791 return tevent_req_post(req
, ev
);
5793 state
->num_files
= MAX(num_parallel
, num_files
);
5795 state
->received
= 0;
5797 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
5798 if (tevent_req_nomem(state
->reqs
, req
)) {
5799 return tevent_req_post(req
, ev
);
5802 for (i
=0; i
<num_parallel
; i
++) {
5805 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5807 if (tevent_req_nomem(name
, req
)) {
5808 return tevent_req_post(req
, ev
);
5810 state
->reqs
[i
] = torture_createdel_send(
5811 state
->reqs
, state
->ev
, state
->cli
, name
);
5812 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5813 return tevent_req_post(req
, ev
);
5815 name
= talloc_move(state
->reqs
[i
], &name
);
5816 tevent_req_set_callback(state
->reqs
[i
],
5817 torture_createdels_done
, req
);
5823 static void torture_createdels_done(struct tevent_req
*subreq
)
5825 struct tevent_req
*req
= tevent_req_callback_data(
5826 subreq
, struct tevent_req
);
5827 struct torture_createdels_state
*state
= tevent_req_data(
5828 req
, struct torture_createdels_state
);
5829 size_t num_parallel
= talloc_array_length(state
->reqs
);
5834 status
= torture_createdel_recv(subreq
);
5835 if (!NT_STATUS_IS_OK(status
)){
5836 DEBUG(10, ("torture_createdel_recv returned %s\n",
5837 nt_errstr(status
)));
5838 TALLOC_FREE(subreq
);
5839 tevent_req_nterror(req
, status
);
5843 for (i
=0; i
<num_parallel
; i
++) {
5844 if (subreq
== state
->reqs
[i
]) {
5848 if (i
== num_parallel
) {
5849 DEBUG(10, ("received something we did not send\n"));
5850 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
5853 TALLOC_FREE(state
->reqs
[i
]);
5855 if (state
->sent
>= state
->num_files
) {
5856 tevent_req_done(req
);
5860 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5862 if (tevent_req_nomem(name
, req
)) {
5865 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
5867 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5870 name
= talloc_move(state
->reqs
[i
], &name
);
5871 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
5875 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
5877 return tevent_req_simple_recv_ntstatus(req
);
5880 struct swallow_notify_state
{
5881 struct tevent_context
*ev
;
5882 struct cli_state
*cli
;
5884 uint32_t completion_filter
;
5886 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
5890 static void swallow_notify_done(struct tevent_req
*subreq
);
5892 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
5893 struct tevent_context
*ev
,
5894 struct cli_state
*cli
,
5896 uint32_t completion_filter
,
5898 bool (*fn
)(uint32_t action
,
5903 struct tevent_req
*req
, *subreq
;
5904 struct swallow_notify_state
*state
;
5906 req
= tevent_req_create(mem_ctx
, &state
,
5907 struct swallow_notify_state
);
5914 state
->completion_filter
= completion_filter
;
5915 state
->recursive
= recursive
;
5919 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5920 0xffff, state
->completion_filter
,
5922 if (tevent_req_nomem(subreq
, req
)) {
5923 return tevent_req_post(req
, ev
);
5925 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5929 static void swallow_notify_done(struct tevent_req
*subreq
)
5931 struct tevent_req
*req
= tevent_req_callback_data(
5932 subreq
, struct tevent_req
);
5933 struct swallow_notify_state
*state
= tevent_req_data(
5934 req
, struct swallow_notify_state
);
5936 uint32_t i
, num_changes
;
5937 struct notify_change
*changes
;
5939 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
5940 TALLOC_FREE(subreq
);
5941 if (!NT_STATUS_IS_OK(status
)) {
5942 DEBUG(10, ("cli_notify_recv returned %s\n",
5943 nt_errstr(status
)));
5944 tevent_req_nterror(req
, status
);
5948 for (i
=0; i
<num_changes
; i
++) {
5949 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
5951 TALLOC_FREE(changes
);
5953 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5954 0xffff, state
->completion_filter
,
5956 if (tevent_req_nomem(subreq
, req
)) {
5959 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5962 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
5964 if (DEBUGLEVEL
> 5) {
5965 d_printf("%d %s\n", (int)action
, name
);
5970 static void notify_bench_done(struct tevent_req
*req
)
5972 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
5976 static bool run_notify_bench(int dummy
)
5978 const char *dname
= "\\notify-bench";
5979 struct tevent_context
*ev
;
5982 struct tevent_req
*req1
;
5983 struct tevent_req
*req2
= NULL
;
5984 int i
, num_unc_names
;
5985 int num_finished
= 0;
5987 printf("starting notify-bench test\n");
5989 if (use_multishare_conn
) {
5991 unc_list
= file_lines_load(multishare_conn_fname
,
5992 &num_unc_names
, 0, NULL
);
5993 if (!unc_list
|| num_unc_names
<= 0) {
5994 d_printf("Failed to load unc names list from '%s'\n",
5995 multishare_conn_fname
);
5998 TALLOC_FREE(unc_list
);
6003 ev
= tevent_context_init(talloc_tos());
6005 d_printf("tevent_context_init failed\n");
6009 for (i
=0; i
<num_unc_names
; i
++) {
6010 struct cli_state
*cli
;
6013 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6015 if (base_fname
== NULL
) {
6019 if (!torture_open_connection(&cli
, i
)) {
6023 status
= cli_ntcreate(cli
, dname
, 0,
6024 MAXIMUM_ALLOWED_ACCESS
,
6025 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6027 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6030 if (!NT_STATUS_IS_OK(status
)) {
6031 d_printf("Could not create %s: %s\n", dname
,
6036 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6037 FILE_NOTIFY_CHANGE_FILE_NAME
|
6038 FILE_NOTIFY_CHANGE_DIR_NAME
|
6039 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6040 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6041 false, print_notifies
, NULL
);
6043 d_printf("Could not create notify request\n");
6047 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6048 base_fname
, 10, torture_numops
);
6050 d_printf("Could not create createdels request\n");
6053 TALLOC_FREE(base_fname
);
6055 tevent_req_set_callback(req2
, notify_bench_done
,
6059 while (num_finished
< num_unc_names
) {
6061 ret
= tevent_loop_once(ev
);
6063 d_printf("tevent_loop_once failed\n");
6068 if (!tevent_req_poll(req2
, ev
)) {
6069 d_printf("tevent_req_poll failed\n");
6072 status
= torture_createdels_recv(req2
);
6073 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
6078 static bool run_mangle1(int dummy
)
6080 struct cli_state
*cli
;
6081 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
6085 time_t change_time
, access_time
, write_time
;
6089 printf("starting mangle1 test\n");
6090 if (!torture_open_connection(&cli
, 0)) {
6094 cli_sockopt(cli
, sockops
);
6096 if (!NT_STATUS_IS_OK(cli_ntcreate(
6097 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6098 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6099 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
6102 cli_close(cli
, fnum
);
6104 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
6105 if (!NT_STATUS_IS_OK(status
)) {
6106 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6110 d_printf("alt_name: %s\n", alt_name
);
6112 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
6113 d_printf("cli_open(%s) failed: %s\n", alt_name
,
6117 cli_close(cli
, fnum
);
6119 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
6120 &write_time
, &size
, &mode
);
6121 if (!NT_STATUS_IS_OK(status
)) {
6122 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
6130 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
6132 size_t *to_pull
= (size_t *)priv
;
6133 size_t thistime
= *to_pull
;
6135 thistime
= MIN(thistime
, n
);
6136 if (thistime
== 0) {
6140 memset(buf
, 0, thistime
);
6141 *to_pull
-= thistime
;
6145 static bool run_windows_write(int dummy
)
6147 struct cli_state
*cli1
;
6151 const char *fname
= "\\writetest.txt";
6152 struct timeval start_time
;
6156 printf("starting windows_write test\n");
6157 if (!torture_open_connection(&cli1
, 0)) {
6161 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
6162 printf("open failed (%s)\n", cli_errstr(cli1
));
6166 cli_sockopt(cli1
, sockops
);
6168 start_time
= timeval_current();
6170 for (i
=0; i
<torture_numops
; i
++) {
6172 off_t start
= i
* torture_blocksize
;
6174 size_t to_pull
= torture_blocksize
- 1;
6176 if (cli_write(cli1
, fnum
, 0, &c
,
6177 start
+ torture_blocksize
- 1, 1) != 1) {
6178 printf("cli_write failed: %s\n", cli_errstr(cli1
));
6182 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6183 null_source
, &to_pull
);
6184 if (!NT_STATUS_IS_OK(status
)) {
6185 printf("cli_push returned: %s\n", nt_errstr(status
));
6190 seconds
= timeval_elapsed(&start_time
);
6191 kbytes
= (double)torture_blocksize
* torture_numops
;
6194 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6195 (double)seconds
, (int)(kbytes
/seconds
));
6199 cli_close(cli1
, fnum
);
6200 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6201 torture_close_connection(cli1
);
6205 static bool run_cli_echo(int dummy
)
6207 struct cli_state
*cli
;
6210 printf("starting cli_echo test\n");
6211 if (!torture_open_connection(&cli
, 0)) {
6214 cli_sockopt(cli
, sockops
);
6216 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6218 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6220 torture_close_connection(cli
);
6221 return NT_STATUS_IS_OK(status
);
6224 static bool run_uid_regression_test(int dummy
)
6226 static struct cli_state
*cli
;
6229 bool correct
= True
;
6232 printf("starting uid regression test\n");
6234 if (!torture_open_connection(&cli
, 0)) {
6238 cli_sockopt(cli
, sockops
);
6240 /* Ok - now save then logoff our current user. */
6241 old_vuid
= cli
->vuid
;
6243 status
= cli_ulogoff(cli
);
6244 if (!NT_STATUS_IS_OK(status
)) {
6245 d_printf("(%s) cli_ulogoff failed: %s\n",
6246 __location__
, nt_errstr(status
));
6251 cli
->vuid
= old_vuid
;
6253 /* Try an operation. */
6254 status
= cli_mkdir(cli
, "\\uid_reg_test");
6255 if (NT_STATUS_IS_OK(status
)) {
6256 d_printf("(%s) cli_mkdir succeeded\n",
6261 /* Should be bad uid. */
6262 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6263 NT_STATUS_USER_SESSION_DELETED
)) {
6269 old_cnum
= cli
->cnum
;
6271 /* Now try a SMBtdis with the invald vuid set to zero. */
6274 /* This should succeed. */
6275 status
= cli_tdis(cli
);
6277 if (NT_STATUS_IS_OK(status
)) {
6278 d_printf("First tdis with invalid vuid should succeed.\n");
6280 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
6285 cli
->vuid
= old_vuid
;
6286 cli
->cnum
= old_cnum
;
6288 /* This should fail. */
6289 status
= cli_tdis(cli
);
6290 if (NT_STATUS_IS_OK(status
)) {
6291 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6295 /* Should be bad tid. */
6296 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6297 NT_STATUS_NETWORK_NAME_DELETED
)) {
6303 cli_rmdir(cli
, "\\uid_reg_test");
6312 static const char *illegal_chars
= "*\\/?<>|\":";
6313 static char force_shortname_chars
[] = " +,.[];=\177";
6315 static void shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
6316 const char *mask
, void *state
)
6318 struct cli_state
*pcli
= (struct cli_state
*)state
;
6320 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6322 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6325 if (finfo
->mode
& aDIR
) {
6326 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
6327 printf("del_fn: failed to rmdir %s\n,", fname
);
6329 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
6330 printf("del_fn: failed to unlink %s\n,", fname
);
6340 static void shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
6341 const char *name
, void *state
)
6343 struct sn_state
*s
= (struct sn_state
*)state
;
6347 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6348 i
, finfo
->name
, finfo
->short_name
);
6351 if (strchr(force_shortname_chars
, i
)) {
6352 if (!finfo
->short_name
[0]) {
6353 /* Shortname not created when it should be. */
6354 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6355 __location__
, finfo
->name
, i
);
6358 } else if (finfo
->short_name
[0]){
6359 /* Shortname created when it should not be. */
6360 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6361 __location__
, finfo
->short_name
, finfo
->name
);
6367 static bool run_shortname_test(int dummy
)
6369 static struct cli_state
*cli
;
6370 bool correct
= True
;
6375 printf("starting shortname test\n");
6377 if (!torture_open_connection(&cli
, 0)) {
6381 cli_sockopt(cli
, sockops
);
6383 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6384 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6385 cli_rmdir(cli
, "\\shortname");
6387 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6388 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6389 __location__
, cli_errstr(cli
));
6394 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6395 strlcat(fname
, "test .txt", sizeof(fname
));
6399 for (i
= 32; i
< 128; i
++) {
6401 uint16_t fnum
= (uint16_t)-1;
6405 if (strchr(illegal_chars
, i
)) {
6410 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6411 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6412 if (!NT_STATUS_IS_OK(status
)) {
6413 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6414 __location__
, fname
, cli_errstr(cli
));
6418 cli_close(cli
, fnum
);
6421 cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
,
6423 if (s
.matched
!= 1) {
6424 d_printf("(%s) failed to list %s: %s\n",
6425 __location__
, fname
, cli_errstr(cli
));
6429 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6430 d_printf("(%s) failed to delete %s: %s\n",
6431 __location__
, fname
, cli_errstr(cli
));
6444 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6445 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6446 cli_rmdir(cli
, "\\shortname");
6447 torture_close_connection(cli
);
6451 static void pagedsearch_cb(struct tevent_req
*req
)
6454 struct tldap_message
*msg
;
6457 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6458 if (rc
!= TLDAP_SUCCESS
) {
6459 d_printf("tldap_search_paged_recv failed: %s\n",
6460 tldap_err2string(rc
));
6463 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6467 if (!tldap_entry_dn(msg
, &dn
)) {
6468 d_printf("tldap_entry_dn failed\n");
6471 d_printf("%s\n", dn
);
6475 static bool run_tldap(int dummy
)
6477 struct tldap_context
*ld
;
6480 struct sockaddr_storage addr
;
6481 struct tevent_context
*ev
;
6482 struct tevent_req
*req
;
6486 if (!resolve_name(host
, &addr
, 0, false)) {
6487 d_printf("could not find host %s\n", host
);
6490 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6491 if (!NT_STATUS_IS_OK(status
)) {
6492 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6496 ld
= tldap_context_create(talloc_tos(), fd
);
6499 d_printf("tldap_context_create failed\n");
6503 rc
= tldap_fetch_rootdse(ld
);
6504 if (rc
!= TLDAP_SUCCESS
) {
6505 d_printf("tldap_fetch_rootdse failed: %s\n",
6506 tldap_errstr(talloc_tos(), ld
, rc
));
6510 basedn
= tldap_talloc_single_attribute(
6511 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6512 if (basedn
== NULL
) {
6513 d_printf("no defaultNamingContext\n");
6516 d_printf("defaultNamingContext: %s\n", basedn
);
6518 ev
= tevent_context_init(talloc_tos());
6520 d_printf("tevent_context_init failed\n");
6524 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6525 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6527 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6529 d_printf("tldap_search_paged_send failed\n");
6532 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6534 tevent_req_poll(req
, ev
);
6538 /* test search filters against rootDSE */
6539 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6540 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6542 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
6543 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
6544 talloc_tos(), NULL
, NULL
);
6545 if (rc
!= TLDAP_SUCCESS
) {
6546 d_printf("tldap_search with complex filter failed: %s\n",
6547 tldap_errstr(talloc_tos(), ld
, rc
));
6555 /* Torture test to ensure no regression of :
6556 https://bugzilla.samba.org/show_bug.cgi?id=7084
6559 static bool run_dir_createtime(int dummy
)
6561 struct cli_state
*cli
;
6562 const char *dname
= "\\testdir";
6563 const char *fname
= "\\testdir\\testfile";
6565 struct timespec create_time
;
6566 struct timespec create_time1
;
6570 if (!torture_open_connection(&cli
, 0)) {
6574 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6575 cli_rmdir(cli
, dname
);
6577 status
= cli_mkdir(cli
, dname
);
6578 if (!NT_STATUS_IS_OK(status
)) {
6579 printf("mkdir failed: %s\n", nt_errstr(status
));
6583 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
6585 if (!NT_STATUS_IS_OK(status
)) {
6586 printf("cli_qpathinfo2 returned %s\n",
6591 /* Sleep 3 seconds, then create a file. */
6594 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
6596 if (!NT_STATUS_IS_OK(status
)) {
6597 printf("cli_open failed: %s\n", nt_errstr(status
));
6601 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
6603 if (!NT_STATUS_IS_OK(status
)) {
6604 printf("cli_qpathinfo2 (2) returned %s\n",
6609 if (timespec_compare(&create_time1
, &create_time
)) {
6610 printf("run_dir_createtime: create time was updated (error)\n");
6612 printf("run_dir_createtime: create time was not updated (correct)\n");
6618 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6619 cli_rmdir(cli
, dname
);
6620 if (!torture_close_connection(cli
)) {
6627 static bool run_streamerror(int dummy
)
6629 struct cli_state
*cli
;
6630 const char *dname
= "\\testdir";
6631 const char *streamname
=
6632 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6634 time_t change_time
, access_time
, write_time
;
6636 uint16_t mode
, fnum
;
6639 if (!torture_open_connection(&cli
, 0)) {
6643 cli_unlink(cli
, "\\testdir\\*", aSYSTEM
| aHIDDEN
);
6644 cli_rmdir(cli
, dname
);
6646 status
= cli_mkdir(cli
, dname
);
6647 if (!NT_STATUS_IS_OK(status
)) {
6648 printf("mkdir failed: %s\n", nt_errstr(status
));
6652 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
6654 status
= cli_nt_error(cli
);
6656 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6657 printf("pathinfo returned %s, expected "
6658 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6663 status
= cli_ntcreate(cli
, streamname
, 0x16,
6664 FILE_READ_DATA
|FILE_READ_EA
|
6665 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
6666 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6667 FILE_OPEN
, 0, 0, &fnum
);
6669 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6670 printf("ntcreate returned %s, expected "
6671 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6677 cli_rmdir(cli
, dname
);
6681 static bool run_local_substitute(int dummy
)
6685 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
6686 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6687 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6688 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6689 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
6690 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
6691 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6692 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6694 /* Different captialization rules in sub_basic... */
6696 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6702 static bool run_local_base64(int dummy
)
6707 for (i
=1; i
<2000; i
++) {
6708 DATA_BLOB blob1
, blob2
;
6711 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
6713 generate_random_buffer(blob1
.data
, blob1
.length
);
6715 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
6717 d_fprintf(stderr
, "base64_encode_data_blob failed "
6718 "for %d bytes\n", i
);
6721 blob2
= base64_decode_data_blob(b64
);
6724 if (data_blob_cmp(&blob1
, &blob2
)) {
6725 d_fprintf(stderr
, "data_blob_cmp failed for %d "
6729 TALLOC_FREE(blob1
.data
);
6730 data_blob_free(&blob2
);
6735 static bool run_local_gencache(int dummy
)
6741 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
6742 d_printf("%s: gencache_set() failed\n", __location__
);
6746 if (!gencache_get("foo", NULL
, NULL
)) {
6747 d_printf("%s: gencache_get() failed\n", __location__
);
6751 if (!gencache_get("foo", &val
, &tm
)) {
6752 d_printf("%s: gencache_get() failed\n", __location__
);
6756 if (strcmp(val
, "bar") != 0) {
6757 d_printf("%s: gencache_get() returned %s, expected %s\n",
6758 __location__
, val
, "bar");
6765 if (!gencache_del("foo")) {
6766 d_printf("%s: gencache_del() failed\n", __location__
);
6769 if (gencache_del("foo")) {
6770 d_printf("%s: second gencache_del() succeeded\n",
6775 if (gencache_get("foo", &val
, &tm
)) {
6776 d_printf("%s: gencache_get() on deleted entry "
6777 "succeeded\n", __location__
);
6781 blob
= data_blob_string_const_null("bar");
6782 tm
= time(NULL
) + 60;
6784 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
6785 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
6789 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6790 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
6794 if (strcmp((const char *)blob
.data
, "bar") != 0) {
6795 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6796 __location__
, (const char *)blob
.data
, "bar");
6797 data_blob_free(&blob
);
6801 data_blob_free(&blob
);
6803 if (!gencache_del("foo")) {
6804 d_printf("%s: gencache_del() failed\n", __location__
);
6807 if (gencache_del("foo")) {
6808 d_printf("%s: second gencache_del() succeeded\n",
6813 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6814 d_printf("%s: gencache_get_data_blob() on deleted entry "
6815 "succeeded\n", __location__
);
6822 static bool rbt_testval(struct db_context
*db
, const char *key
,
6825 struct db_record
*rec
;
6826 TDB_DATA data
= string_tdb_data(value
);
6830 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6832 d_fprintf(stderr
, "fetch_locked failed\n");
6835 status
= rec
->store(rec
, data
, 0);
6836 if (!NT_STATUS_IS_OK(status
)) {
6837 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
6842 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6844 d_fprintf(stderr
, "second fetch_locked failed\n");
6847 if ((rec
->value
.dsize
!= data
.dsize
)
6848 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
6849 d_fprintf(stderr
, "Got wrong data back\n");
6859 static bool run_local_rbtree(int dummy
)
6861 struct db_context
*db
;
6865 db
= db_open_rbt(NULL
);
6868 d_fprintf(stderr
, "db_open_rbt failed\n");
6872 for (i
=0; i
<1000; i
++) {
6875 if (asprintf(&key
, "key%ld", random()) == -1) {
6878 if (asprintf(&value
, "value%ld", random()) == -1) {
6883 if (!rbt_testval(db
, key
, value
)) {
6890 if (asprintf(&value
, "value%ld", random()) == -1) {
6895 if (!rbt_testval(db
, key
, value
)) {
6912 struct talloc_dict_test
{
6916 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
6918 int *count
= (int *)priv
;
6923 static bool run_local_talloc_dict(int dummy
)
6925 struct talloc_dict
*dict
;
6926 struct talloc_dict_test
*t
;
6929 dict
= talloc_dict_init(talloc_tos());
6934 t
= talloc(talloc_tos(), struct talloc_dict_test
);
6941 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
6946 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
6959 static bool run_local_string_to_sid(int dummy
) {
6962 if (string_to_sid(&sid
, "S--1-5-32-545")) {
6963 printf("allowing S--1-5-32-545\n");
6966 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
6967 printf("allowing S-1-5-32-+545\n");
6970 if (string_to_sid(&sid
, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6971 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6974 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
6975 printf("allowing S-1-5-32-545-abc\n");
6978 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
6979 printf("could not parse S-1-5-32-545\n");
6982 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
6983 printf("mis-parsed S-1-5-32-545 as %s\n",
6984 sid_string_tos(&sid
));
6990 static bool run_local_binary_to_sid(int dummy
) {
6991 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
6992 static const char good_binary_sid
[] = {
6993 0x1, /* revision number */
6995 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
6996 0x1, 0x1, 0x1, 0x1, /* auth[0] */
6997 0x1, 0x1, 0x1, 0x1, /* auth[1] */
6998 0x1, 0x1, 0x1, 0x1, /* auth[2] */
6999 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7000 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7001 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7002 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7003 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7004 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7005 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7006 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7007 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7008 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7009 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7010 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7013 static const char long_binary_sid
[] = {
7014 0x1, /* revision number */
7016 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7017 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7018 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7019 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7020 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7021 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7022 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7023 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7024 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7025 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7026 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7027 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7028 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7029 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7030 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7031 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7032 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7033 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7034 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7037 static const char long_binary_sid2
[] = {
7038 0x1, /* revision number */
7040 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7041 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7042 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7043 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7044 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7045 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7046 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7047 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7048 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7049 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7050 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7051 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7052 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7053 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7054 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7055 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7056 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7057 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7058 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7059 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7060 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7061 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7062 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7063 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7064 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7065 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7066 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7067 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7068 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7069 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7070 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7071 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7072 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7075 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
7078 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
7081 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
7087 /* Split a path name into filename and stream name components. Canonicalise
7088 * such that an implicit $DATA token is always explicit.
7090 * The "specification" of this function can be found in the
7091 * run_local_stream_name() function in torture.c, I've tried those
7092 * combinations against a W2k3 server.
7095 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
7096 char **pbase
, char **pstream
)
7099 char *stream
= NULL
;
7100 char *sname
; /* stream name */
7101 const char *stype
; /* stream type */
7103 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
7105 sname
= strchr_m(fname
, ':');
7107 if (lp_posix_pathnames() || (sname
== NULL
)) {
7108 if (pbase
!= NULL
) {
7109 base
= talloc_strdup(mem_ctx
, fname
);
7110 NT_STATUS_HAVE_NO_MEMORY(base
);
7115 if (pbase
!= NULL
) {
7116 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
7117 NT_STATUS_HAVE_NO_MEMORY(base
);
7122 stype
= strchr_m(sname
, ':');
7124 if (stype
== NULL
) {
7125 sname
= talloc_strdup(mem_ctx
, sname
);
7129 if (StrCaseCmp(stype
, ":$DATA") != 0) {
7131 * If there is an explicit stream type, so far we only
7132 * allow $DATA. Is there anything else allowed? -- vl
7134 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
7136 return NT_STATUS_OBJECT_NAME_INVALID
;
7138 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
7142 if (sname
== NULL
) {
7144 return NT_STATUS_NO_MEMORY
;
7147 if (sname
[0] == '\0') {
7149 * no stream name, so no stream
7154 if (pstream
!= NULL
) {
7155 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
7156 if (stream
== NULL
) {
7159 return NT_STATUS_NO_MEMORY
;
7162 * upper-case the type field
7164 strupper_m(strchr_m(stream
, ':')+1);
7168 if (pbase
!= NULL
) {
7171 if (pstream
!= NULL
) {
7174 return NT_STATUS_OK
;
7177 static bool test_stream_name(const char *fname
, const char *expected_base
,
7178 const char *expected_stream
,
7179 NTSTATUS expected_status
)
7183 char *stream
= NULL
;
7185 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
7186 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
7190 if (!NT_STATUS_IS_OK(status
)) {
7194 if (base
== NULL
) goto error
;
7196 if (strcmp(expected_base
, base
) != 0) goto error
;
7198 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
7199 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
7201 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
7205 TALLOC_FREE(stream
);
7209 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
7210 fname
, expected_base
? expected_base
: "<NULL>",
7211 expected_stream
? expected_stream
: "<NULL>",
7212 nt_errstr(expected_status
));
7213 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
7214 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
7217 TALLOC_FREE(stream
);
7221 static bool run_local_stream_name(int dummy
)
7225 ret
&= test_stream_name(
7226 "bla", "bla", NULL
, NT_STATUS_OK
);
7227 ret
&= test_stream_name(
7228 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
7229 ret
&= test_stream_name(
7230 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7231 ret
&= test_stream_name(
7232 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7233 ret
&= test_stream_name(
7234 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7235 ret
&= test_stream_name(
7236 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
7237 ret
&= test_stream_name(
7238 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
7239 ret
&= test_stream_name(
7240 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
7245 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
7247 if (a
.length
!= b
.length
) {
7248 printf("a.length=%d != b.length=%d\n",
7249 (int)a
.length
, (int)b
.length
);
7252 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
7253 printf("a.data and b.data differ\n");
7259 static bool run_local_memcache(int dummy
)
7261 struct memcache
*cache
;
7263 DATA_BLOB d1
, d2
, d3
;
7264 DATA_BLOB v1
, v2
, v3
;
7266 TALLOC_CTX
*mem_ctx
;
7268 size_t size1
, size2
;
7271 cache
= memcache_init(NULL
, 100);
7273 if (cache
== NULL
) {
7274 printf("memcache_init failed\n");
7278 d1
= data_blob_const("d1", 2);
7279 d2
= data_blob_const("d2", 2);
7280 d3
= data_blob_const("d3", 2);
7282 k1
= data_blob_const("d1", 2);
7283 k2
= data_blob_const("d2", 2);
7285 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
7286 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
7288 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
7289 printf("could not find k1\n");
7292 if (!data_blob_equal(d1
, v1
)) {
7296 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7297 printf("could not find k2\n");
7300 if (!data_blob_equal(d2
, v2
)) {
7304 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
7306 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
7307 printf("could not find replaced k1\n");
7310 if (!data_blob_equal(d3
, v3
)) {
7314 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
7316 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7317 printf("Did find k2, should have been purged\n");
7323 cache
= memcache_init(NULL
, 0);
7325 mem_ctx
= talloc_init("foo");
7327 str1
= talloc_strdup(mem_ctx
, "string1");
7328 str2
= talloc_strdup(mem_ctx
, "string2");
7330 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7331 data_blob_string_const("torture"), &str1
);
7332 size1
= talloc_total_size(cache
);
7334 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7335 data_blob_string_const("torture"), &str2
);
7336 size2
= talloc_total_size(cache
);
7338 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
7340 if (size2
> size1
) {
7341 printf("memcache leaks memory!\n");
7351 static void wbclient_done(struct tevent_req
*req
)
7354 struct winbindd_response
*wb_resp
;
7355 int *i
= (int *)tevent_req_callback_data_void(req
);
7357 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
7360 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
7363 static bool run_local_wbclient(int dummy
)
7365 struct event_context
*ev
;
7366 struct wb_context
**wb_ctx
;
7367 struct winbindd_request wb_req
;
7368 bool result
= false;
7371 BlockSignals(True
, SIGPIPE
);
7373 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
7378 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
7379 if (wb_ctx
== NULL
) {
7383 ZERO_STRUCT(wb_req
);
7384 wb_req
.cmd
= WINBINDD_PING
;
7386 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
7388 for (i
=0; i
<nprocs
; i
++) {
7389 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
7390 if (wb_ctx
[i
] == NULL
) {
7393 for (j
=0; j
<torture_numops
; j
++) {
7394 struct tevent_req
*req
;
7395 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
7396 (j
% 2) == 0, &wb_req
);
7400 tevent_req_set_callback(req
, wbclient_done
, &i
);
7406 while (i
< nprocs
* torture_numops
) {
7407 event_loop_once(ev
);
7416 static void getaddrinfo_finished(struct tevent_req
*req
)
7418 char *name
= (char *)tevent_req_callback_data_void(req
);
7419 struct addrinfo
*ainfo
;
7422 res
= getaddrinfo_recv(req
, &ainfo
);
7424 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7427 d_printf("gai(%s) succeeded\n", name
);
7428 freeaddrinfo(ainfo
);
7431 static bool run_getaddrinfo_send(int dummy
)
7433 TALLOC_CTX
*frame
= talloc_stackframe();
7434 struct fncall_context
*ctx
;
7435 struct tevent_context
*ev
;
7436 bool result
= false;
7437 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7438 "www.slashdot.org", "heise.de" };
7439 struct tevent_req
*reqs
[4];
7442 ev
= event_context_init(frame
);
7447 ctx
= fncall_context_init(frame
, 4);
7449 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7450 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7452 if (reqs
[i
] == NULL
) {
7455 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7459 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7460 tevent_loop_once(ev
);
7469 static bool dbtrans_inc(struct db_context
*db
)
7471 struct db_record
*rec
;
7476 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7478 printf(__location__
"fetch_lock failed\n");
7482 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
7483 printf(__location__
"value.dsize = %d\n",
7484 (int)rec
->value
.dsize
);
7488 val
= (uint32_t *)rec
->value
.dptr
;
7491 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
7494 if (!NT_STATUS_IS_OK(status
)) {
7495 printf(__location__
"store failed: %s\n",
7506 static bool run_local_dbtrans(int dummy
)
7508 struct db_context
*db
;
7509 struct db_record
*rec
;
7514 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
7515 O_RDWR
|O_CREAT
, 0600);
7517 printf("Could not open transtest.db\n");
7521 res
= db
->transaction_start(db
);
7523 printf(__location__
"transaction_start failed\n");
7527 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7529 printf(__location__
"fetch_lock failed\n");
7533 if (rec
->value
.dptr
== NULL
) {
7535 status
= rec
->store(
7536 rec
, make_tdb_data((uint8_t *)&initial
,
7539 if (!NT_STATUS_IS_OK(status
)) {
7540 printf(__location__
"store returned %s\n",
7548 res
= db
->transaction_commit(db
);
7550 printf(__location__
"transaction_commit failed\n");
7558 res
= db
->transaction_start(db
);
7560 printf(__location__
"transaction_start failed\n");
7564 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
7565 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7569 for (i
=0; i
<10; i
++) {
7570 if (!dbtrans_inc(db
)) {
7575 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
7576 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7580 if (val2
!= val
+ 10) {
7581 printf(__location__
"val=%d, val2=%d\n",
7582 (int)val
, (int)val2
);
7586 printf("val2=%d\r", val2
);
7588 res
= db
->transaction_commit(db
);
7590 printf(__location__
"transaction_commit failed\n");
7600 * Just a dummy test to be run under a debugger. There's no real way
7601 * to inspect the tevent_select specific function from outside of
7605 static bool run_local_tevent_select(int dummy
)
7607 struct tevent_context
*ev
;
7608 struct tevent_fd
*fd1
, *fd2
;
7609 bool result
= false;
7611 ev
= tevent_context_init_byname(NULL
, "select");
7613 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
7617 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
7619 d_fprintf(stderr
, "tevent_add_fd failed\n");
7622 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
7624 d_fprintf(stderr
, "tevent_add_fd failed\n");
7629 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
7631 d_fprintf(stderr
, "tevent_add_fd failed\n");
7641 static double create_procs(bool (*fn
)(int), bool *result
)
7644 volatile pid_t
*child_status
;
7645 volatile bool *child_status_out
;
7648 struct timeval start
;
7652 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
7653 if (!child_status
) {
7654 printf("Failed to setup shared memory\n");
7658 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
7659 if (!child_status_out
) {
7660 printf("Failed to setup result status shared memory\n");
7664 for (i
= 0; i
< nprocs
; i
++) {
7665 child_status
[i
] = 0;
7666 child_status_out
[i
] = True
;
7669 start
= timeval_current();
7671 for (i
=0;i
<nprocs
;i
++) {
7674 pid_t mypid
= getpid();
7675 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
7677 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
7680 if (torture_open_connection(¤t_cli
, i
)) break;
7682 printf("pid %d failed to start\n", (int)getpid());
7688 child_status
[i
] = getpid();
7690 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
7692 child_status_out
[i
] = fn(i
);
7699 for (i
=0;i
<nprocs
;i
++) {
7700 if (child_status
[i
]) synccount
++;
7702 if (synccount
== nprocs
) break;
7704 } while (timeval_elapsed(&start
) < 30);
7706 if (synccount
!= nprocs
) {
7707 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
7709 return timeval_elapsed(&start
);
7712 /* start the client load */
7713 start
= timeval_current();
7715 for (i
=0;i
<nprocs
;i
++) {
7716 child_status
[i
] = 0;
7719 printf("%d clients started\n", nprocs
);
7721 for (i
=0;i
<nprocs
;i
++) {
7722 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
7727 for (i
=0;i
<nprocs
;i
++) {
7728 if (!child_status_out
[i
]) {
7732 return timeval_elapsed(&start
);
7735 #define FLAG_MULTIPROC 1
7742 {"FDPASS", run_fdpasstest
, 0},
7743 {"LOCK1", run_locktest1
, 0},
7744 {"LOCK2", run_locktest2
, 0},
7745 {"LOCK3", run_locktest3
, 0},
7746 {"LOCK4", run_locktest4
, 0},
7747 {"LOCK5", run_locktest5
, 0},
7748 {"LOCK6", run_locktest6
, 0},
7749 {"LOCK7", run_locktest7
, 0},
7750 {"LOCK8", run_locktest8
, 0},
7751 {"LOCK9", run_locktest9
, 0},
7752 {"UNLINK", run_unlinktest
, 0},
7753 {"BROWSE", run_browsetest
, 0},
7754 {"ATTR", run_attrtest
, 0},
7755 {"TRANS2", run_trans2test
, 0},
7756 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
7757 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
7758 {"RANDOMIPC", run_randomipc
, 0},
7759 {"NEGNOWAIT", run_negprot_nowait
, 0},
7760 {"NBENCH", run_nbench
, 0},
7761 {"NBENCH2", run_nbench2
, 0},
7762 {"OPLOCK1", run_oplock1
, 0},
7763 {"OPLOCK2", run_oplock2
, 0},
7764 {"OPLOCK3", run_oplock3
, 0},
7765 {"DIR", run_dirtest
, 0},
7766 {"DIR1", run_dirtest1
, 0},
7767 {"DIR-CREATETIME", run_dir_createtime
, 0},
7768 {"DENY1", torture_denytest1
, 0},
7769 {"DENY2", torture_denytest2
, 0},
7770 {"TCON", run_tcon_test
, 0},
7771 {"TCONDEV", run_tcon_devtype_test
, 0},
7772 {"RW1", run_readwritetest
, 0},
7773 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
7774 {"RW3", run_readwritelarge
, 0},
7775 {"OPEN", run_opentest
, 0},
7776 {"POSIX", run_simple_posix_open_test
, 0},
7777 {"POSIX-APPEND", run_posix_append
, 0},
7778 {"ASYNC-ECHO", run_async_echo
, 0},
7779 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
7780 { "SHORTNAME-TEST", run_shortname_test
, 0},
7782 {"OPENATTR", run_openattrtest
, 0},
7784 {"XCOPY", run_xcopy
, 0},
7785 {"RENAME", run_rename
, 0},
7786 {"DELETE", run_deletetest
, 0},
7787 {"PROPERTIES", run_properties
, 0},
7788 {"MANGLE", torture_mangle
, 0},
7789 {"MANGLE1", run_mangle1
, 0},
7790 {"W2K", run_w2ktest
, 0},
7791 {"TRANS2SCAN", torture_trans2_scan
, 0},
7792 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
7793 {"UTABLE", torture_utable
, 0},
7794 {"CASETABLE", torture_casetable
, 0},
7795 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
7796 {"PIPE_NUMBER", run_pipe_number
, 0},
7797 {"TCON2", run_tcon2_test
, 0},
7798 {"IOCTL", torture_ioctl_test
, 0},
7799 {"CHKPATH", torture_chkpath_test
, 0},
7800 {"FDSESS", run_fdsesstest
, 0},
7801 { "EATEST", run_eatest
, 0},
7802 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
7803 { "CHAIN1", run_chain1
, 0},
7804 { "CHAIN2", run_chain2
, 0},
7805 { "WINDOWS-WRITE", run_windows_write
, 0},
7806 { "CLI_ECHO", run_cli_echo
, 0},
7807 { "GETADDRINFO", run_getaddrinfo_send
, 0},
7808 { "TLDAP", run_tldap
},
7809 { "STREAMERROR", run_streamerror
},
7810 { "NOTIFY-BENCH", run_notify_bench
},
7811 { "BAD-NBT-SESSION", run_bad_nbt_session
},
7812 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
7813 { "LOCAL-GENCACHE", run_local_gencache
, 0},
7814 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
7815 { "LOCAL-BASE64", run_local_base64
, 0},
7816 { "LOCAL-RBTREE", run_local_rbtree
, 0},
7817 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
7818 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
7819 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
7820 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
7821 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
7822 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
7823 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
7828 /****************************************************************************
7829 run a specified test or "ALL"
7830 ****************************************************************************/
7831 static bool run_test(const char *name
)
7838 if (strequal(name
,"ALL")) {
7839 for (i
=0;torture_ops
[i
].name
;i
++) {
7840 run_test(torture_ops
[i
].name
);
7845 for (i
=0;torture_ops
[i
].name
;i
++) {
7846 fstr_sprintf(randomfname
, "\\XX%x",
7847 (unsigned)random());
7849 if (strequal(name
, torture_ops
[i
].name
)) {
7851 printf("Running %s\n", name
);
7852 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
7853 t
= create_procs(torture_ops
[i
].fn
, &result
);
7856 printf("TEST %s FAILED!\n", name
);
7859 struct timeval start
;
7860 start
= timeval_current();
7861 if (!torture_ops
[i
].fn(0)) {
7863 printf("TEST %s FAILED!\n", name
);
7865 t
= timeval_elapsed(&start
);
7867 printf("%s took %g secs\n\n", name
, t
);
7872 printf("Did not find a test named %s\n", name
);
7880 static void usage(void)
7884 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7885 printf("Please use samba4 torture.\n\n");
7887 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7889 printf("\t-d debuglevel\n");
7890 printf("\t-U user%%pass\n");
7891 printf("\t-k use kerberos\n");
7892 printf("\t-N numprocs\n");
7893 printf("\t-n my_netbios_name\n");
7894 printf("\t-W workgroup\n");
7895 printf("\t-o num_operations\n");
7896 printf("\t-O socket_options\n");
7897 printf("\t-m maximum protocol\n");
7898 printf("\t-L use oplocks\n");
7899 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7900 printf("\t-A showall\n");
7901 printf("\t-p port\n");
7902 printf("\t-s seed\n");
7903 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7906 printf("tests are:");
7907 for (i
=0;torture_ops
[i
].name
;i
++) {
7908 printf(" %s", torture_ops
[i
].name
);
7912 printf("default test is ALL\n");
7917 /****************************************************************************
7919 ****************************************************************************/
7920 int main(int argc
,char *argv
[])
7926 bool correct
= True
;
7927 TALLOC_CTX
*frame
= talloc_stackframe();
7928 int seed
= time(NULL
);
7932 #ifdef HAVE_SETBUFFER
7933 setbuffer(stdout
, NULL
, 0);
7938 setup_logging("smbtorture", true);
7940 if (is_default_dyn_CONFIGFILE()) {
7941 if(getenv("SMB_CONF_PATH")) {
7942 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7945 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
7952 for(p
= argv
[1]; *p
; p
++)
7956 if (strncmp(argv
[1], "//", 2)) {
7960 fstrcpy(host
, &argv
[1][2]);
7961 p
= strchr_m(&host
[2],'/');
7966 fstrcpy(share
, p
+1);
7968 fstrcpy(myname
, get_myname(talloc_tos()));
7970 fprintf(stderr
, "Failed to get my hostname.\n");
7974 if (*username
== 0 && getenv("LOGNAME")) {
7975 fstrcpy(username
,getenv("LOGNAME"));
7981 fstrcpy(workgroup
, lp_workgroup());
7983 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
7986 port_to_use
= atoi(optarg
);
7989 seed
= atoi(optarg
);
7992 fstrcpy(workgroup
,optarg
);
7995 max_protocol
= interpret_protocol(optarg
, max_protocol
);
7998 nprocs
= atoi(optarg
);
8001 torture_numops
= atoi(optarg
);
8004 DEBUGLEVEL
= atoi(optarg
);
8013 local_path
= optarg
;
8016 torture_showall
= True
;
8019 fstrcpy(myname
, optarg
);
8022 client_txt
= optarg
;
8029 use_kerberos
= True
;
8031 d_printf("No kerberos support compiled in\n");
8037 fstrcpy(username
,optarg
);
8038 p
= strchr_m(username
,'%');
8041 fstrcpy(password
, p
+1);
8046 fstrcpy(multishare_conn_fname
, optarg
);
8047 use_multishare_conn
= True
;
8050 torture_blocksize
= atoi(optarg
);
8053 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
8058 d_printf("using seed %d\n", seed
);
8062 if(use_kerberos
&& !gotuser
) gotpass
= True
;
8065 p
= getpass("Password:");
8067 fstrcpy(password
, p
);
8072 printf("host=%s share=%s user=%s myname=%s\n",
8073 host
, share
, username
, myname
);
8075 if (argc
== optind
) {
8076 correct
= run_test("ALL");
8078 for (i
=optind
;i
<argc
;i
++) {
8079 if (!run_test(argv
[i
])) {