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 "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
;
55 static int signing_state
= Undefined
;
57 bool torture_showall
= False
;
59 static double create_procs(bool (*fn
)(int), bool *result
);
62 /* return a pointer to a anonymous shared memory segment of size "size"
63 which will persist across fork() but will disappear when all processes
66 The memory is not zeroed
68 This function uses system5 shared memory. It takes advantage of a property
69 that the memory is not destroyed if it is attached when the id is removed
71 void *shm_setup(int size
)
77 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
79 printf("can't get shared memory\n");
82 shm_unlink("private");
83 if (ftruncate(shmid
, size
) == -1) {
84 printf("can't set shared memory size\n");
87 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
88 if (ret
== MAP_FAILED
) {
89 printf("can't map shared memory\n");
93 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
95 printf("can't get shared memory\n");
98 ret
= (void *)shmat(shmid
, 0, 0);
99 if (!ret
|| ret
== (void *)-1) {
100 printf("can't attach to shared memory\n");
103 /* the following releases the ipc, but note that this process
104 and all its children will still have access to the memory, its
105 just that the shmid is no longer valid for other shm calls. This
106 means we don't leave behind lots of shm segments after we exit
108 See Stevens "advanced programming in unix env" for details
110 shmctl(shmid
, IPC_RMID
, 0);
116 /********************************************************************
117 Ensure a connection is encrypted.
118 ********************************************************************/
120 static bool force_cli_encryption(struct cli_state
*c
,
121 const char *sharename
)
124 uint32 caplow
, caphigh
;
127 if (!SERVER_HAS_UNIX_CIFS(c
)) {
128 d_printf("Encryption required and "
129 "server that doesn't support "
130 "UNIX extensions - failing connect\n");
134 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
136 if (!NT_STATUS_IS_OK(status
)) {
137 d_printf("Encryption required and "
138 "can't get UNIX CIFS extensions "
139 "version from server: %s\n", nt_errstr(status
));
143 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
144 d_printf("Encryption required and "
145 "share %s doesn't support "
146 "encryption.\n", sharename
);
150 if (c
->use_kerberos
) {
151 status
= cli_gss_smb_encryption_start(c
);
153 status
= cli_raw_ntlm_smb_encryption_start(c
,
159 if (!NT_STATUS_IS_OK(status
)) {
160 d_printf("Encryption required and "
161 "setup failed with error %s.\n",
170 static struct cli_state
*open_nbt_connection(void)
172 struct nmb_name called
, calling
;
173 struct sockaddr_storage ss
;
177 make_nmb_name(&calling
, myname
, 0x0);
178 make_nmb_name(&called
, host
, 0x20);
182 if (!(c
= cli_initialise_ex(signing_state
))) {
183 printf("Failed initialize cli_struct to connect with %s\n", host
);
187 c
->port
= port_to_use
;
189 status
= cli_connect(c
, host
, &ss
);
190 if (!NT_STATUS_IS_OK(status
)) {
191 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
195 c
->use_kerberos
= use_kerberos
;
197 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
198 if (use_oplocks
) c
->use_oplocks
= True
;
199 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
201 if (!cli_session_request(c
, &calling
, &called
)) {
203 * Well, that failed, try *SMBSERVER ...
204 * However, we must reconnect as well ...
206 status
= cli_connect(c
, host
, &ss
);
207 if (!NT_STATUS_IS_OK(status
)) {
208 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
212 make_nmb_name(&called
, "*SMBSERVER", 0x20);
213 if (!cli_session_request(c
, &calling
, &called
)) {
214 printf("%s rejected the session\n",host
);
215 printf("We tried with a called name of %s & %s\n",
225 /****************************************************************************
226 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
227 ****************************************************************************/
229 static bool cli_bad_session_request(struct cli_state
*cli
,
230 struct nmb_name
*calling
, struct nmb_name
*called
)
237 memcpy(&(cli
->calling
), calling
, sizeof(*calling
));
238 memcpy(&(cli
->called
), called
, sizeof(*called
));
240 /* put in the destination name */
242 tmp
= name_mangle(talloc_tos(), cli
->called
.name
,
243 cli
->called
.name_type
);
249 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
251 memcpy(p
, tmp
, namelen
);
256 /* Deliberately corrupt the name len (first byte) */
261 tmp
= name_mangle(talloc_tos(), cli
->calling
.name
,
262 cli
->calling
.name_type
);
268 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
270 memcpy(p
, tmp
, namelen
);
274 /* Deliberately corrupt the name len (first byte) */
277 /* send a session request (RFC 1002) */
278 /* setup the packet length
279 * Remove four bytes from the length count, since the length
280 * field in the NBT Session Service header counts the number
281 * of bytes which follow. The cli_send_smb() function knows
282 * about this and accounts for those four bytes.
286 _smb_setlen(cli
->outbuf
,len
);
287 SCVAL(cli
->outbuf
,0,0x81);
290 DEBUG(5,("Sent session request\n"));
292 if (!cli_receive_smb(cli
))
295 if (CVAL(cli
->inbuf
,0) != 0x82) {
296 /* This is the wrong place to put the error... JRA. */
297 cli
->rap_error
= CVAL(cli
->inbuf
,4);
303 static struct cli_state
*open_bad_nbt_connection(void)
305 struct nmb_name called
, calling
;
306 struct sockaddr_storage ss
;
310 make_nmb_name(&calling
, myname
, 0x0);
311 make_nmb_name(&called
, host
, 0x20);
315 if (!(c
= cli_initialise_ex(signing_state
))) {
316 printf("Failed initialize cli_struct to connect with %s\n", host
);
322 status
= cli_connect(c
, host
, &ss
);
323 if (!NT_STATUS_IS_OK(status
)) {
324 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
328 c
->timeout
= 4000; /* set a short timeout (4 seconds) */
330 if (!cli_bad_session_request(c
, &calling
, &called
)) {
331 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
339 /* Insert a NULL at the first separator of the given path and return a pointer
340 * to the remainder of the string.
343 terminate_path_at_separator(char * path
)
351 if ((p
= strchr_m(path
, '/'))) {
356 if ((p
= strchr_m(path
, '\\'))) {
366 parse a //server/share type UNC name
368 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
369 char **hostname
, char **sharename
)
373 *hostname
= *sharename
= NULL
;
375 if (strncmp(unc_name
, "\\\\", 2) &&
376 strncmp(unc_name
, "//", 2)) {
380 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
381 p
= terminate_path_at_separator(*hostname
);
384 *sharename
= talloc_strdup(mem_ctx
, p
);
385 terminate_path_at_separator(*sharename
);
388 if (*hostname
&& *sharename
) {
392 TALLOC_FREE(*hostname
);
393 TALLOC_FREE(*sharename
);
397 static bool torture_open_connection_share(struct cli_state
**c
,
398 const char *hostname
,
399 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
, signing_state
);
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;
670 NTSTATUS status
= NT_STATUS_OK
;
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_internal(int max_xmit_k
)
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
= max_xmit_k
*1024;
907 if (signing_state
== Required
) {
908 /* Horrible cheat to force
909 multiple signed outstanding
910 packets against a Samba server.
912 cli1
->is_samba
= false;
915 printf("starting readwritelarge_internal\n");
917 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
919 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
920 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
924 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
926 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
927 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
928 NULL
, NULL
, NULL
))) {
929 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
933 if (fsize
== sizeof(buf
))
934 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
935 (unsigned long)fsize
);
937 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
938 (unsigned long)fsize
);
942 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
943 printf("close failed (%s)\n", cli_errstr(cli1
));
947 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
948 printf("unlink failed (%s)\n", cli_errstr(cli1
));
952 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
953 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
957 cli1
->max_xmit
= 4*1024;
959 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
));
961 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
962 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
963 NULL
, NULL
, NULL
))) {
964 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
968 if (fsize
== sizeof(buf
))
969 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
970 (unsigned long)fsize
);
972 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
973 (unsigned long)fsize
);
978 /* ToDo - set allocation. JRA */
979 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
980 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
983 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
985 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
989 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
992 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
993 printf("close failed (%s)\n", cli_errstr(cli1
));
997 if (!torture_close_connection(cli1
)) {
1003 static bool run_readwritelarge(int dummy
)
1005 return run_readwritelarge_internal(128);
1008 static bool run_readwritelarge_signtest(int dummy
)
1011 signing_state
= Required
;
1012 ret
= run_readwritelarge_internal(2);
1013 signing_state
= Undefined
;
1020 #define ival(s) strtol(s, NULL, 0)
1022 /* run a test that simulates an approximate netbench client load */
1023 static bool run_netbench(int client
)
1025 struct cli_state
*cli
;
1030 const char *params
[20];
1031 bool correct
= True
;
1037 cli_sockopt(cli
, sockops
);
1041 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1043 f
= fopen(client_txt
, "r");
1050 while (fgets(line
, sizeof(line
)-1, f
)) {
1054 line
[strlen(line
)-1] = 0;
1056 /* printf("[%d] %s\n", line_count, line); */
1058 all_string_sub(line
,"client1", cname
, sizeof(line
));
1060 /* parse the command parameters */
1061 params
[0] = strtok_r(line
, " ", &saveptr
);
1063 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1067 if (i
< 2) continue;
1069 if (!strncmp(params
[0],"SMB", 3)) {
1070 printf("ERROR: You are using a dbench 1 load file\n");
1074 if (!strcmp(params
[0],"NTCreateX")) {
1075 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1077 } else if (!strcmp(params
[0],"Close")) {
1078 nb_close(ival(params
[1]));
1079 } else if (!strcmp(params
[0],"Rename")) {
1080 nb_rename(params
[1], params
[2]);
1081 } else if (!strcmp(params
[0],"Unlink")) {
1082 nb_unlink(params
[1]);
1083 } else if (!strcmp(params
[0],"Deltree")) {
1084 nb_deltree(params
[1]);
1085 } else if (!strcmp(params
[0],"Rmdir")) {
1086 nb_rmdir(params
[1]);
1087 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1088 nb_qpathinfo(params
[1]);
1089 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1090 nb_qfileinfo(ival(params
[1]));
1091 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1092 nb_qfsinfo(ival(params
[1]));
1093 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1094 nb_findfirst(params
[1]);
1095 } else if (!strcmp(params
[0],"WriteX")) {
1096 nb_writex(ival(params
[1]),
1097 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1098 } else if (!strcmp(params
[0],"ReadX")) {
1099 nb_readx(ival(params
[1]),
1100 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1101 } else if (!strcmp(params
[0],"Flush")) {
1102 nb_flush(ival(params
[1]));
1104 printf("Unknown operation %s\n", params
[0]);
1112 if (!torture_close_connection(cli
)) {
1120 /* run a test that simulates an approximate netbench client load */
1121 static bool run_nbench(int dummy
)
1124 bool correct
= True
;
1130 signal(SIGALRM
, nb_alarm
);
1132 t
= create_procs(run_netbench
, &correct
);
1135 printf("\nThroughput %g MB/sec\n",
1136 1.0e-6 * nbio_total() / t
);
1142 This test checks for two things:
1144 1) correct support for retaining locks over a close (ie. the server
1145 must not use posix semantics)
1146 2) support for lock timeouts
1148 static bool run_locktest1(int dummy
)
1150 struct cli_state
*cli1
, *cli2
;
1151 const char *fname
= "\\lockt1.lck";
1152 uint16_t fnum1
, fnum2
, fnum3
;
1154 unsigned lock_timeout
;
1156 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1159 cli_sockopt(cli1
, sockops
);
1160 cli_sockopt(cli2
, sockops
);
1162 printf("starting locktest1\n");
1164 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1166 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1167 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1170 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1171 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1174 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1175 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1179 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1180 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1185 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1186 printf("lock2 succeeded! This is a locking bug\n");
1189 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1190 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1194 lock_timeout
= (1 + (random() % 20));
1195 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1197 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1198 printf("lock3 succeeded! This is a locking bug\n");
1201 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1202 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1206 if (ABS(t2
- t1
) < lock_timeout
-1) {
1207 printf("error: This server appears not to support timed lock requests\n");
1210 printf("server slept for %u seconds for a %u second timeout\n",
1211 (unsigned int)(t2
-t1
), lock_timeout
);
1213 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1214 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1218 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1219 printf("lock4 succeeded! This is a locking bug\n");
1222 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1223 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1226 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1227 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1231 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1232 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1236 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1237 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1242 if (!torture_close_connection(cli1
)) {
1246 if (!torture_close_connection(cli2
)) {
1250 printf("Passed locktest1\n");
1255 this checks to see if a secondary tconx can use open files from an
1258 static bool run_tcon_test(int dummy
)
1260 static struct cli_state
*cli
;
1261 const char *fname
= "\\tcontest.tmp";
1263 uint16 cnum1
, cnum2
, cnum3
;
1264 uint16 vuid1
, vuid2
;
1269 memset(buf
, '\0', sizeof(buf
));
1271 if (!torture_open_connection(&cli
, 0)) {
1274 cli_sockopt(cli
, sockops
);
1276 printf("starting tcontest\n");
1278 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1280 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1281 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1288 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1289 printf("initial write failed (%s)", cli_errstr(cli
));
1293 status
= cli_tcon_andx(cli
, share
, "?????",
1294 password
, strlen(password
)+1);
1295 if (!NT_STATUS_IS_OK(status
)) {
1296 printf("%s refused 2nd tree connect (%s)\n", host
,
1303 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1304 vuid2
= cli
->vuid
+ 1;
1306 /* try a write with the wrong tid */
1309 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1310 printf("* server allows write with wrong TID\n");
1313 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1317 /* try a write with an invalid tid */
1320 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1321 printf("* server allows write with invalid TID\n");
1324 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1327 /* try a write with an invalid vuid */
1331 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1332 printf("* server allows write with invalid VUID\n");
1335 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1341 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1342 printf("close failed (%s)\n", cli_errstr(cli
));
1348 status
= cli_tdis(cli
);
1349 if (!NT_STATUS_IS_OK(status
)) {
1350 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1356 if (!torture_close_connection(cli
)) {
1365 checks for old style tcon support
1367 static bool run_tcon2_test(int dummy
)
1369 static struct cli_state
*cli
;
1370 uint16 cnum
, max_xmit
;
1374 if (!torture_open_connection(&cli
, 0)) {
1377 cli_sockopt(cli
, sockops
);
1379 printf("starting tcon2 test\n");
1381 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1385 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1387 if (!NT_STATUS_IS_OK(status
)) {
1388 printf("tcon2 failed : %s\n", cli_errstr(cli
));
1390 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1391 (int)max_xmit
, (int)cnum
, SVAL(cli
->inbuf
, smb_tid
));
1394 if (!torture_close_connection(cli
)) {
1398 printf("Passed tcon2 test\n");
1402 static bool tcon_devtest(struct cli_state
*cli
,
1403 const char *myshare
, const char *devtype
,
1404 const char *return_devtype
,
1405 NTSTATUS expected_error
)
1410 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1411 password
, strlen(password
)+1);
1413 if (NT_STATUS_IS_OK(expected_error
)) {
1414 if (NT_STATUS_IS_OK(status
)) {
1415 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1418 printf("tconX to share %s with type %s "
1419 "succeeded but returned the wrong "
1420 "device type (got [%s] but should have got [%s])\n",
1421 myshare
, devtype
, cli
->dev
, return_devtype
);
1425 printf("tconX to share %s with type %s "
1426 "should have succeeded but failed\n",
1432 if (NT_STATUS_IS_OK(status
)) {
1433 printf("tconx to share %s with type %s "
1434 "should have failed but succeeded\n",
1438 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1442 printf("Returned unexpected error\n");
1451 checks for correct tconX support
1453 static bool run_tcon_devtype_test(int dummy
)
1455 static struct cli_state
*cli1
= NULL
;
1460 status
= cli_full_connection(&cli1
, myname
,
1461 host
, NULL
, port_to_use
,
1463 username
, workgroup
,
1464 password
, flags
, signing_state
);
1466 if (!NT_STATUS_IS_OK(status
)) {
1467 printf("could not open connection\n");
1471 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1474 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1477 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1480 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1483 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1486 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1489 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1492 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1495 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1498 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1504 printf("Passed tcondevtest\n");
1511 This test checks that
1513 1) the server supports multiple locking contexts on the one SMB
1514 connection, distinguished by PID.
1516 2) the server correctly fails overlapping locks made by the same PID (this
1517 goes against POSIX behaviour, which is why it is tricky to implement)
1519 3) the server denies unlock requests by an incorrect client PID
1521 static bool run_locktest2(int dummy
)
1523 static struct cli_state
*cli
;
1524 const char *fname
= "\\lockt2.lck";
1525 uint16_t fnum1
, fnum2
, fnum3
;
1526 bool correct
= True
;
1528 if (!torture_open_connection(&cli
, 0)) {
1532 cli_sockopt(cli
, sockops
);
1534 printf("starting locktest2\n");
1536 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1540 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1541 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1545 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1546 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1552 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1553 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1559 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1560 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1564 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1565 printf("WRITE lock1 succeeded! This is a locking bug\n");
1568 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1569 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1572 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1573 printf("WRITE lock2 succeeded! This is a locking bug\n");
1576 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1577 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1580 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1581 printf("READ lock2 succeeded! This is a locking bug\n");
1584 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1585 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1588 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1589 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1592 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1593 printf("unlock at 100 succeeded! This is a locking bug\n");
1597 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1598 printf("unlock1 succeeded! This is a locking bug\n");
1601 if (!check_error(__LINE__
, cli
,
1603 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1606 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1607 printf("unlock2 succeeded! This is a locking bug\n");
1610 if (!check_error(__LINE__
, cli
,
1612 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1615 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1616 printf("lock3 succeeded! This is a locking bug\n");
1619 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1624 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1625 printf("close1 failed (%s)\n", cli_errstr(cli
));
1629 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1630 printf("close2 failed (%s)\n", cli_errstr(cli
));
1634 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1635 printf("close3 failed (%s)\n", cli_errstr(cli
));
1639 if (!torture_close_connection(cli
)) {
1643 printf("locktest2 finished\n");
1650 This test checks that
1652 1) the server supports the full offset range in lock requests
1654 static bool run_locktest3(int dummy
)
1656 static struct cli_state
*cli1
, *cli2
;
1657 const char *fname
= "\\lockt3.lck";
1658 uint16_t fnum1
, fnum2
;
1661 bool correct
= True
;
1663 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1665 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1668 cli_sockopt(cli1
, sockops
);
1669 cli_sockopt(cli2
, sockops
);
1671 printf("starting locktest3\n");
1673 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1675 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1676 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1679 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1680 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1684 for (offset
=i
=0;i
<torture_numops
;i
++) {
1686 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1687 printf("lock1 %d failed (%s)\n",
1693 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1694 printf("lock2 %d failed (%s)\n",
1701 for (offset
=i
=0;i
<torture_numops
;i
++) {
1704 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1705 printf("error: lock1 %d succeeded!\n", i
);
1709 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1710 printf("error: lock2 %d succeeded!\n", i
);
1714 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1715 printf("error: lock3 %d succeeded!\n", i
);
1719 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1720 printf("error: lock4 %d succeeded!\n", i
);
1725 for (offset
=i
=0;i
<torture_numops
;i
++) {
1728 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1729 printf("unlock1 %d failed (%s)\n",
1735 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1736 printf("unlock2 %d failed (%s)\n",
1743 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1744 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1748 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1749 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1753 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1754 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1758 if (!torture_close_connection(cli1
)) {
1762 if (!torture_close_connection(cli2
)) {
1766 printf("finished locktest3\n");
1771 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1772 printf("** "); correct = False; \
1776 looks at overlapping locks
1778 static bool run_locktest4(int dummy
)
1780 static struct cli_state
*cli1
, *cli2
;
1781 const char *fname
= "\\lockt4.lck";
1782 uint16_t fnum1
, fnum2
, f
;
1785 bool correct
= True
;
1787 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1791 cli_sockopt(cli1
, sockops
);
1792 cli_sockopt(cli2
, sockops
);
1794 printf("starting locktest4\n");
1796 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1798 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1799 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1801 memset(buf
, 0, sizeof(buf
));
1803 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1804 printf("Failed to create file\n");
1809 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1810 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1811 EXPECTED(ret
, False
);
1812 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1814 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1815 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1816 EXPECTED(ret
, True
);
1817 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1819 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1820 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1821 EXPECTED(ret
, False
);
1822 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1824 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1825 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1826 EXPECTED(ret
, True
);
1827 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1829 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1830 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1831 EXPECTED(ret
, False
);
1832 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1834 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1835 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1836 EXPECTED(ret
, True
);
1837 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1839 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1840 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1841 EXPECTED(ret
, True
);
1842 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1844 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1845 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1846 EXPECTED(ret
, False
);
1847 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1849 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1850 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1851 EXPECTED(ret
, False
);
1852 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1854 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1855 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1856 EXPECTED(ret
, True
);
1857 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1859 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1860 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1861 EXPECTED(ret
, False
);
1862 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1864 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1865 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1866 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1867 EXPECTED(ret
, False
);
1868 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1871 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1872 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1873 EXPECTED(ret
, False
);
1874 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1876 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1877 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1878 EXPECTED(ret
, False
);
1879 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1882 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1883 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1884 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1885 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1886 EXPECTED(ret
, True
);
1887 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1890 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1891 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1892 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1893 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1894 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1896 EXPECTED(ret
, True
);
1897 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1899 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1901 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1902 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1903 EXPECTED(ret
, True
);
1904 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1906 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1907 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1908 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1909 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1910 EXPECTED(ret
, True
);
1911 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1913 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1914 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1915 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1916 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1917 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1918 EXPECTED(ret
, True
);
1919 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1921 cli_close(cli1
, fnum1
);
1922 cli_close(cli2
, fnum2
);
1923 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1924 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1925 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1926 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1927 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1928 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1929 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1931 cli_close(cli1
, fnum1
);
1932 EXPECTED(ret
, True
);
1933 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1936 cli_close(cli1
, fnum1
);
1937 cli_close(cli2
, fnum2
);
1938 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1939 torture_close_connection(cli1
);
1940 torture_close_connection(cli2
);
1942 printf("finished locktest4\n");
1947 looks at lock upgrade/downgrade.
1949 static bool run_locktest5(int dummy
)
1951 static struct cli_state
*cli1
, *cli2
;
1952 const char *fname
= "\\lockt5.lck";
1953 uint16_t fnum1
, fnum2
, fnum3
;
1956 bool correct
= True
;
1958 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1962 cli_sockopt(cli1
, sockops
);
1963 cli_sockopt(cli2
, sockops
);
1965 printf("starting locktest5\n");
1967 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1969 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1970 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1971 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1973 memset(buf
, 0, sizeof(buf
));
1975 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1976 printf("Failed to create file\n");
1981 /* Check for NT bug... */
1982 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1983 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1984 cli_close(cli1
, fnum1
);
1985 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1986 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1987 EXPECTED(ret
, True
);
1988 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1989 cli_close(cli1
, fnum1
);
1990 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1991 cli_unlock(cli1
, fnum3
, 0, 1);
1993 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1994 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1995 EXPECTED(ret
, True
);
1996 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1998 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1999 EXPECTED(ret
, False
);
2001 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2003 /* Unlock the process 2 lock. */
2004 cli_unlock(cli2
, fnum2
, 0, 4);
2006 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2007 EXPECTED(ret
, False
);
2009 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2011 /* Unlock the process 1 fnum3 lock. */
2012 cli_unlock(cli1
, fnum3
, 0, 4);
2014 /* Stack 2 more locks here. */
2015 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
2016 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
2018 EXPECTED(ret
, True
);
2019 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2021 /* Unlock the first process lock, then check this was the WRITE lock that was
2024 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2025 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2027 EXPECTED(ret
, True
);
2028 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2030 /* Unlock the process 2 lock. */
2031 cli_unlock(cli2
, fnum2
, 0, 4);
2033 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2035 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2036 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2039 EXPECTED(ret
, True
);
2040 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2042 /* Ensure the next unlock fails. */
2043 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2044 EXPECTED(ret
, False
);
2045 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2047 /* Ensure connection 2 can get a write lock. */
2048 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2049 EXPECTED(ret
, True
);
2051 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2055 cli_close(cli1
, fnum1
);
2056 cli_close(cli2
, fnum2
);
2057 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2058 if (!torture_close_connection(cli1
)) {
2061 if (!torture_close_connection(cli2
)) {
2065 printf("finished locktest5\n");
2071 tries the unusual lockingX locktype bits
2073 static bool run_locktest6(int dummy
)
2075 static struct cli_state
*cli
;
2076 const char *fname
[1] = { "\\lock6.txt" };
2081 if (!torture_open_connection(&cli
, 0)) {
2085 cli_sockopt(cli
, sockops
);
2087 printf("starting locktest6\n");
2090 printf("Testing %s\n", fname
[i
]);
2092 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2094 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2095 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2096 cli_close(cli
, fnum
);
2097 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2099 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2100 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2101 cli_close(cli
, fnum
);
2102 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2104 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2107 torture_close_connection(cli
);
2109 printf("finished locktest6\n");
2113 static bool run_locktest7(int dummy
)
2115 struct cli_state
*cli1
;
2116 const char *fname
= "\\lockt7.lck";
2119 bool correct
= False
;
2121 if (!torture_open_connection(&cli1
, 0)) {
2125 cli_sockopt(cli1
, sockops
);
2127 printf("starting locktest7\n");
2129 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2131 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2133 memset(buf
, 0, sizeof(buf
));
2135 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
2136 printf("Failed to create file\n");
2140 cli_setpid(cli1
, 1);
2142 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
2143 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2146 printf("pid1 successfully locked range 130:4 for READ\n");
2149 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2150 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2153 printf("pid1 successfully read the range 130:4\n");
2156 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2157 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2158 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2159 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2163 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2167 cli_setpid(cli1
, 2);
2169 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2170 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2172 printf("pid2 successfully read the range 130:4\n");
2175 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2176 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2177 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2178 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2182 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2186 cli_setpid(cli1
, 1);
2187 cli_unlock(cli1
, fnum1
, 130, 4);
2189 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2190 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2193 printf("pid1 successfully locked range 130:4 for WRITE\n");
2196 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2197 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2200 printf("pid1 successfully read the range 130:4\n");
2203 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2204 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2207 printf("pid1 successfully wrote to the range 130:4\n");
2210 cli_setpid(cli1
, 2);
2212 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2213 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2214 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2215 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2219 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2223 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2224 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2225 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2226 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2230 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2234 cli_unlock(cli1
, fnum1
, 130, 0);
2238 cli_close(cli1
, fnum1
);
2239 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2240 torture_close_connection(cli1
);
2242 printf("finished locktest7\n");
2247 * This demonstrates a problem with our use of GPFS share modes: A file
2248 * descriptor sitting in the pending close queue holding a GPFS share mode
2249 * blocks opening a file another time. Happens with Word 2007 temp files.
2250 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2251 * open is denied with NT_STATUS_SHARING_VIOLATION.
2254 static bool run_locktest8(int dummy
)
2256 struct cli_state
*cli1
;
2257 const char *fname
= "\\lockt8.lck";
2258 uint16_t fnum1
, fnum2
;
2260 bool correct
= False
;
2263 if (!torture_open_connection(&cli1
, 0)) {
2267 cli_sockopt(cli1
, sockops
);
2269 printf("starting locktest8\n");
2271 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2273 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2275 if (!NT_STATUS_IS_OK(status
)) {
2276 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2280 memset(buf
, 0, sizeof(buf
));
2282 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2283 if (!NT_STATUS_IS_OK(status
)) {
2284 d_fprintf(stderr
, "cli_open second time returned %s\n",
2289 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2290 printf("Unable to apply read lock on range 1:1, error was "
2291 "%s\n", cli_errstr(cli1
));
2295 status
= cli_close(cli1
, fnum1
);
2296 if (!NT_STATUS_IS_OK(status
)) {
2297 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2301 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2302 if (!NT_STATUS_IS_OK(status
)) {
2303 d_fprintf(stderr
, "cli_open third time returned %s\n",
2311 cli_close(cli1
, fnum1
);
2312 cli_close(cli1
, fnum2
);
2313 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2314 torture_close_connection(cli1
);
2316 printf("finished locktest8\n");
2321 * This test is designed to be run in conjunction with
2322 * external NFS or POSIX locks taken in the filesystem.
2323 * It checks that the smbd server will block until the
2324 * lock is released and then acquire it. JRA.
2327 static bool got_alarm
;
2328 static int alarm_fd
;
2330 static void alarm_handler(int dummy
)
2335 static void alarm_handler_parent(int dummy
)
2340 static void do_local_lock(int read_fd
, int write_fd
)
2345 const char *local_pathname
= NULL
;
2348 local_pathname
= talloc_asprintf(talloc_tos(),
2349 "%s/lockt9.lck", local_path
);
2350 if (!local_pathname
) {
2351 printf("child: alloc fail\n");
2355 unlink(local_pathname
);
2356 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2358 printf("child: open of %s failed %s.\n",
2359 local_pathname
, strerror(errno
));
2363 /* Now take a fcntl lock. */
2364 lock
.l_type
= F_WRLCK
;
2365 lock
.l_whence
= SEEK_SET
;
2368 lock
.l_pid
= getpid();
2370 ret
= fcntl(fd
,F_SETLK
,&lock
);
2372 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2373 local_pathname
, strerror(errno
));
2376 printf("child: got lock 0:4 on file %s.\n",
2381 CatchSignal(SIGALRM
, alarm_handler
);
2383 /* Signal the parent. */
2384 if (write(write_fd
, &c
, 1) != 1) {
2385 printf("child: start signal fail %s.\n",
2392 /* Wait for the parent to be ready. */
2393 if (read(read_fd
, &c
, 1) != 1) {
2394 printf("child: reply signal fail %s.\n",
2402 printf("child: released lock 0:4 on file %s.\n",
2408 static bool run_locktest9(int dummy
)
2410 struct cli_state
*cli1
;
2411 const char *fname
= "\\lockt9.lck";
2413 bool correct
= False
;
2414 int pipe_in
[2], pipe_out
[2];
2418 struct timeval start
;
2422 printf("starting locktest9\n");
2424 if (local_path
== NULL
) {
2425 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2429 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2434 if (child_pid
== -1) {
2438 if (child_pid
== 0) {
2440 do_local_lock(pipe_out
[0], pipe_in
[1]);
2450 ret
= read(pipe_in
[0], &c
, 1);
2452 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2457 if (!torture_open_connection(&cli1
, 0)) {
2461 cli_sockopt(cli1
, sockops
);
2463 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2465 if (!NT_STATUS_IS_OK(status
)) {
2466 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2470 /* Ensure the child has the lock. */
2471 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2472 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2475 d_printf("Child has the lock.\n");
2478 /* Tell the child to wait 5 seconds then exit. */
2479 ret
= write(pipe_out
[1], &c
, 1);
2481 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2486 /* Wait 20 seconds for the lock. */
2487 alarm_fd
= cli1
->fd
;
2488 CatchSignal(SIGALRM
, alarm_handler_parent
);
2491 start
= timeval_current();
2493 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2494 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2495 "%s\n", cli_errstr(cli1
));
2500 seconds
= timeval_elapsed(&start
);
2502 printf("Parent got the lock after %.2f seconds.\n",
2505 status
= cli_close(cli1
, fnum
);
2506 if (!NT_STATUS_IS_OK(status
)) {
2507 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2514 cli_close(cli1
, fnum
);
2515 torture_close_connection(cli1
);
2519 printf("finished locktest9\n");
2524 test whether fnums and tids open on one VC are available on another (a major
2527 static bool run_fdpasstest(int dummy
)
2529 struct cli_state
*cli1
, *cli2
;
2530 const char *fname
= "\\fdpass.tst";
2534 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2537 cli_sockopt(cli1
, sockops
);
2538 cli_sockopt(cli2
, sockops
);
2540 printf("starting fdpasstest\n");
2542 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2544 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2545 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2549 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2550 printf("write failed (%s)\n", cli_errstr(cli1
));
2554 cli2
->vuid
= cli1
->vuid
;
2555 cli2
->cnum
= cli1
->cnum
;
2556 cli2
->pid
= cli1
->pid
;
2558 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2559 printf("read succeeded! nasty security hole [%s]\n",
2564 cli_close(cli1
, fnum1
);
2565 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2567 torture_close_connection(cli1
);
2568 torture_close_connection(cli2
);
2570 printf("finished fdpasstest\n");
2574 static bool run_fdsesstest(int dummy
)
2576 struct cli_state
*cli
;
2581 const char *fname
= "\\fdsess.tst";
2582 const char *fname1
= "\\fdsess1.tst";
2588 if (!torture_open_connection(&cli
, 0))
2590 cli_sockopt(cli
, sockops
);
2592 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2595 saved_cnum
= cli
->cnum
;
2596 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2598 new_cnum
= cli
->cnum
;
2599 cli
->cnum
= saved_cnum
;
2601 printf("starting fdsesstest\n");
2603 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2604 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2606 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2607 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2611 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2612 printf("write failed (%s)\n", cli_errstr(cli
));
2616 saved_vuid
= cli
->vuid
;
2617 cli
->vuid
= new_vuid
;
2619 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2620 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2624 /* Try to open a file with different vuid, samba cnum. */
2625 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2626 printf("create with different vuid, same cnum succeeded.\n");
2627 cli_close(cli
, fnum2
);
2628 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2630 printf("create with different vuid, same cnum failed.\n");
2631 printf("This will cause problems with service clients.\n");
2635 cli
->vuid
= saved_vuid
;
2637 /* Try with same vuid, different cnum. */
2638 cli
->cnum
= new_cnum
;
2640 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2641 printf("read succeeded with different cnum![%s]\n",
2646 cli
->cnum
= saved_cnum
;
2647 cli_close(cli
, fnum1
);
2648 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2650 torture_close_connection(cli
);
2652 printf("finished fdsesstest\n");
2657 This test checks that
2659 1) the server does not allow an unlink on a file that is open
2661 static bool run_unlinktest(int dummy
)
2663 struct cli_state
*cli
;
2664 const char *fname
= "\\unlink.tst";
2666 bool correct
= True
;
2668 if (!torture_open_connection(&cli
, 0)) {
2672 cli_sockopt(cli
, sockops
);
2674 printf("starting unlink test\n");
2676 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2680 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2681 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2685 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2686 printf("error: server allowed unlink on an open file\n");
2689 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2690 NT_STATUS_SHARING_VIOLATION
);
2693 cli_close(cli
, fnum
);
2694 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2696 if (!torture_close_connection(cli
)) {
2700 printf("unlink test finished\n");
2707 test how many open files this server supports on the one socket
2709 static bool run_maxfidtest(int dummy
)
2711 struct cli_state
*cli
;
2712 const char *ftemplate
= "\\maxfid.%d.%d";
2714 uint16_t fnums
[0x11000];
2717 bool correct
= True
;
2722 printf("failed to connect\n");
2726 cli_sockopt(cli
, sockops
);
2728 for (i
=0; i
<0x11000; i
++) {
2729 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2730 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2731 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2732 printf("open of %s failed (%s)\n",
2733 fname
, cli_errstr(cli
));
2734 printf("maximum fnum is %d\n", i
);
2742 printf("cleaning up\n");
2744 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2745 cli_close(cli
, fnums
[i
]);
2746 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2747 printf("unlink of %s failed (%s)\n",
2748 fname
, cli_errstr(cli
));
2755 printf("maxfid test finished\n");
2756 if (!torture_close_connection(cli
)) {
2762 /* generate a random buffer */
2763 static void rand_buf(char *buf
, int len
)
2766 *buf
= (char)sys_random();
2771 /* send smb negprot commands, not reading the response */
2772 static bool run_negprot_nowait(int dummy
)
2775 static struct cli_state
*cli
;
2776 bool correct
= True
;
2778 printf("starting negprot nowait test\n");
2780 if (!(cli
= open_nbt_connection())) {
2784 for (i
=0;i
<50000;i
++) {
2785 cli_negprot_sendsync(cli
);
2788 if (!torture_close_connection(cli
)) {
2792 printf("finished negprot nowait test\n");
2797 /* send smb negprot commands, not reading the response */
2798 static bool run_bad_nbt_session(int dummy
)
2800 static struct cli_state
*cli
;
2802 printf("starting bad nbt session test\n");
2804 if (!(cli
= open_bad_nbt_connection())) {
2809 printf("finished bad nbt session test\n");
2813 /* send random IPC commands */
2814 static bool run_randomipc(int dummy
)
2816 char *rparam
= NULL
;
2818 unsigned int rdrcnt
,rprcnt
;
2820 int api
, param_len
, i
;
2821 struct cli_state
*cli
;
2822 bool correct
= True
;
2825 printf("starting random ipc test\n");
2827 if (!torture_open_connection(&cli
, 0)) {
2831 for (i
=0;i
<count
;i
++) {
2832 api
= sys_random() % 500;
2833 param_len
= (sys_random() % 64);
2835 rand_buf(param
, param_len
);
2840 param
, param_len
, 8,
2841 NULL
, 0, BUFFER_SIZE
,
2845 printf("%d/%d\r", i
,count
);
2848 printf("%d/%d\n", i
, count
);
2850 if (!torture_close_connection(cli
)) {
2854 printf("finished random ipc test\n");
2861 static void browse_callback(const char *sname
, uint32 stype
,
2862 const char *comment
, void *state
)
2864 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2870 This test checks the browse list code
2873 static bool run_browsetest(int dummy
)
2875 static struct cli_state
*cli
;
2876 bool correct
= True
;
2878 printf("starting browse test\n");
2880 if (!torture_open_connection(&cli
, 0)) {
2884 printf("domain list:\n");
2885 cli_NetServerEnum(cli
, cli
->server_domain
,
2886 SV_TYPE_DOMAIN_ENUM
,
2887 browse_callback
, NULL
);
2889 printf("machine list:\n");
2890 cli_NetServerEnum(cli
, cli
->server_domain
,
2892 browse_callback
, NULL
);
2894 if (!torture_close_connection(cli
)) {
2898 printf("browse test finished\n");
2906 This checks how the getatr calls works
2908 static bool run_attrtest(int dummy
)
2910 struct cli_state
*cli
;
2913 const char *fname
= "\\attrib123456789.tst";
2914 bool correct
= True
;
2916 printf("starting attrib test\n");
2918 if (!torture_open_connection(&cli
, 0)) {
2922 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2923 cli_open(cli
, fname
,
2924 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2925 cli_close(cli
, fnum
);
2926 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2927 printf("getatr failed (%s)\n", cli_errstr(cli
));
2931 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2932 printf("ERROR: SMBgetatr bug. time is %s",
2938 t2
= t
-60*60*24; /* 1 day ago */
2940 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
2941 printf("setatr failed (%s)\n", cli_errstr(cli
));
2945 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2946 printf("getatr failed (%s)\n", cli_errstr(cli
));
2951 printf("ERROR: getatr/setatr bug. times are\n%s",
2953 printf("%s", ctime(&t2
));
2957 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2959 if (!torture_close_connection(cli
)) {
2963 printf("attrib test finished\n");
2970 This checks a couple of trans2 calls
2972 static bool run_trans2test(int dummy
)
2974 struct cli_state
*cli
;
2977 time_t c_time
, a_time
, m_time
;
2978 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
2979 const char *fname
= "\\trans2.tst";
2980 const char *dname
= "\\trans2";
2981 const char *fname2
= "\\trans2\\trans2.tst";
2983 bool correct
= True
;
2987 printf("starting trans2 test\n");
2989 if (!torture_open_connection(&cli
, 0)) {
2993 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
2994 if (!NT_STATUS_IS_OK(status
)) {
2995 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3000 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3001 cli_open(cli
, fname
,
3002 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3003 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3004 cli
, fnum
, NULL
, &size
, &c_time_ts
,
3005 &a_time_ts
, &w_time_ts
,
3006 &m_time_ts
, NULL
))) {
3007 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
3011 if (!NT_STATUS_IS_OK(cli_qfilename(cli
, fnum
, pname
, sizeof(pname
)))) {
3012 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
3016 if (strcmp(pname
, fname
)) {
3017 printf("qfilename gave different name? [%s] [%s]\n",
3022 cli_close(cli
, fnum
);
3026 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3027 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
3028 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
3029 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
3032 cli_close(cli
, fnum
);
3034 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3036 if (!NT_STATUS_IS_OK(status
)) {
3037 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3040 if (c_time
!= m_time
) {
3041 printf("create time=%s", ctime(&c_time
));
3042 printf("modify time=%s", ctime(&m_time
));
3043 printf("This system appears to have sticky create times\n");
3045 if (a_time
% (60*60) == 0) {
3046 printf("access time=%s", ctime(&a_time
));
3047 printf("This system appears to set a midnight access time\n");
3051 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3052 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3058 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3059 cli_open(cli
, fname
,
3060 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3061 cli_close(cli
, fnum
);
3062 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3063 &m_time_ts
, &size
, NULL
, NULL
);
3064 if (!NT_STATUS_IS_OK(status
)) {
3065 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3068 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3069 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3070 printf("This system appears to set a initial 0 write time\n");
3075 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3078 /* check if the server updates the directory modification time
3079 when creating a new file */
3080 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
3081 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
3085 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3086 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3087 if (!NT_STATUS_IS_OK(status
)) {
3088 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3092 cli_open(cli
, fname2
,
3093 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3094 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
3095 cli_close(cli
, fnum
);
3096 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3097 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3098 if (!NT_STATUS_IS_OK(status
)) {
3099 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3102 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3104 printf("This system does not update directory modification times\n");
3108 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
3109 cli_rmdir(cli
, dname
);
3111 if (!torture_close_connection(cli
)) {
3115 printf("trans2 test finished\n");
3121 This checks new W2K calls.
3124 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3126 uint8_t *buf
= NULL
;
3130 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3131 pcli
->max_xmit
, &buf
, &len
);
3132 if (!NT_STATUS_IS_OK(status
)) {
3133 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3136 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3137 dump_data(0, (uint8
*)buf
, len
);
3144 static bool run_w2ktest(int dummy
)
3146 struct cli_state
*cli
;
3148 const char *fname
= "\\w2ktest\\w2k.tst";
3150 bool correct
= True
;
3152 printf("starting w2k test\n");
3154 if (!torture_open_connection(&cli
, 0)) {
3158 cli_open(cli
, fname
,
3159 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3161 for (level
= 1004; level
< 1040; level
++) {
3162 new_trans(cli
, fnum
, level
);
3165 cli_close(cli
, fnum
);
3167 if (!torture_close_connection(cli
)) {
3171 printf("w2k test finished\n");
3178 this is a harness for some oplock tests
3180 static bool run_oplock1(int dummy
)
3182 struct cli_state
*cli1
;
3183 const char *fname
= "\\lockt1.lck";
3185 bool correct
= True
;
3187 printf("starting oplock test 1\n");
3189 if (!torture_open_connection(&cli1
, 0)) {
3193 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3195 cli_sockopt(cli1
, sockops
);
3197 cli1
->use_oplocks
= True
;
3199 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3200 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3204 cli1
->use_oplocks
= False
;
3206 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3207 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3209 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3210 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3214 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3215 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3219 if (!torture_close_connection(cli1
)) {
3223 printf("finished oplock test 1\n");
3228 static bool run_oplock2(int dummy
)
3230 struct cli_state
*cli1
, *cli2
;
3231 const char *fname
= "\\lockt2.lck";
3232 uint16_t fnum1
, fnum2
;
3233 int saved_use_oplocks
= use_oplocks
;
3235 bool correct
= True
;
3236 volatile bool *shared_correct
;
3238 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3239 *shared_correct
= True
;
3241 use_level_II_oplocks
= True
;
3244 printf("starting oplock test 2\n");
3246 if (!torture_open_connection(&cli1
, 0)) {
3247 use_level_II_oplocks
= False
;
3248 use_oplocks
= saved_use_oplocks
;
3252 cli1
->use_oplocks
= True
;
3253 cli1
->use_level_II_oplocks
= True
;
3255 if (!torture_open_connection(&cli2
, 1)) {
3256 use_level_II_oplocks
= False
;
3257 use_oplocks
= saved_use_oplocks
;
3261 cli2
->use_oplocks
= True
;
3262 cli2
->use_level_II_oplocks
= True
;
3264 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3266 cli_sockopt(cli1
, sockops
);
3267 cli_sockopt(cli2
, sockops
);
3269 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3270 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3274 /* Don't need the globals any more. */
3275 use_level_II_oplocks
= False
;
3276 use_oplocks
= saved_use_oplocks
;
3280 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3281 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3282 *shared_correct
= False
;
3288 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3289 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3290 *shared_correct
= False
;
3298 /* Ensure cli1 processes the break. Empty file should always return 0
3301 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3302 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3306 /* Should now be at level II. */
3307 /* Test if sending a write locks causes a break to none. */
3309 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3310 printf("lock failed (%s)\n", cli_errstr(cli1
));
3314 cli_unlock(cli1
, fnum1
, 0, 4);
3318 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3319 printf("lock failed (%s)\n", cli_errstr(cli1
));
3323 cli_unlock(cli1
, fnum1
, 0, 4);
3327 cli_read(cli1
, fnum1
, buf
, 0, 4);
3330 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3331 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
3336 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3337 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3343 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3344 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3348 if (!torture_close_connection(cli1
)) {
3352 if (!*shared_correct
) {
3356 printf("finished oplock test 2\n");
3361 /* handler for oplock 3 tests */
3362 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3364 printf("got oplock break fnum=%d level=%d\n",
3366 return cli_oplock_ack(cli
, fnum
, level
);
3369 static bool run_oplock3(int dummy
)
3371 struct cli_state
*cli
;
3372 const char *fname
= "\\oplockt3.dat";
3374 char buf
[4] = "abcd";
3375 bool correct
= True
;
3376 volatile bool *shared_correct
;
3378 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3379 *shared_correct
= True
;
3381 printf("starting oplock test 3\n");
3386 use_level_II_oplocks
= True
;
3387 if (!torture_open_connection(&cli
, 0)) {
3388 *shared_correct
= False
;
3392 /* try to trigger a oplock break in parent */
3393 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3394 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3400 use_level_II_oplocks
= True
;
3401 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3404 cli_oplock_handler(cli
, oplock3_handler
);
3405 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3406 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3407 cli_close(cli
, fnum
);
3408 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3409 cli
->timeout
= 20000;
3410 cli_receive_smb(cli
);
3411 printf("finished oplock test 3\n");
3413 return (correct
&& *shared_correct
);
3415 /* What are we looking for here? What's sucess and what's FAILURE? */
3418 /* handler for oplock 4 tests */
3419 bool *oplock4_shared_correct
;
3421 static NTSTATUS
oplock4_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3423 printf("got oplock break fnum=%d level=%d\n",
3425 *oplock4_shared_correct
= true;
3426 cli_oplock_ack(cli
, fnum
, level
);
3427 return NT_STATUS_UNSUCCESSFUL
; /* Cause cli_receive_smb to return. */
3430 static bool run_oplock4(int dummy
)
3432 struct cli_state
*cli1
, *cli2
;
3433 const char *fname
= "\\lockt4.lck";
3434 const char *fname_ln
= "\\lockt4_ln.lck";
3435 uint16_t fnum1
, fnum2
;
3436 int saved_use_oplocks
= use_oplocks
;
3438 bool correct
= true;
3440 oplock4_shared_correct
= (bool *)shm_setup(sizeof(bool));
3441 *oplock4_shared_correct
= false;
3443 printf("starting oplock test 4\n");
3445 if (!torture_open_connection(&cli1
, 0)) {
3446 use_level_II_oplocks
= false;
3447 use_oplocks
= saved_use_oplocks
;
3451 if (!torture_open_connection(&cli2
, 1)) {
3452 use_level_II_oplocks
= false;
3453 use_oplocks
= saved_use_oplocks
;
3457 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3458 cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
);
3460 cli_sockopt(cli1
, sockops
);
3461 cli_sockopt(cli2
, sockops
);
3463 /* Create the file. */
3464 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3465 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3469 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3470 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3474 /* Now create a hardlink. */
3475 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1
, fname
, fname_ln
))) {
3476 printf("nt hardlink failed (%s)\n", cli_errstr(cli1
));
3480 /* Prove that opening hardlinks cause deny modes to conflict. */
3481 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
))) {
3482 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3486 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3487 if (NT_STATUS_IS_OK(status
)) {
3488 printf("open of %s succeeded - should fail with sharing violation.\n",
3493 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3494 printf("open of %s should fail with sharing violation. Got %s\n",
3495 fname_ln
, nt_errstr(status
));
3499 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3500 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3504 cli1
->use_oplocks
= true;
3505 cli1
->use_level_II_oplocks
= true;
3507 cli2
->use_oplocks
= true;
3508 cli2
->use_level_II_oplocks
= true;
3510 cli_oplock_handler(cli1
, oplock4_handler
);
3511 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3512 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3518 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3519 printf("open of %s failed (%s)\n", fname_ln
, cli_errstr(cli1
));
3520 *oplock4_shared_correct
= false;
3524 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3525 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3526 *oplock4_shared_correct
= false;
3534 /* Process the oplock break. */
3535 cli_receive_smb(cli1
);
3537 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3538 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3542 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3543 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3546 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
))) {
3547 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3551 if (!torture_close_connection(cli1
)) {
3555 if (!*oplock4_shared_correct
) {
3559 printf("finished oplock test 4\n");
3566 Test delete on close semantics.
3568 static bool run_deletetest(int dummy
)
3570 struct cli_state
*cli1
= NULL
;
3571 struct cli_state
*cli2
= NULL
;
3572 const char *fname
= "\\delete.file";
3573 uint16_t fnum1
= (uint16_t)-1;
3574 uint16_t fnum2
= (uint16_t)-1;
3575 bool correct
= True
;
3577 printf("starting delete test\n");
3579 if (!torture_open_connection(&cli1
, 0)) {
3583 cli_sockopt(cli1
, sockops
);
3585 /* Test 1 - this should delete the file on close. */
3587 cli_setatr(cli1
, fname
, 0, 0);
3588 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3590 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3591 0, FILE_OVERWRITE_IF
,
3592 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3593 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3598 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3599 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3604 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3605 printf("[1] open of %s succeeded (should fail)\n", fname
);
3610 printf("first delete on close test succeeded.\n");
3612 /* Test 2 - this should delete the file on close. */
3614 cli_setatr(cli1
, fname
, 0, 0);
3615 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3617 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3618 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3619 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3620 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3625 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3626 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3631 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3632 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3637 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3638 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3639 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3640 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3644 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3646 printf("second delete on close test succeeded.\n");
3649 cli_setatr(cli1
, fname
, 0, 0);
3650 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3652 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3653 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3654 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3659 /* This should fail with a sharing violation - open for delete is only compatible
3660 with SHARE_DELETE. */
3662 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3663 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3664 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3669 /* This should succeed. */
3671 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3672 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3673 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3678 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3679 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3684 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3685 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3690 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3691 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3696 /* This should fail - file should no longer be there. */
3698 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3699 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3700 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3701 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3703 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3707 printf("third delete on close test succeeded.\n");
3710 cli_setatr(cli1
, fname
, 0, 0);
3711 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3713 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3714 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3715 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3720 /* This should succeed. */
3721 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3722 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3723 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3728 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3729 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3734 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3735 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3740 /* This should fail - no more opens once delete on close set. */
3741 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3742 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3743 FILE_OPEN
, 0, 0, &fnum2
))) {
3744 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3748 printf("fourth delete on close test succeeded.\n");
3750 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3751 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3757 cli_setatr(cli1
, fname
, 0, 0);
3758 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3760 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3761 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3766 /* This should fail - only allowed on NT opens with DELETE access. */
3768 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3769 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3774 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3775 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3780 printf("fifth delete on close test succeeded.\n");
3783 cli_setatr(cli1
, fname
, 0, 0);
3784 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3787 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3788 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3789 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3794 /* This should fail - only allowed on NT opens with DELETE access. */
3796 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3797 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3802 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3803 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3808 printf("sixth delete on close test succeeded.\n");
3811 cli_setatr(cli1
, fname
, 0, 0);
3812 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3814 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3815 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3816 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3821 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3822 printf("[7] setting delete_on_close on file failed !\n");
3827 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3828 printf("[7] unsetting delete_on_close on file failed !\n");
3833 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3834 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3839 /* This next open should succeed - we reset the flag. */
3841 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3842 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3847 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3848 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3853 printf("seventh delete on close test succeeded.\n");
3856 cli_setatr(cli1
, fname
, 0, 0);
3857 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3859 if (!torture_open_connection(&cli2
, 1)) {
3860 printf("[8] failed to open second connection.\n");
3865 cli_sockopt(cli1
, sockops
);
3867 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3868 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3869 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3870 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3875 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3876 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3877 FILE_OPEN
, 0, 0, &fnum2
))) {
3878 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3883 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3884 printf("[8] setting delete_on_close on file failed !\n");
3889 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3890 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3895 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3896 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3901 /* This should fail.. */
3902 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3903 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3907 printf("eighth delete on close test succeeded.\n");
3909 /* This should fail - we need to set DELETE_ACCESS. */
3910 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3911 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3912 printf("[9] open of %s succeeded should have failed!\n", fname
);
3917 printf("ninth delete on close test succeeded.\n");
3919 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3920 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3921 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3926 /* This should delete the file. */
3927 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3928 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3933 /* This should fail.. */
3934 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3935 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3939 printf("tenth delete on close test succeeded.\n");
3941 cli_setatr(cli1
, fname
, 0, 0);
3942 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3944 /* What error do we get when attempting to open a read-only file with
3947 /* Create a readonly file. */
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3949 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3950 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3955 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3956 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3961 /* Now try open for delete access. */
3962 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3963 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3964 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3965 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3966 cli_close(cli1
, fnum1
);
3970 NTSTATUS nterr
= cli_nt_error(cli1
);
3971 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
3972 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
3976 printf("eleventh delete on close test succeeded.\n");
3980 printf("finished delete test\n");
3983 /* FIXME: This will crash if we aborted before cli2 got
3984 * intialized, because these functions don't handle
3985 * uninitialized connections. */
3987 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
3988 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
3989 cli_setatr(cli1
, fname
, 0, 0);
3990 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3992 if (cli1
&& !torture_close_connection(cli1
)) {
3995 if (cli2
&& !torture_close_connection(cli2
)) {
4001 static bool run_deletetest_ln(int dummy
)
4003 struct cli_state
*cli
;
4004 const char *fname
= "\\delete1";
4005 const char *fname_ln
= "\\delete1_ln";
4009 bool correct
= true;
4012 printf("starting deletetest-ln\n");
4014 if (!torture_open_connection(&cli
, 0)) {
4018 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4019 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4021 cli_sockopt(cli
, sockops
);
4023 /* Create the file. */
4024 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4025 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4029 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum
))) {
4030 printf("close1 failed (%s)\n", cli_errstr(cli
));
4034 /* Now create a hardlink. */
4035 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli
, fname
, fname_ln
))) {
4036 printf("nt hardlink failed (%s)\n", cli_errstr(cli
));
4040 /* Open the original file. */
4041 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4042 FILE_ATTRIBUTE_NORMAL
,
4043 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4044 FILE_OPEN_IF
, 0, 0, &fnum
);
4045 if (!NT_STATUS_IS_OK(status
)) {
4046 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4050 /* Unlink the hard link path. */
4051 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4052 FILE_ATTRIBUTE_NORMAL
,
4053 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4054 FILE_OPEN_IF
, 0, 0, &fnum1
);
4055 if (!NT_STATUS_IS_OK(status
)) {
4056 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4059 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4060 if (!NT_STATUS_IS_OK(status
)) {
4061 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4062 __location__
, fname_ln
, nt_errstr(status
));
4066 status
= cli_close(cli
, fnum1
);
4067 if (!NT_STATUS_IS_OK(status
)) {
4068 printf("close %s failed (%s)\n",
4069 fname_ln
, nt_errstr(status
));
4073 status
= cli_close(cli
, fnum
);
4074 if (!NT_STATUS_IS_OK(status
)) {
4075 printf("close %s failed (%s)\n",
4076 fname
, nt_errstr(status
));
4080 /* Ensure the original file is still there. */
4081 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4082 if (!NT_STATUS_IS_OK(status
)) {
4083 printf("%s getatr on file %s failed (%s)\n",
4090 /* Ensure the link path is gone. */
4091 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4092 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4093 printf("%s, getatr for file %s returned wrong error code %s "
4094 "- should have been deleted\n",
4096 fname_ln
, nt_errstr(status
));
4100 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4101 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4103 if (!torture_close_connection(cli
)) {
4107 printf("finished deletetest-ln\n");
4113 print out server properties
4115 static bool run_properties(int dummy
)
4117 struct cli_state
*cli
;
4118 bool correct
= True
;
4120 printf("starting properties test\n");
4124 if (!torture_open_connection(&cli
, 0)) {
4128 cli_sockopt(cli
, sockops
);
4130 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
4132 if (!torture_close_connection(cli
)) {
4141 /* FIRST_DESIRED_ACCESS 0xf019f */
4142 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4143 FILE_READ_EA| /* 0xf */ \
4144 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4145 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4146 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4147 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4148 /* SECOND_DESIRED_ACCESS 0xe0080 */
4149 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4150 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4151 WRITE_OWNER_ACCESS /* 0xe0000 */
4154 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4155 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4157 WRITE_OWNER_ACCESS /* */
4161 Test ntcreate calls made by xcopy
4163 static bool run_xcopy(int dummy
)
4165 static struct cli_state
*cli1
;
4166 const char *fname
= "\\test.txt";
4167 bool correct
= True
;
4168 uint16_t fnum1
, fnum2
;
4170 printf("starting xcopy test\n");
4172 if (!torture_open_connection(&cli1
, 0)) {
4176 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4177 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
4178 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
4179 0x4044, 0, &fnum1
))) {
4180 printf("First open failed - %s\n", cli_errstr(cli1
));
4184 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4185 SECOND_DESIRED_ACCESS
, 0,
4186 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
4187 0x200000, 0, &fnum2
))) {
4188 printf("second open failed - %s\n", cli_errstr(cli1
));
4192 if (!torture_close_connection(cli1
)) {
4200 Test rename on files open with share delete and no share delete.
4202 static bool run_rename(int dummy
)
4204 static struct cli_state
*cli1
;
4205 const char *fname
= "\\test.txt";
4206 const char *fname1
= "\\test1.txt";
4207 bool correct
= True
;
4212 printf("starting rename test\n");
4214 if (!torture_open_connection(&cli1
, 0)) {
4218 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4219 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4220 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4221 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4222 printf("First open failed - %s\n", cli_errstr(cli1
));
4226 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4227 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
4229 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4233 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4234 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
4238 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4239 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4240 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4242 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4244 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4246 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4247 if (!NT_STATUS_IS_OK(status
)) {
4248 printf("Second open failed - %s\n", cli_errstr(cli1
));
4252 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4253 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
4256 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4259 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4260 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
4264 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4265 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4267 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4268 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4269 printf("Third open failed - %s\n", cli_errstr(cli1
));
4278 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4279 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4280 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4283 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4284 printf("[8] setting delete_on_close on file failed !\n");
4288 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4289 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4295 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4296 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
4299 printf("Third rename succeeded (SHARE_NONE)\n");
4302 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4303 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
4307 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4308 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4312 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4313 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4314 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4318 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4319 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
4321 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4325 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4326 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4330 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4331 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4335 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4336 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4337 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
4341 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4342 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4346 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
4350 * Now check if the first name still exists ...
4353 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4354 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4355 printf("Opening original file after rename of open file fails: %s\n",
4359 printf("Opening original file after rename of open file works ...\n");
4360 (void)cli_close(cli1, fnum2);
4364 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4365 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
4369 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4370 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
))) {
4371 printf("getatr on file %s failed - %s ! \n",
4376 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4377 printf("Renamed file %s has wrong attr 0x%x "
4378 "(should be 0x%x)\n",
4381 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4384 printf("Renamed file %s has archive bit set\n", fname1
);
4388 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4389 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4391 if (!torture_close_connection(cli1
)) {
4398 static bool run_pipe_number(int dummy
)
4400 struct cli_state
*cli1
;
4401 const char *pipe_name
= "\\SPOOLSS";
4405 printf("starting pipenumber test\n");
4406 if (!torture_open_connection(&cli1
, 0)) {
4410 cli_sockopt(cli1
, sockops
);
4412 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4413 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
4414 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
4418 printf("\r%6d", num_pipes
);
4421 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4422 torture_close_connection(cli1
);
4427 Test open mode returns on read-only files.
4429 static bool run_opentest(int dummy
)
4431 static struct cli_state
*cli1
;
4432 static struct cli_state
*cli2
;
4433 const char *fname
= "\\readonly.file";
4434 uint16_t fnum1
, fnum2
;
4437 bool correct
= True
;
4440 printf("starting open test\n");
4442 if (!torture_open_connection(&cli1
, 0)) {
4446 cli_setatr(cli1
, fname
, 0, 0);
4447 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4449 cli_sockopt(cli1
, sockops
);
4451 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4452 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4456 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4457 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4461 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4462 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
4466 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4467 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4471 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4472 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4474 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4475 NT_STATUS_ACCESS_DENIED
)) {
4476 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4479 printf("finished open test 1\n");
4481 cli_close(cli1
, fnum1
);
4483 /* Now try not readonly and ensure ERRbadshare is returned. */
4485 cli_setatr(cli1
, fname
, 0, 0);
4487 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4488 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4492 /* This will fail - but the error should be ERRshare. */
4493 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4495 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4496 NT_STATUS_SHARING_VIOLATION
)) {
4497 printf("correct error code ERRDOS/ERRbadshare returned\n");
4500 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4501 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4505 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4507 printf("finished open test 2\n");
4509 /* Test truncate open disposition on file opened for read. */
4511 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4512 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4516 /* write 20 bytes. */
4518 memset(buf
, '\0', 20);
4520 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4521 printf("write failed (%s)\n", cli_errstr(cli1
));
4525 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4526 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4530 /* Ensure size == 20. */
4531 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4532 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4537 printf("(3) file size != 20\n");
4541 /* Now test if we can truncate a file opened for readonly. */
4543 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4544 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4548 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4549 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4553 /* Ensure size == 0. */
4554 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4555 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4560 printf("(3) file size != 0\n");
4563 printf("finished open test 3\n");
4565 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4567 printf("Do ctemp tests\n");
4568 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4569 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4572 printf("ctemp gave path %s\n", tmp_path
);
4573 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4574 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4576 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4577 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4580 /* Test the non-io opens... */
4582 if (!torture_open_connection(&cli2
, 1)) {
4586 cli_setatr(cli2
, fname
, 0, 0);
4587 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4589 cli_sockopt(cli2
, sockops
);
4591 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4593 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4594 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4595 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4599 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4600 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4601 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4605 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4606 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4609 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4610 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4614 printf("non-io open test #1 passed.\n");
4616 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4618 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4620 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4621 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4622 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4626 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4627 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4628 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4632 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4633 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4636 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4637 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4641 printf("non-io open test #2 passed.\n");
4643 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4645 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4647 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4648 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4649 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4653 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4654 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4655 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4659 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4660 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4663 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4664 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4668 printf("non-io open test #3 passed.\n");
4670 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4672 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4675 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4676 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4680 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4681 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4682 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4686 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4688 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4689 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4693 printf("non-io open test #4 passed.\n");
4695 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4697 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4699 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4700 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4701 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4705 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4706 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4707 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4711 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4712 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4716 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4717 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4721 printf("non-io open test #5 passed.\n");
4723 printf("TEST #6 testing 1 non-io open, one io open\n");
4725 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4727 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4728 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4729 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4733 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4734 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4735 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4739 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4740 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4744 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4745 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4749 printf("non-io open test #6 passed.\n");
4751 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4753 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4755 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4756 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4757 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4761 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4762 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4763 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4767 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4769 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4770 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4774 printf("non-io open test #7 passed.\n");
4776 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4778 if (!torture_close_connection(cli1
)) {
4781 if (!torture_close_connection(cli2
)) {
4788 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4790 uint16 major
, minor
;
4791 uint32 caplow
, caphigh
;
4794 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4795 printf("Server doesn't support UNIX CIFS extensions.\n");
4796 return NT_STATUS_NOT_SUPPORTED
;
4799 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4801 if (!NT_STATUS_IS_OK(status
)) {
4802 printf("Server didn't return UNIX CIFS extensions: %s\n",
4807 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4809 if (!NT_STATUS_IS_OK(status
)) {
4810 printf("Server doesn't support setting UNIX CIFS extensions: "
4811 "%s.\n", nt_errstr(status
));
4815 return NT_STATUS_OK
;
4819 Test POSIX open /mkdir calls.
4821 static bool run_simple_posix_open_test(int dummy
)
4823 static struct cli_state
*cli1
;
4824 const char *fname
= "posix:file";
4825 const char *hname
= "posix:hlink";
4826 const char *sname
= "posix:symlink";
4827 const char *dname
= "posix:dir";
4830 uint16_t fnum1
= (uint16_t)-1;
4831 SMB_STRUCT_STAT sbuf
;
4832 bool correct
= false;
4835 printf("Starting simple POSIX open test\n");
4837 if (!torture_open_connection(&cli1
, 0)) {
4841 cli_sockopt(cli1
, sockops
);
4843 status
= torture_setup_unix_extensions(cli1
);
4844 if (!NT_STATUS_IS_OK(status
)) {
4848 cli_setatr(cli1
, fname
, 0, 0);
4849 cli_posix_unlink(cli1
, fname
);
4850 cli_setatr(cli1
, dname
, 0, 0);
4851 cli_posix_rmdir(cli1
, dname
);
4852 cli_setatr(cli1
, hname
, 0, 0);
4853 cli_posix_unlink(cli1
, hname
);
4854 cli_setatr(cli1
, sname
, 0, 0);
4855 cli_posix_unlink(cli1
, sname
);
4857 /* Create a directory. */
4858 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4859 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4863 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4864 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4868 /* Test ftruncate - set file size. */
4869 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4870 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4874 /* Ensure st_size == 1000 */
4875 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4876 printf("stat failed (%s)\n", cli_errstr(cli1
));
4880 if (sbuf
.st_ex_size
!= 1000) {
4881 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4885 /* Test ftruncate - set file size back to zero. */
4886 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4887 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4891 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4892 printf("close failed (%s)\n", cli_errstr(cli1
));
4896 /* Now open the file again for read only. */
4897 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4898 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4902 /* Now unlink while open. */
4903 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
4904 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4908 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4909 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4913 /* Ensure the file has gone. */
4914 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4915 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4919 /* What happens when we try and POSIX open a directory ? */
4920 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
4921 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
4924 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
4925 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4930 /* Create the file. */
4931 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4932 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4936 /* Write some data into it. */
4937 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4938 printf("cli_write failed: %s\n", cli_errstr(cli1
));
4942 cli_close(cli1
, fnum1
);
4944 /* Now create a hardlink. */
4945 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
4946 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4950 /* Now create a symlink. */
4951 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
4952 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
4956 /* Open the hardlink for read. */
4957 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
4958 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4962 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
4963 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4967 if (memcmp(buf
, "TEST DATA\n", 10)) {
4968 printf("invalid data read from hardlink\n");
4972 /* Do a POSIX lock/unlock. */
4973 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
4974 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
4978 /* Punch a hole in the locked area. */
4979 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
4980 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
4984 cli_close(cli1
, fnum1
);
4986 /* Open the symlink for read - this should fail. A POSIX
4987 client should not be doing opens on a symlink. */
4988 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
4989 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
4992 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
4993 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
4994 printf("POSIX open of %s should have failed "
4995 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4996 "failed with %s instead.\n",
4997 sname
, cli_errstr(cli1
));
5002 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
5003 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
5007 if (strcmp(namebuf
, fname
) != 0) {
5008 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5009 sname
, fname
, namebuf
);
5013 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
5014 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
5018 printf("Simple POSIX open test passed\n");
5023 if (fnum1
!= (uint16_t)-1) {
5024 cli_close(cli1
, fnum1
);
5025 fnum1
= (uint16_t)-1;
5028 cli_setatr(cli1
, sname
, 0, 0);
5029 cli_posix_unlink(cli1
, sname
);
5030 cli_setatr(cli1
, hname
, 0, 0);
5031 cli_posix_unlink(cli1
, hname
);
5032 cli_setatr(cli1
, fname
, 0, 0);
5033 cli_posix_unlink(cli1
, fname
);
5034 cli_setatr(cli1
, dname
, 0, 0);
5035 cli_posix_rmdir(cli1
, dname
);
5037 if (!torture_close_connection(cli1
)) {
5045 static uint32 open_attrs_table
[] = {
5046 FILE_ATTRIBUTE_NORMAL
,
5047 FILE_ATTRIBUTE_ARCHIVE
,
5048 FILE_ATTRIBUTE_READONLY
,
5049 FILE_ATTRIBUTE_HIDDEN
,
5050 FILE_ATTRIBUTE_SYSTEM
,
5052 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5053 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5054 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5055 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5056 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5057 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5059 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5060 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5061 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5062 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5065 struct trunc_open_results
{
5072 static struct trunc_open_results attr_results
[] = {
5073 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5074 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5075 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5076 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5077 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5078 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5079 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5080 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5081 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5082 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5083 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5084 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5085 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5086 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5087 { 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
},
5088 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5089 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5090 { 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
},
5091 { 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
},
5092 { 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
},
5093 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5094 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5095 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5096 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5097 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5098 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5101 static bool run_openattrtest(int dummy
)
5103 static struct cli_state
*cli1
;
5104 const char *fname
= "\\openattr.file";
5106 bool correct
= True
;
5108 unsigned int i
, j
, k
, l
;
5110 printf("starting open attr test\n");
5112 if (!torture_open_connection(&cli1
, 0)) {
5116 cli_sockopt(cli1
, sockops
);
5118 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5119 cli_setatr(cli1
, fname
, 0, 0);
5120 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5121 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
5122 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
5123 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5127 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5128 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5132 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5133 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
5134 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
5135 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5136 if (attr_results
[l
].num
== k
) {
5137 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5138 k
, open_attrs_table
[i
],
5139 open_attrs_table
[j
],
5140 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
5144 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
5145 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5146 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5151 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5157 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5158 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
5162 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
5163 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
5168 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5169 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5172 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5173 if (attr_results
[l
].num
== k
) {
5174 if (attr
!= attr_results
[l
].result_attr
||
5175 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5176 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5177 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5178 open_attrs_table
[i
],
5179 open_attrs_table
[j
],
5181 attr_results
[l
].result_attr
);
5191 cli_setatr(cli1
, fname
, 0, 0);
5192 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5194 printf("open attr test %s.\n", correct
? "passed" : "failed");
5196 if (!torture_close_connection(cli1
)) {
5202 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5203 const char *name
, void *state
)
5205 int *matched
= (int *)state
;
5206 if (matched
!= NULL
) {
5209 return NT_STATUS_OK
;
5213 test directory listing speed
5215 static bool run_dirtest(int dummy
)
5218 static struct cli_state
*cli
;
5220 struct timeval core_start
;
5221 bool correct
= True
;
5224 printf("starting directory test\n");
5226 if (!torture_open_connection(&cli
, 0)) {
5230 cli_sockopt(cli
, sockops
);
5233 for (i
=0;i
<torture_numops
;i
++) {
5235 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5236 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5237 fprintf(stderr
,"Failed to open %s\n", fname
);
5240 cli_close(cli
, fnum
);
5243 core_start
= timeval_current();
5246 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5247 printf("Matched %d\n", matched
);
5250 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5251 printf("Matched %d\n", matched
);
5254 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5255 printf("Matched %d\n", matched
);
5257 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5260 for (i
=0;i
<torture_numops
;i
++) {
5262 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5263 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5266 if (!torture_close_connection(cli
)) {
5270 printf("finished dirtest\n");
5275 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5278 struct cli_state
*pcli
= (struct cli_state
*)state
;
5280 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5282 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5283 return NT_STATUS_OK
;
5285 if (finfo
->mode
& aDIR
) {
5286 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5287 printf("del_fn: failed to rmdir %s\n,", fname
);
5289 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
5290 printf("del_fn: failed to unlink %s\n,", fname
);
5292 return NT_STATUS_OK
;
5297 sees what IOCTLs are supported
5299 bool torture_ioctl_test(int dummy
)
5301 static struct cli_state
*cli
;
5302 uint16_t device
, function
;
5304 const char *fname
= "\\ioctl.dat";
5308 if (!torture_open_connection(&cli
, 0)) {
5312 printf("starting ioctl test\n");
5314 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5316 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5317 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
5321 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5322 printf("ioctl device info: %s\n", nt_errstr(status
));
5324 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5325 printf("ioctl job info: %s\n", nt_errstr(status
));
5327 for (device
=0;device
<0x100;device
++) {
5328 printf("ioctl test with device = 0x%x\n", device
);
5329 for (function
=0;function
<0x100;function
++) {
5330 uint32 code
= (device
<<16) | function
;
5332 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5334 if (NT_STATUS_IS_OK(status
)) {
5335 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5337 data_blob_free(&blob
);
5342 if (!torture_close_connection(cli
)) {
5351 tries varients of chkpath
5353 bool torture_chkpath_test(int dummy
)
5355 static struct cli_state
*cli
;
5359 if (!torture_open_connection(&cli
, 0)) {
5363 printf("starting chkpath test\n");
5365 /* cleanup from an old run */
5366 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5367 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5368 cli_rmdir(cli
, "\\chkpath.dir");
5370 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
5371 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
5375 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
5376 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
5380 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5381 printf("open1 failed (%s)\n", cli_errstr(cli
));
5384 cli_close(cli
, fnum
);
5386 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
5387 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
5391 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
5392 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
5396 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
5397 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5398 NT_STATUS_NOT_A_DIRECTORY
);
5400 printf("* chkpath on a file should fail\n");
5404 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
5405 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
5406 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
5408 printf("* chkpath on a non existant file should fail\n");
5412 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5413 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5414 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
5416 printf("* chkpath on a non existent component should fail\n");
5420 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5421 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5422 cli_rmdir(cli
, "\\chkpath.dir");
5424 if (!torture_close_connection(cli
)) {
5431 static bool run_eatest(int dummy
)
5433 static struct cli_state
*cli
;
5434 const char *fname
= "\\eatest.txt";
5435 bool correct
= True
;
5439 struct ea_struct
*ea_list
= NULL
;
5440 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5443 printf("starting eatest\n");
5445 if (!torture_open_connection(&cli
, 0)) {
5446 talloc_destroy(mem_ctx
);
5450 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5452 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5453 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5454 0x4044, 0, &fnum
))) {
5455 printf("open failed - %s\n", cli_errstr(cli
));
5456 talloc_destroy(mem_ctx
);
5460 for (i
= 0; i
< 10; i
++) {
5461 fstring ea_name
, ea_val
;
5463 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5464 memset(ea_val
, (char)i
+1, i
+1);
5465 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
5466 if (!NT_STATUS_IS_OK(status
)) {
5467 printf("ea_set of name %s failed - %s\n", ea_name
,
5469 talloc_destroy(mem_ctx
);
5474 cli_close(cli
, fnum
);
5475 for (i
= 0; i
< 10; i
++) {
5476 fstring ea_name
, ea_val
;
5478 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5479 memset(ea_val
, (char)i
+1, i
+1);
5480 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
5481 if (!NT_STATUS_IS_OK(status
)) {
5482 printf("ea_set of name %s failed - %s\n", ea_name
,
5484 talloc_destroy(mem_ctx
);
5489 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5490 if (!NT_STATUS_IS_OK(status
)) {
5491 printf("ea_get list failed - %s\n", nt_errstr(status
));
5495 printf("num_eas = %d\n", (int)num_eas
);
5497 if (num_eas
!= 20) {
5498 printf("Should be 20 EA's stored... failing.\n");
5502 for (i
= 0; i
< num_eas
; i
++) {
5503 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5504 dump_data(0, ea_list
[i
].value
.data
,
5505 ea_list
[i
].value
.length
);
5508 /* Setting EA's to zero length deletes them. Test this */
5509 printf("Now deleting all EA's - case indepenent....\n");
5512 cli_set_ea_path(cli
, fname
, "", "", 0);
5514 for (i
= 0; i
< 20; i
++) {
5516 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5517 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
5518 if (!NT_STATUS_IS_OK(status
)) {
5519 printf("ea_set of name %s failed - %s\n", ea_name
,
5521 talloc_destroy(mem_ctx
);
5527 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5528 if (!NT_STATUS_IS_OK(status
)) {
5529 printf("ea_get list failed - %s\n", nt_errstr(status
));
5533 printf("num_eas = %d\n", (int)num_eas
);
5534 for (i
= 0; i
< num_eas
; i
++) {
5535 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5536 dump_data(0, ea_list
[i
].value
.data
,
5537 ea_list
[i
].value
.length
);
5541 printf("deleting EA's failed.\n");
5545 /* Try and delete a non existant EA. */
5546 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
5547 if (!NT_STATUS_IS_OK(status
)) {
5548 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5553 talloc_destroy(mem_ctx
);
5554 if (!torture_close_connection(cli
)) {
5561 static bool run_dirtest1(int dummy
)
5564 static struct cli_state
*cli
;
5567 bool correct
= True
;
5569 printf("starting directory test\n");
5571 if (!torture_open_connection(&cli
, 0)) {
5575 cli_sockopt(cli
, sockops
);
5577 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5578 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5579 cli_rmdir(cli
, "\\LISTDIR");
5580 cli_mkdir(cli
, "\\LISTDIR");
5582 /* Create 1000 files and 1000 directories. */
5583 for (i
=0;i
<1000;i
++) {
5585 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5586 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5587 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5588 fprintf(stderr
,"Failed to open %s\n", fname
);
5591 cli_close(cli
, fnum
);
5593 for (i
=0;i
<1000;i
++) {
5595 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5596 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5597 fprintf(stderr
,"Failed to open %s\n", fname
);
5602 /* Now ensure that doing an old list sees both files and directories. */
5604 cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, &num_seen
);
5605 printf("num_seen = %d\n", num_seen
);
5606 /* We should see 100 files + 1000 directories + . and .. */
5607 if (num_seen
!= 2002)
5610 /* Ensure if we have the "must have" bits we only see the
5614 cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, &num_seen
);
5615 printf("num_seen = %d\n", num_seen
);
5616 if (num_seen
!= 1002)
5620 cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, &num_seen
);
5621 printf("num_seen = %d\n", num_seen
);
5622 if (num_seen
!= 1000)
5625 /* Delete everything. */
5626 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5627 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5628 cli_rmdir(cli
, "\\LISTDIR");
5631 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5632 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5633 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5636 if (!torture_close_connection(cli
)) {
5640 printf("finished dirtest1\n");
5645 static bool run_error_map_extract(int dummy
) {
5647 static struct cli_state
*c_dos
;
5648 static struct cli_state
*c_nt
;
5653 uint32 flgs2
, errnum
;
5660 /* NT-Error connection */
5662 if (!(c_nt
= open_nbt_connection())) {
5666 c_nt
->use_spnego
= False
;
5668 status
= cli_negprot(c_nt
);
5670 if (!NT_STATUS_IS_OK(status
)) {
5671 printf("%s rejected the NT-error negprot (%s)\n", host
,
5677 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5679 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5683 /* DOS-Error connection */
5685 if (!(c_dos
= open_nbt_connection())) {
5689 c_dos
->use_spnego
= False
;
5690 c_dos
->force_dos_errors
= True
;
5692 status
= cli_negprot(c_dos
);
5693 if (!NT_STATUS_IS_OK(status
)) {
5694 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5696 cli_shutdown(c_dos
);
5700 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5702 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5706 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5707 fstr_sprintf(user
, "%X", error
);
5709 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5710 password
, strlen(password
),
5711 password
, strlen(password
),
5713 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5716 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5718 /* Case #1: 32-bit NT errors */
5719 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5720 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5722 printf("/** Dos error on NT connection! (%s) */\n",
5724 nt_status
= NT_STATUS(0xc0000000);
5727 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5728 password
, strlen(password
),
5729 password
, strlen(password
),
5731 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5733 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5735 /* Case #1: 32-bit NT errors */
5736 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5737 printf("/** NT error on DOS connection! (%s) */\n",
5739 errnum
= errclass
= 0;
5741 cli_dos_error(c_dos
, &errclass
, &errnum
);
5744 if (NT_STATUS_V(nt_status
) != error
) {
5745 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5746 get_nt_error_c_code(NT_STATUS(error
)),
5747 get_nt_error_c_code(nt_status
));
5750 printf("\t{%s,\t%s,\t%s},\n",
5751 smb_dos_err_class(errclass
),
5752 smb_dos_err_name(errclass
, errnum
),
5753 get_nt_error_c_code(NT_STATUS(error
)));
5758 static bool run_sesssetup_bench(int dummy
)
5760 static struct cli_state
*c
;
5761 const char *fname
= "\\file.dat";
5766 if (!torture_open_connection(&c
, 0)) {
5770 if (!NT_STATUS_IS_OK(cli_ntcreate(
5771 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5772 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5773 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5774 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5778 for (i
=0; i
<torture_numops
; i
++) {
5779 status
= cli_session_setup(
5781 password
, strlen(password
),
5782 password
, strlen(password
),
5784 if (!NT_STATUS_IS_OK(status
)) {
5785 d_printf("(%s) cli_session_setup failed: %s\n",
5786 __location__
, nt_errstr(status
));
5790 d_printf("\r%d ", (int)c
->vuid
);
5792 status
= cli_ulogoff(c
);
5793 if (!NT_STATUS_IS_OK(status
)) {
5794 d_printf("(%s) cli_ulogoff failed: %s\n",
5795 __location__
, nt_errstr(status
));
5804 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5805 uid_t uid
, gid_t gid
, const char *expected
)
5810 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5812 if (strcmp(subst
, expected
) != 0) {
5813 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5814 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5823 static void chain1_open_completion(struct tevent_req
*req
)
5827 status
= cli_open_recv(req
, &fnum
);
5830 d_printf("cli_open_recv returned %s: %d\n",
5832 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5835 static void chain1_write_completion(struct tevent_req
*req
)
5839 status
= cli_write_andx_recv(req
, &written
);
5842 d_printf("cli_write_andx_recv returned %s: %d\n",
5844 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5847 static void chain1_close_completion(struct tevent_req
*req
)
5850 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5852 status
= cli_close_recv(req
);
5857 d_printf("cli_close returned %s\n", nt_errstr(status
));
5860 static bool run_chain1(int dummy
)
5862 struct cli_state
*cli1
;
5863 struct event_context
*evt
= event_context_init(NULL
);
5864 struct tevent_req
*reqs
[3], *smbreqs
[3];
5866 const char *str
= "foobar";
5869 printf("starting chain1 test\n");
5870 if (!torture_open_connection(&cli1
, 0)) {
5874 cli_sockopt(cli1
, sockops
);
5876 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5877 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5878 if (reqs
[0] == NULL
) return false;
5879 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5882 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5883 (uint8_t *)str
, 0, strlen(str
)+1,
5884 smbreqs
, 1, &smbreqs
[1]);
5885 if (reqs
[1] == NULL
) return false;
5886 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5888 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5889 if (reqs
[2] == NULL
) return false;
5890 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5892 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5893 if (!NT_STATUS_IS_OK(status
)) {
5898 event_loop_once(evt
);
5901 torture_close_connection(cli1
);
5905 static void chain2_sesssetup_completion(struct tevent_req
*req
)
5908 status
= cli_session_setup_guest_recv(req
);
5909 d_printf("sesssetup returned %s\n", nt_errstr(status
));
5912 static void chain2_tcon_completion(struct tevent_req
*req
)
5914 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5916 status
= cli_tcon_andx_recv(req
);
5917 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
5921 static bool run_chain2(int dummy
)
5923 struct cli_state
*cli1
;
5924 struct event_context
*evt
= event_context_init(NULL
);
5925 struct tevent_req
*reqs
[2], *smbreqs
[2];
5929 printf("starting chain2 test\n");
5930 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
5931 port_to_use
, Undefined
, 0);
5932 if (!NT_STATUS_IS_OK(status
)) {
5936 cli_sockopt(cli1
, sockops
);
5938 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
5940 if (reqs
[0] == NULL
) return false;
5941 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
5943 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
5944 "?????", NULL
, 0, &smbreqs
[1]);
5945 if (reqs
[1] == NULL
) return false;
5946 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
5948 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5949 if (!NT_STATUS_IS_OK(status
)) {
5954 event_loop_once(evt
);
5957 torture_close_connection(cli1
);
5962 struct torture_createdel_state
{
5963 struct tevent_context
*ev
;
5964 struct cli_state
*cli
;
5967 static void torture_createdel_created(struct tevent_req
*subreq
);
5968 static void torture_createdel_closed(struct tevent_req
*subreq
);
5970 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
5971 struct tevent_context
*ev
,
5972 struct cli_state
*cli
,
5975 struct tevent_req
*req
, *subreq
;
5976 struct torture_createdel_state
*state
;
5978 req
= tevent_req_create(mem_ctx
, &state
,
5979 struct torture_createdel_state
);
5986 subreq
= cli_ntcreate_send(
5987 state
, ev
, cli
, name
, 0,
5988 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5989 FILE_ATTRIBUTE_NORMAL
,
5990 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5991 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
5993 if (tevent_req_nomem(subreq
, req
)) {
5994 return tevent_req_post(req
, ev
);
5996 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6000 static void torture_createdel_created(struct tevent_req
*subreq
)
6002 struct tevent_req
*req
= tevent_req_callback_data(
6003 subreq
, struct tevent_req
);
6004 struct torture_createdel_state
*state
= tevent_req_data(
6005 req
, struct torture_createdel_state
);
6009 status
= cli_ntcreate_recv(subreq
, &fnum
);
6010 TALLOC_FREE(subreq
);
6011 if (!NT_STATUS_IS_OK(status
)) {
6012 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6013 nt_errstr(status
)));
6014 tevent_req_nterror(req
, status
);
6018 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6019 if (tevent_req_nomem(subreq
, req
)) {
6022 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6025 static void torture_createdel_closed(struct tevent_req
*subreq
)
6027 struct tevent_req
*req
= tevent_req_callback_data(
6028 subreq
, struct tevent_req
);
6031 status
= cli_close_recv(subreq
);
6032 if (!NT_STATUS_IS_OK(status
)) {
6033 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6034 tevent_req_nterror(req
, status
);
6037 tevent_req_done(req
);
6040 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6042 return tevent_req_simple_recv_ntstatus(req
);
6045 struct torture_createdels_state
{
6046 struct tevent_context
*ev
;
6047 struct cli_state
*cli
;
6048 const char *base_name
;
6052 struct tevent_req
**reqs
;
6055 static void torture_createdels_done(struct tevent_req
*subreq
);
6057 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6058 struct tevent_context
*ev
,
6059 struct cli_state
*cli
,
6060 const char *base_name
,
6064 struct tevent_req
*req
;
6065 struct torture_createdels_state
*state
;
6068 req
= tevent_req_create(mem_ctx
, &state
,
6069 struct torture_createdels_state
);
6075 state
->base_name
= talloc_strdup(state
, base_name
);
6076 if (tevent_req_nomem(state
->base_name
, req
)) {
6077 return tevent_req_post(req
, ev
);
6079 state
->num_files
= MAX(num_parallel
, num_files
);
6081 state
->received
= 0;
6083 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6084 if (tevent_req_nomem(state
->reqs
, req
)) {
6085 return tevent_req_post(req
, ev
);
6088 for (i
=0; i
<num_parallel
; i
++) {
6091 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6093 if (tevent_req_nomem(name
, req
)) {
6094 return tevent_req_post(req
, ev
);
6096 state
->reqs
[i
] = torture_createdel_send(
6097 state
->reqs
, state
->ev
, state
->cli
, name
);
6098 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6099 return tevent_req_post(req
, ev
);
6101 name
= talloc_move(state
->reqs
[i
], &name
);
6102 tevent_req_set_callback(state
->reqs
[i
],
6103 torture_createdels_done
, req
);
6109 static void torture_createdels_done(struct tevent_req
*subreq
)
6111 struct tevent_req
*req
= tevent_req_callback_data(
6112 subreq
, struct tevent_req
);
6113 struct torture_createdels_state
*state
= tevent_req_data(
6114 req
, struct torture_createdels_state
);
6115 size_t num_parallel
= talloc_array_length(state
->reqs
);
6120 status
= torture_createdel_recv(subreq
);
6121 if (!NT_STATUS_IS_OK(status
)){
6122 DEBUG(10, ("torture_createdel_recv returned %s\n",
6123 nt_errstr(status
)));
6124 TALLOC_FREE(subreq
);
6125 tevent_req_nterror(req
, status
);
6129 for (i
=0; i
<num_parallel
; i
++) {
6130 if (subreq
== state
->reqs
[i
]) {
6134 if (i
== num_parallel
) {
6135 DEBUG(10, ("received something we did not send\n"));
6136 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6139 TALLOC_FREE(state
->reqs
[i
]);
6141 if (state
->sent
>= state
->num_files
) {
6142 tevent_req_done(req
);
6146 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6148 if (tevent_req_nomem(name
, req
)) {
6151 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6153 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6156 name
= talloc_move(state
->reqs
[i
], &name
);
6157 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6161 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6163 return tevent_req_simple_recv_ntstatus(req
);
6166 struct swallow_notify_state
{
6167 struct tevent_context
*ev
;
6168 struct cli_state
*cli
;
6170 uint32_t completion_filter
;
6172 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6176 static void swallow_notify_done(struct tevent_req
*subreq
);
6178 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6179 struct tevent_context
*ev
,
6180 struct cli_state
*cli
,
6182 uint32_t completion_filter
,
6184 bool (*fn
)(uint32_t action
,
6189 struct tevent_req
*req
, *subreq
;
6190 struct swallow_notify_state
*state
;
6192 req
= tevent_req_create(mem_ctx
, &state
,
6193 struct swallow_notify_state
);
6200 state
->completion_filter
= completion_filter
;
6201 state
->recursive
= recursive
;
6205 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6206 0xffff, state
->completion_filter
,
6208 if (tevent_req_nomem(subreq
, req
)) {
6209 return tevent_req_post(req
, ev
);
6211 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6215 static void swallow_notify_done(struct tevent_req
*subreq
)
6217 struct tevent_req
*req
= tevent_req_callback_data(
6218 subreq
, struct tevent_req
);
6219 struct swallow_notify_state
*state
= tevent_req_data(
6220 req
, struct swallow_notify_state
);
6222 uint32_t i
, num_changes
;
6223 struct notify_change
*changes
;
6225 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6226 TALLOC_FREE(subreq
);
6227 if (!NT_STATUS_IS_OK(status
)) {
6228 DEBUG(10, ("cli_notify_recv returned %s\n",
6229 nt_errstr(status
)));
6230 tevent_req_nterror(req
, status
);
6234 for (i
=0; i
<num_changes
; i
++) {
6235 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6237 TALLOC_FREE(changes
);
6239 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6240 0xffff, state
->completion_filter
,
6242 if (tevent_req_nomem(subreq
, req
)) {
6245 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6248 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6250 if (DEBUGLEVEL
> 5) {
6251 d_printf("%d %s\n", (int)action
, name
);
6256 static void notify_bench_done(struct tevent_req
*req
)
6258 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6262 static bool run_notify_bench(int dummy
)
6264 const char *dname
= "\\notify-bench";
6265 struct tevent_context
*ev
;
6268 struct tevent_req
*req1
;
6269 struct tevent_req
*req2
= NULL
;
6270 int i
, num_unc_names
;
6271 int num_finished
= 0;
6273 printf("starting notify-bench test\n");
6275 if (use_multishare_conn
) {
6277 unc_list
= file_lines_load(multishare_conn_fname
,
6278 &num_unc_names
, 0, NULL
);
6279 if (!unc_list
|| num_unc_names
<= 0) {
6280 d_printf("Failed to load unc names list from '%s'\n",
6281 multishare_conn_fname
);
6284 TALLOC_FREE(unc_list
);
6289 ev
= tevent_context_init(talloc_tos());
6291 d_printf("tevent_context_init failed\n");
6295 for (i
=0; i
<num_unc_names
; i
++) {
6296 struct cli_state
*cli
;
6299 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6301 if (base_fname
== NULL
) {
6305 if (!torture_open_connection(&cli
, i
)) {
6309 status
= cli_ntcreate(cli
, dname
, 0,
6310 MAXIMUM_ALLOWED_ACCESS
,
6311 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6313 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6316 if (!NT_STATUS_IS_OK(status
)) {
6317 d_printf("Could not create %s: %s\n", dname
,
6322 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6323 FILE_NOTIFY_CHANGE_FILE_NAME
|
6324 FILE_NOTIFY_CHANGE_DIR_NAME
|
6325 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6326 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6327 false, print_notifies
, NULL
);
6329 d_printf("Could not create notify request\n");
6333 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6334 base_fname
, 10, torture_numops
);
6336 d_printf("Could not create createdels request\n");
6339 TALLOC_FREE(base_fname
);
6341 tevent_req_set_callback(req2
, notify_bench_done
,
6345 while (num_finished
< num_unc_names
) {
6347 ret
= tevent_loop_once(ev
);
6349 d_printf("tevent_loop_once failed\n");
6354 if (!tevent_req_poll(req2
, ev
)) {
6355 d_printf("tevent_req_poll failed\n");
6358 status
= torture_createdels_recv(req2
);
6359 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
6364 static bool run_mangle1(int dummy
)
6366 struct cli_state
*cli
;
6367 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
6371 time_t change_time
, access_time
, write_time
;
6375 printf("starting mangle1 test\n");
6376 if (!torture_open_connection(&cli
, 0)) {
6380 cli_sockopt(cli
, sockops
);
6382 if (!NT_STATUS_IS_OK(cli_ntcreate(
6383 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6384 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6385 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
6388 cli_close(cli
, fnum
);
6390 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
6391 if (!NT_STATUS_IS_OK(status
)) {
6392 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6396 d_printf("alt_name: %s\n", alt_name
);
6398 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
6399 d_printf("cli_open(%s) failed: %s\n", alt_name
,
6403 cli_close(cli
, fnum
);
6405 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
6406 &write_time
, &size
, &mode
);
6407 if (!NT_STATUS_IS_OK(status
)) {
6408 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
6416 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
6418 size_t *to_pull
= (size_t *)priv
;
6419 size_t thistime
= *to_pull
;
6421 thistime
= MIN(thistime
, n
);
6422 if (thistime
== 0) {
6426 memset(buf
, 0, thistime
);
6427 *to_pull
-= thistime
;
6431 static bool run_windows_write(int dummy
)
6433 struct cli_state
*cli1
;
6437 const char *fname
= "\\writetest.txt";
6438 struct timeval start_time
;
6442 printf("starting windows_write test\n");
6443 if (!torture_open_connection(&cli1
, 0)) {
6447 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
6448 printf("open failed (%s)\n", cli_errstr(cli1
));
6452 cli_sockopt(cli1
, sockops
);
6454 start_time
= timeval_current();
6456 for (i
=0; i
<torture_numops
; i
++) {
6458 off_t start
= i
* torture_blocksize
;
6460 size_t to_pull
= torture_blocksize
- 1;
6462 if (cli_write(cli1
, fnum
, 0, &c
,
6463 start
+ torture_blocksize
- 1, 1) != 1) {
6464 printf("cli_write failed: %s\n", cli_errstr(cli1
));
6468 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6469 null_source
, &to_pull
);
6470 if (!NT_STATUS_IS_OK(status
)) {
6471 printf("cli_push returned: %s\n", nt_errstr(status
));
6476 seconds
= timeval_elapsed(&start_time
);
6477 kbytes
= (double)torture_blocksize
* torture_numops
;
6480 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6481 (double)seconds
, (int)(kbytes
/seconds
));
6485 cli_close(cli1
, fnum
);
6486 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6487 torture_close_connection(cli1
);
6491 static bool run_cli_echo(int dummy
)
6493 struct cli_state
*cli
;
6496 printf("starting cli_echo test\n");
6497 if (!torture_open_connection(&cli
, 0)) {
6500 cli_sockopt(cli
, sockops
);
6502 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6504 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6506 torture_close_connection(cli
);
6507 return NT_STATUS_IS_OK(status
);
6510 static bool run_uid_regression_test(int dummy
)
6512 static struct cli_state
*cli
;
6515 bool correct
= True
;
6518 printf("starting uid regression test\n");
6520 if (!torture_open_connection(&cli
, 0)) {
6524 cli_sockopt(cli
, sockops
);
6526 /* Ok - now save then logoff our current user. */
6527 old_vuid
= cli
->vuid
;
6529 status
= cli_ulogoff(cli
);
6530 if (!NT_STATUS_IS_OK(status
)) {
6531 d_printf("(%s) cli_ulogoff failed: %s\n",
6532 __location__
, nt_errstr(status
));
6537 cli
->vuid
= old_vuid
;
6539 /* Try an operation. */
6540 status
= cli_mkdir(cli
, "\\uid_reg_test");
6541 if (NT_STATUS_IS_OK(status
)) {
6542 d_printf("(%s) cli_mkdir succeeded\n",
6547 /* Should be bad uid. */
6548 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6549 NT_STATUS_USER_SESSION_DELETED
)) {
6555 old_cnum
= cli
->cnum
;
6557 /* Now try a SMBtdis with the invald vuid set to zero. */
6560 /* This should succeed. */
6561 status
= cli_tdis(cli
);
6563 if (NT_STATUS_IS_OK(status
)) {
6564 d_printf("First tdis with invalid vuid should succeed.\n");
6566 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
6571 cli
->vuid
= old_vuid
;
6572 cli
->cnum
= old_cnum
;
6574 /* This should fail. */
6575 status
= cli_tdis(cli
);
6576 if (NT_STATUS_IS_OK(status
)) {
6577 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6581 /* Should be bad tid. */
6582 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6583 NT_STATUS_NETWORK_NAME_DELETED
)) {
6589 cli_rmdir(cli
, "\\uid_reg_test");
6598 static const char *illegal_chars
= "*\\/?<>|\":";
6599 static char force_shortname_chars
[] = " +,.[];=\177";
6601 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
6602 const char *mask
, void *state
)
6604 struct cli_state
*pcli
= (struct cli_state
*)state
;
6606 NTSTATUS status
= NT_STATUS_OK
;
6608 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6610 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6611 return NT_STATUS_OK
;
6613 if (finfo
->mode
& aDIR
) {
6614 status
= cli_rmdir(pcli
, fname
);
6615 if (!NT_STATUS_IS_OK(status
)) {
6616 printf("del_fn: failed to rmdir %s\n,", fname
);
6619 status
= cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
);
6620 if (!NT_STATUS_IS_OK(status
)) {
6621 printf("del_fn: failed to unlink %s\n,", fname
);
6633 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
6634 const char *name
, void *state
)
6636 struct sn_state
*s
= (struct sn_state
*)state
;
6640 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6641 i
, finfo
->name
, finfo
->short_name
);
6644 if (strchr(force_shortname_chars
, i
)) {
6645 if (!finfo
->short_name
[0]) {
6646 /* Shortname not created when it should be. */
6647 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6648 __location__
, finfo
->name
, i
);
6651 } else if (finfo
->short_name
[0]){
6652 /* Shortname created when it should not be. */
6653 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6654 __location__
, finfo
->short_name
, finfo
->name
);
6658 return NT_STATUS_OK
;
6661 static bool run_shortname_test(int dummy
)
6663 static struct cli_state
*cli
;
6664 bool correct
= True
;
6669 printf("starting shortname test\n");
6671 if (!torture_open_connection(&cli
, 0)) {
6675 cli_sockopt(cli
, sockops
);
6677 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6678 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6679 cli_rmdir(cli
, "\\shortname");
6681 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6682 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6683 __location__
, cli_errstr(cli
));
6688 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6689 strlcat(fname
, "test .txt", sizeof(fname
));
6693 for (i
= 32; i
< 128; i
++) {
6695 uint16_t fnum
= (uint16_t)-1;
6699 if (strchr(illegal_chars
, i
)) {
6704 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6705 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6706 if (!NT_STATUS_IS_OK(status
)) {
6707 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6708 __location__
, fname
, cli_errstr(cli
));
6712 cli_close(cli
, fnum
);
6715 cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
,
6717 if (s
.matched
!= 1) {
6718 d_printf("(%s) failed to list %s: %s\n",
6719 __location__
, fname
, cli_errstr(cli
));
6723 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6724 d_printf("(%s) failed to delete %s: %s\n",
6725 __location__
, fname
, cli_errstr(cli
));
6738 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6739 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6740 cli_rmdir(cli
, "\\shortname");
6741 torture_close_connection(cli
);
6745 static void pagedsearch_cb(struct tevent_req
*req
)
6748 struct tldap_message
*msg
;
6751 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6752 if (rc
!= TLDAP_SUCCESS
) {
6753 d_printf("tldap_search_paged_recv failed: %s\n",
6754 tldap_err2string(rc
));
6757 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6761 if (!tldap_entry_dn(msg
, &dn
)) {
6762 d_printf("tldap_entry_dn failed\n");
6765 d_printf("%s\n", dn
);
6769 static bool run_tldap(int dummy
)
6771 struct tldap_context
*ld
;
6774 struct sockaddr_storage addr
;
6775 struct tevent_context
*ev
;
6776 struct tevent_req
*req
;
6780 if (!resolve_name(host
, &addr
, 0, false)) {
6781 d_printf("could not find host %s\n", host
);
6784 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6785 if (!NT_STATUS_IS_OK(status
)) {
6786 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6790 ld
= tldap_context_create(talloc_tos(), fd
);
6793 d_printf("tldap_context_create failed\n");
6797 rc
= tldap_fetch_rootdse(ld
);
6798 if (rc
!= TLDAP_SUCCESS
) {
6799 d_printf("tldap_fetch_rootdse failed: %s\n",
6800 tldap_errstr(talloc_tos(), ld
, rc
));
6804 basedn
= tldap_talloc_single_attribute(
6805 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6806 if (basedn
== NULL
) {
6807 d_printf("no defaultNamingContext\n");
6810 d_printf("defaultNamingContext: %s\n", basedn
);
6812 ev
= tevent_context_init(talloc_tos());
6814 d_printf("tevent_context_init failed\n");
6818 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6819 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6821 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6823 d_printf("tldap_search_paged_send failed\n");
6826 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6828 tevent_req_poll(req
, ev
);
6832 /* test search filters against rootDSE */
6833 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6834 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6836 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
6837 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
6838 talloc_tos(), NULL
, NULL
);
6839 if (rc
!= TLDAP_SUCCESS
) {
6840 d_printf("tldap_search with complex filter failed: %s\n",
6841 tldap_errstr(talloc_tos(), ld
, rc
));
6849 /* Torture test to ensure no regression of :
6850 https://bugzilla.samba.org/show_bug.cgi?id=7084
6853 static bool run_dir_createtime(int dummy
)
6855 struct cli_state
*cli
;
6856 const char *dname
= "\\testdir";
6857 const char *fname
= "\\testdir\\testfile";
6859 struct timespec create_time
;
6860 struct timespec create_time1
;
6864 if (!torture_open_connection(&cli
, 0)) {
6868 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6869 cli_rmdir(cli
, dname
);
6871 status
= cli_mkdir(cli
, dname
);
6872 if (!NT_STATUS_IS_OK(status
)) {
6873 printf("mkdir failed: %s\n", nt_errstr(status
));
6877 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
6879 if (!NT_STATUS_IS_OK(status
)) {
6880 printf("cli_qpathinfo2 returned %s\n",
6885 /* Sleep 3 seconds, then create a file. */
6888 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
6890 if (!NT_STATUS_IS_OK(status
)) {
6891 printf("cli_open failed: %s\n", nt_errstr(status
));
6895 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
6897 if (!NT_STATUS_IS_OK(status
)) {
6898 printf("cli_qpathinfo2 (2) returned %s\n",
6903 if (timespec_compare(&create_time1
, &create_time
)) {
6904 printf("run_dir_createtime: create time was updated (error)\n");
6906 printf("run_dir_createtime: create time was not updated (correct)\n");
6912 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6913 cli_rmdir(cli
, dname
);
6914 if (!torture_close_connection(cli
)) {
6921 static bool run_streamerror(int dummy
)
6923 struct cli_state
*cli
;
6924 const char *dname
= "\\testdir";
6925 const char *streamname
=
6926 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6928 time_t change_time
, access_time
, write_time
;
6930 uint16_t mode
, fnum
;
6933 if (!torture_open_connection(&cli
, 0)) {
6937 cli_unlink(cli
, "\\testdir\\*", aSYSTEM
| aHIDDEN
);
6938 cli_rmdir(cli
, dname
);
6940 status
= cli_mkdir(cli
, dname
);
6941 if (!NT_STATUS_IS_OK(status
)) {
6942 printf("mkdir failed: %s\n", nt_errstr(status
));
6946 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
6948 status
= cli_nt_error(cli
);
6950 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6951 printf("pathinfo returned %s, expected "
6952 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6957 status
= cli_ntcreate(cli
, streamname
, 0x16,
6958 FILE_READ_DATA
|FILE_READ_EA
|
6959 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
6960 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6961 FILE_OPEN
, 0, 0, &fnum
);
6963 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6964 printf("ntcreate returned %s, expected "
6965 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6971 cli_rmdir(cli
, dname
);
6975 static bool run_local_substitute(int dummy
)
6979 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
6980 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6981 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6982 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6983 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
6984 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
6985 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6986 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6988 /* Different captialization rules in sub_basic... */
6990 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6996 static bool run_local_base64(int dummy
)
7001 for (i
=1; i
<2000; i
++) {
7002 DATA_BLOB blob1
, blob2
;
7005 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7007 generate_random_buffer(blob1
.data
, blob1
.length
);
7009 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7011 d_fprintf(stderr
, "base64_encode_data_blob failed "
7012 "for %d bytes\n", i
);
7015 blob2
= base64_decode_data_blob(b64
);
7018 if (data_blob_cmp(&blob1
, &blob2
)) {
7019 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7023 TALLOC_FREE(blob1
.data
);
7024 data_blob_free(&blob2
);
7029 static bool run_local_gencache(int dummy
)
7035 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7036 d_printf("%s: gencache_set() failed\n", __location__
);
7040 if (!gencache_get("foo", NULL
, NULL
)) {
7041 d_printf("%s: gencache_get() failed\n", __location__
);
7045 if (!gencache_get("foo", &val
, &tm
)) {
7046 d_printf("%s: gencache_get() failed\n", __location__
);
7050 if (strcmp(val
, "bar") != 0) {
7051 d_printf("%s: gencache_get() returned %s, expected %s\n",
7052 __location__
, val
, "bar");
7059 if (!gencache_del("foo")) {
7060 d_printf("%s: gencache_del() failed\n", __location__
);
7063 if (gencache_del("foo")) {
7064 d_printf("%s: second gencache_del() succeeded\n",
7069 if (gencache_get("foo", &val
, &tm
)) {
7070 d_printf("%s: gencache_get() on deleted entry "
7071 "succeeded\n", __location__
);
7075 blob
= data_blob_string_const_null("bar");
7076 tm
= time(NULL
) + 60;
7078 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7079 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7083 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7084 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7088 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7089 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7090 __location__
, (const char *)blob
.data
, "bar");
7091 data_blob_free(&blob
);
7095 data_blob_free(&blob
);
7097 if (!gencache_del("foo")) {
7098 d_printf("%s: gencache_del() failed\n", __location__
);
7101 if (gencache_del("foo")) {
7102 d_printf("%s: second gencache_del() succeeded\n",
7107 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7108 d_printf("%s: gencache_get_data_blob() on deleted entry "
7109 "succeeded\n", __location__
);
7116 static bool rbt_testval(struct db_context
*db
, const char *key
,
7119 struct db_record
*rec
;
7120 TDB_DATA data
= string_tdb_data(value
);
7124 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7126 d_fprintf(stderr
, "fetch_locked failed\n");
7129 status
= rec
->store(rec
, data
, 0);
7130 if (!NT_STATUS_IS_OK(status
)) {
7131 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7136 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7138 d_fprintf(stderr
, "second fetch_locked failed\n");
7141 if ((rec
->value
.dsize
!= data
.dsize
)
7142 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7143 d_fprintf(stderr
, "Got wrong data back\n");
7153 static bool run_local_rbtree(int dummy
)
7155 struct db_context
*db
;
7159 db
= db_open_rbt(NULL
);
7162 d_fprintf(stderr
, "db_open_rbt failed\n");
7166 for (i
=0; i
<1000; i
++) {
7169 if (asprintf(&key
, "key%ld", random()) == -1) {
7172 if (asprintf(&value
, "value%ld", random()) == -1) {
7177 if (!rbt_testval(db
, key
, value
)) {
7184 if (asprintf(&value
, "value%ld", random()) == -1) {
7189 if (!rbt_testval(db
, key
, value
)) {
7206 struct talloc_dict_test
{
7210 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7212 int *count
= (int *)priv
;
7217 static bool run_local_talloc_dict(int dummy
)
7219 struct talloc_dict
*dict
;
7220 struct talloc_dict_test
*t
;
7223 dict
= talloc_dict_init(talloc_tos());
7228 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7235 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7240 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
7253 static bool run_local_string_to_sid(int dummy
) {
7256 if (string_to_sid(&sid
, "S--1-5-32-545")) {
7257 printf("allowing S--1-5-32-545\n");
7260 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
7261 printf("allowing S-1-5-32-+545\n");
7264 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")) {
7265 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7268 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
7269 printf("allowing S-1-5-32-545-abc\n");
7272 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
7273 printf("could not parse S-1-5-32-545\n");
7276 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
7277 printf("mis-parsed S-1-5-32-545 as %s\n",
7278 sid_string_tos(&sid
));
7284 static bool run_local_binary_to_sid(int dummy
) {
7285 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
7286 static const char good_binary_sid
[] = {
7287 0x1, /* revision number */
7289 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7290 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7291 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7292 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7293 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7294 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7295 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7296 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7297 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7298 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7299 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7300 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7301 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7302 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7303 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7304 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7307 static const char long_binary_sid
[] = {
7308 0x1, /* revision number */
7310 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7311 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7312 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7313 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7314 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7315 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7316 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7317 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7318 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7319 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7320 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7321 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7322 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7323 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7324 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7325 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7326 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7327 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7328 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7331 static const char long_binary_sid2
[] = {
7332 0x1, /* revision number */
7334 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7335 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7336 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7337 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7338 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7339 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7340 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7341 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7342 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7343 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7344 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7345 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7359 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7360 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7361 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7362 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7363 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7364 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7365 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7366 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7369 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
7372 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
7375 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
7381 /* Split a path name into filename and stream name components. Canonicalise
7382 * such that an implicit $DATA token is always explicit.
7384 * The "specification" of this function can be found in the
7385 * run_local_stream_name() function in torture.c, I've tried those
7386 * combinations against a W2k3 server.
7389 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
7390 char **pbase
, char **pstream
)
7393 char *stream
= NULL
;
7394 char *sname
; /* stream name */
7395 const char *stype
; /* stream type */
7397 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
7399 sname
= strchr_m(fname
, ':');
7401 if (lp_posix_pathnames() || (sname
== NULL
)) {
7402 if (pbase
!= NULL
) {
7403 base
= talloc_strdup(mem_ctx
, fname
);
7404 NT_STATUS_HAVE_NO_MEMORY(base
);
7409 if (pbase
!= NULL
) {
7410 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
7411 NT_STATUS_HAVE_NO_MEMORY(base
);
7416 stype
= strchr_m(sname
, ':');
7418 if (stype
== NULL
) {
7419 sname
= talloc_strdup(mem_ctx
, sname
);
7423 if (StrCaseCmp(stype
, ":$DATA") != 0) {
7425 * If there is an explicit stream type, so far we only
7426 * allow $DATA. Is there anything else allowed? -- vl
7428 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
7430 return NT_STATUS_OBJECT_NAME_INVALID
;
7432 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
7436 if (sname
== NULL
) {
7438 return NT_STATUS_NO_MEMORY
;
7441 if (sname
[0] == '\0') {
7443 * no stream name, so no stream
7448 if (pstream
!= NULL
) {
7449 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
7450 if (stream
== NULL
) {
7453 return NT_STATUS_NO_MEMORY
;
7456 * upper-case the type field
7458 strupper_m(strchr_m(stream
, ':')+1);
7462 if (pbase
!= NULL
) {
7465 if (pstream
!= NULL
) {
7468 return NT_STATUS_OK
;
7471 static bool test_stream_name(const char *fname
, const char *expected_base
,
7472 const char *expected_stream
,
7473 NTSTATUS expected_status
)
7477 char *stream
= NULL
;
7479 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
7480 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
7484 if (!NT_STATUS_IS_OK(status
)) {
7488 if (base
== NULL
) goto error
;
7490 if (strcmp(expected_base
, base
) != 0) goto error
;
7492 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
7493 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
7495 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
7499 TALLOC_FREE(stream
);
7503 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
7504 fname
, expected_base
? expected_base
: "<NULL>",
7505 expected_stream
? expected_stream
: "<NULL>",
7506 nt_errstr(expected_status
));
7507 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
7508 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
7511 TALLOC_FREE(stream
);
7515 static bool run_local_stream_name(int dummy
)
7519 ret
&= test_stream_name(
7520 "bla", "bla", NULL
, NT_STATUS_OK
);
7521 ret
&= test_stream_name(
7522 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
7523 ret
&= test_stream_name(
7524 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7525 ret
&= test_stream_name(
7526 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7527 ret
&= test_stream_name(
7528 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7529 ret
&= test_stream_name(
7530 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
7531 ret
&= test_stream_name(
7532 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
7533 ret
&= test_stream_name(
7534 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
7539 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
7541 if (a
.length
!= b
.length
) {
7542 printf("a.length=%d != b.length=%d\n",
7543 (int)a
.length
, (int)b
.length
);
7546 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
7547 printf("a.data and b.data differ\n");
7553 static bool run_local_memcache(int dummy
)
7555 struct memcache
*cache
;
7557 DATA_BLOB d1
, d2
, d3
;
7558 DATA_BLOB v1
, v2
, v3
;
7560 TALLOC_CTX
*mem_ctx
;
7562 size_t size1
, size2
;
7565 cache
= memcache_init(NULL
, 100);
7567 if (cache
== NULL
) {
7568 printf("memcache_init failed\n");
7572 d1
= data_blob_const("d1", 2);
7573 d2
= data_blob_const("d2", 2);
7574 d3
= data_blob_const("d3", 2);
7576 k1
= data_blob_const("d1", 2);
7577 k2
= data_blob_const("d2", 2);
7579 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
7580 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
7582 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
7583 printf("could not find k1\n");
7586 if (!data_blob_equal(d1
, v1
)) {
7590 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7591 printf("could not find k2\n");
7594 if (!data_blob_equal(d2
, v2
)) {
7598 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
7600 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
7601 printf("could not find replaced k1\n");
7604 if (!data_blob_equal(d3
, v3
)) {
7608 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
7610 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7611 printf("Did find k2, should have been purged\n");
7617 cache
= memcache_init(NULL
, 0);
7619 mem_ctx
= talloc_init("foo");
7621 str1
= talloc_strdup(mem_ctx
, "string1");
7622 str2
= talloc_strdup(mem_ctx
, "string2");
7624 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7625 data_blob_string_const("torture"), &str1
);
7626 size1
= talloc_total_size(cache
);
7628 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7629 data_blob_string_const("torture"), &str2
);
7630 size2
= talloc_total_size(cache
);
7632 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
7634 if (size2
> size1
) {
7635 printf("memcache leaks memory!\n");
7645 static void wbclient_done(struct tevent_req
*req
)
7648 struct winbindd_response
*wb_resp
;
7649 int *i
= (int *)tevent_req_callback_data_void(req
);
7651 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
7654 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
7657 static bool run_local_wbclient(int dummy
)
7659 struct event_context
*ev
;
7660 struct wb_context
**wb_ctx
;
7661 struct winbindd_request wb_req
;
7662 bool result
= false;
7665 BlockSignals(True
, SIGPIPE
);
7667 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
7672 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
7673 if (wb_ctx
== NULL
) {
7677 ZERO_STRUCT(wb_req
);
7678 wb_req
.cmd
= WINBINDD_PING
;
7680 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
7682 for (i
=0; i
<nprocs
; i
++) {
7683 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
7684 if (wb_ctx
[i
] == NULL
) {
7687 for (j
=0; j
<torture_numops
; j
++) {
7688 struct tevent_req
*req
;
7689 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
7690 (j
% 2) == 0, &wb_req
);
7694 tevent_req_set_callback(req
, wbclient_done
, &i
);
7700 while (i
< nprocs
* torture_numops
) {
7701 event_loop_once(ev
);
7710 static void getaddrinfo_finished(struct tevent_req
*req
)
7712 char *name
= (char *)tevent_req_callback_data_void(req
);
7713 struct addrinfo
*ainfo
;
7716 res
= getaddrinfo_recv(req
, &ainfo
);
7718 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7721 d_printf("gai(%s) succeeded\n", name
);
7722 freeaddrinfo(ainfo
);
7725 static bool run_getaddrinfo_send(int dummy
)
7727 TALLOC_CTX
*frame
= talloc_stackframe();
7728 struct fncall_context
*ctx
;
7729 struct tevent_context
*ev
;
7730 bool result
= false;
7731 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7732 "www.slashdot.org", "heise.de" };
7733 struct tevent_req
*reqs
[4];
7736 ev
= event_context_init(frame
);
7741 ctx
= fncall_context_init(frame
, 4);
7743 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7744 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7746 if (reqs
[i
] == NULL
) {
7749 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7753 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7754 tevent_loop_once(ev
);
7763 static bool dbtrans_inc(struct db_context
*db
)
7765 struct db_record
*rec
;
7770 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7772 printf(__location__
"fetch_lock failed\n");
7776 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
7777 printf(__location__
"value.dsize = %d\n",
7778 (int)rec
->value
.dsize
);
7782 val
= (uint32_t *)rec
->value
.dptr
;
7785 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
7788 if (!NT_STATUS_IS_OK(status
)) {
7789 printf(__location__
"store failed: %s\n",
7800 static bool run_local_dbtrans(int dummy
)
7802 struct db_context
*db
;
7803 struct db_record
*rec
;
7808 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
7809 O_RDWR
|O_CREAT
, 0600);
7811 printf("Could not open transtest.db\n");
7815 res
= db
->transaction_start(db
);
7817 printf(__location__
"transaction_start failed\n");
7821 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7823 printf(__location__
"fetch_lock failed\n");
7827 if (rec
->value
.dptr
== NULL
) {
7829 status
= rec
->store(
7830 rec
, make_tdb_data((uint8_t *)&initial
,
7833 if (!NT_STATUS_IS_OK(status
)) {
7834 printf(__location__
"store returned %s\n",
7842 res
= db
->transaction_commit(db
);
7844 printf(__location__
"transaction_commit failed\n");
7852 res
= db
->transaction_start(db
);
7854 printf(__location__
"transaction_start failed\n");
7858 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
7859 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7863 for (i
=0; i
<10; i
++) {
7864 if (!dbtrans_inc(db
)) {
7869 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
7870 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7874 if (val2
!= val
+ 10) {
7875 printf(__location__
"val=%d, val2=%d\n",
7876 (int)val
, (int)val2
);
7880 printf("val2=%d\r", val2
);
7882 res
= db
->transaction_commit(db
);
7884 printf(__location__
"transaction_commit failed\n");
7894 * Just a dummy test to be run under a debugger. There's no real way
7895 * to inspect the tevent_select specific function from outside of
7899 static bool run_local_tevent_select(int dummy
)
7901 struct tevent_context
*ev
;
7902 struct tevent_fd
*fd1
, *fd2
;
7903 bool result
= false;
7905 ev
= tevent_context_init_byname(NULL
, "select");
7907 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
7911 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
7913 d_fprintf(stderr
, "tevent_add_fd failed\n");
7916 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
7918 d_fprintf(stderr
, "tevent_add_fd failed\n");
7923 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
7925 d_fprintf(stderr
, "tevent_add_fd failed\n");
7935 static double create_procs(bool (*fn
)(int), bool *result
)
7938 volatile pid_t
*child_status
;
7939 volatile bool *child_status_out
;
7942 struct timeval start
;
7946 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
7947 if (!child_status
) {
7948 printf("Failed to setup shared memory\n");
7952 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
7953 if (!child_status_out
) {
7954 printf("Failed to setup result status shared memory\n");
7958 for (i
= 0; i
< nprocs
; i
++) {
7959 child_status
[i
] = 0;
7960 child_status_out
[i
] = True
;
7963 start
= timeval_current();
7965 for (i
=0;i
<nprocs
;i
++) {
7968 pid_t mypid
= getpid();
7969 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
7971 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
7974 if (torture_open_connection(¤t_cli
, i
)) break;
7976 printf("pid %d failed to start\n", (int)getpid());
7982 child_status
[i
] = getpid();
7984 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
7986 child_status_out
[i
] = fn(i
);
7993 for (i
=0;i
<nprocs
;i
++) {
7994 if (child_status
[i
]) synccount
++;
7996 if (synccount
== nprocs
) break;
7998 } while (timeval_elapsed(&start
) < 30);
8000 if (synccount
!= nprocs
) {
8001 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8003 return timeval_elapsed(&start
);
8006 /* start the client load */
8007 start
= timeval_current();
8009 for (i
=0;i
<nprocs
;i
++) {
8010 child_status
[i
] = 0;
8013 printf("%d clients started\n", nprocs
);
8015 for (i
=0;i
<nprocs
;i
++) {
8016 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8021 for (i
=0;i
<nprocs
;i
++) {
8022 if (!child_status_out
[i
]) {
8026 return timeval_elapsed(&start
);
8029 #define FLAG_MULTIPROC 1
8036 {"FDPASS", run_fdpasstest
, 0},
8037 {"LOCK1", run_locktest1
, 0},
8038 {"LOCK2", run_locktest2
, 0},
8039 {"LOCK3", run_locktest3
, 0},
8040 {"LOCK4", run_locktest4
, 0},
8041 {"LOCK5", run_locktest5
, 0},
8042 {"LOCK6", run_locktest6
, 0},
8043 {"LOCK7", run_locktest7
, 0},
8044 {"LOCK8", run_locktest8
, 0},
8045 {"LOCK9", run_locktest9
, 0},
8046 {"UNLINK", run_unlinktest
, 0},
8047 {"BROWSE", run_browsetest
, 0},
8048 {"ATTR", run_attrtest
, 0},
8049 {"TRANS2", run_trans2test
, 0},
8050 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8051 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8052 {"RANDOMIPC", run_randomipc
, 0},
8053 {"NEGNOWAIT", run_negprot_nowait
, 0},
8054 {"NBENCH", run_nbench
, 0},
8055 {"NBENCH2", run_nbench2
, 0},
8056 {"OPLOCK1", run_oplock1
, 0},
8057 {"OPLOCK2", run_oplock2
, 0},
8058 {"OPLOCK3", run_oplock3
, 0},
8059 {"OPLOCK4", run_oplock4
, 0},
8060 {"DIR", run_dirtest
, 0},
8061 {"DIR1", run_dirtest1
, 0},
8062 {"DIR-CREATETIME", run_dir_createtime
, 0},
8063 {"DENY1", torture_denytest1
, 0},
8064 {"DENY2", torture_denytest2
, 0},
8065 {"TCON", run_tcon_test
, 0},
8066 {"TCONDEV", run_tcon_devtype_test
, 0},
8067 {"RW1", run_readwritetest
, 0},
8068 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8069 {"RW3", run_readwritelarge
, 0},
8070 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8071 {"OPEN", run_opentest
, 0},
8072 {"POSIX", run_simple_posix_open_test
, 0},
8073 {"POSIX-APPEND", run_posix_append
, 0},
8074 {"ASYNC-ECHO", run_async_echo
, 0},
8075 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8076 { "SHORTNAME-TEST", run_shortname_test
, 0},
8077 { "ADDRCHANGE", run_addrchange
, 0},
8079 {"OPENATTR", run_openattrtest
, 0},
8081 {"XCOPY", run_xcopy
, 0},
8082 {"RENAME", run_rename
, 0},
8083 {"DELETE", run_deletetest
, 0},
8084 {"DELETE-LN", run_deletetest_ln
, 0},
8085 {"PROPERTIES", run_properties
, 0},
8086 {"MANGLE", torture_mangle
, 0},
8087 {"MANGLE1", run_mangle1
, 0},
8088 {"W2K", run_w2ktest
, 0},
8089 {"TRANS2SCAN", torture_trans2_scan
, 0},
8090 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8091 {"UTABLE", torture_utable
, 0},
8092 {"CASETABLE", torture_casetable
, 0},
8093 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8094 {"PIPE_NUMBER", run_pipe_number
, 0},
8095 {"TCON2", run_tcon2_test
, 0},
8096 {"IOCTL", torture_ioctl_test
, 0},
8097 {"CHKPATH", torture_chkpath_test
, 0},
8098 {"FDSESS", run_fdsesstest
, 0},
8099 { "EATEST", run_eatest
, 0},
8100 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8101 { "CHAIN1", run_chain1
, 0},
8102 { "CHAIN2", run_chain2
, 0},
8103 { "WINDOWS-WRITE", run_windows_write
, 0},
8104 { "CLI_ECHO", run_cli_echo
, 0},
8105 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8106 { "TLDAP", run_tldap
},
8107 { "STREAMERROR", run_streamerror
},
8108 { "NOTIFY-BENCH", run_notify_bench
},
8109 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8110 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8111 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8112 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8113 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8114 { "LOCAL-BASE64", run_local_base64
, 0},
8115 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8116 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8117 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8118 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8119 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8120 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8121 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8122 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8127 /****************************************************************************
8128 run a specified test or "ALL"
8129 ****************************************************************************/
8130 static bool run_test(const char *name
)
8137 if (strequal(name
,"ALL")) {
8138 for (i
=0;torture_ops
[i
].name
;i
++) {
8139 run_test(torture_ops
[i
].name
);
8144 for (i
=0;torture_ops
[i
].name
;i
++) {
8145 fstr_sprintf(randomfname
, "\\XX%x",
8146 (unsigned)random());
8148 if (strequal(name
, torture_ops
[i
].name
)) {
8150 printf("Running %s\n", name
);
8151 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8152 t
= create_procs(torture_ops
[i
].fn
, &result
);
8155 printf("TEST %s FAILED!\n", name
);
8158 struct timeval start
;
8159 start
= timeval_current();
8160 if (!torture_ops
[i
].fn(0)) {
8162 printf("TEST %s FAILED!\n", name
);
8164 t
= timeval_elapsed(&start
);
8166 printf("%s took %g secs\n\n", name
, t
);
8171 printf("Did not find a test named %s\n", name
);
8179 static void usage(void)
8183 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8184 printf("Please use samba4 torture.\n\n");
8186 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8188 printf("\t-d debuglevel\n");
8189 printf("\t-U user%%pass\n");
8190 printf("\t-k use kerberos\n");
8191 printf("\t-N numprocs\n");
8192 printf("\t-n my_netbios_name\n");
8193 printf("\t-W workgroup\n");
8194 printf("\t-o num_operations\n");
8195 printf("\t-O socket_options\n");
8196 printf("\t-m maximum protocol\n");
8197 printf("\t-L use oplocks\n");
8198 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8199 printf("\t-A showall\n");
8200 printf("\t-p port\n");
8201 printf("\t-s seed\n");
8202 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8205 printf("tests are:");
8206 for (i
=0;torture_ops
[i
].name
;i
++) {
8207 printf(" %s", torture_ops
[i
].name
);
8211 printf("default test is ALL\n");
8216 /****************************************************************************
8218 ****************************************************************************/
8219 int main(int argc
,char *argv
[])
8225 bool correct
= True
;
8226 TALLOC_CTX
*frame
= talloc_stackframe();
8227 int seed
= time(NULL
);
8229 #ifdef HAVE_SETBUFFER
8230 setbuffer(stdout
, NULL
, 0);
8233 setup_logging("smbtorture", DEBUG_STDOUT
);
8237 if (is_default_dyn_CONFIGFILE()) {
8238 if(getenv("SMB_CONF_PATH")) {
8239 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8242 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
8249 for(p
= argv
[1]; *p
; p
++)
8253 if (strncmp(argv
[1], "//", 2)) {
8257 fstrcpy(host
, &argv
[1][2]);
8258 p
= strchr_m(&host
[2],'/');
8263 fstrcpy(share
, p
+1);
8265 fstrcpy(myname
, get_myname(talloc_tos()));
8267 fprintf(stderr
, "Failed to get my hostname.\n");
8271 if (*username
== 0 && getenv("LOGNAME")) {
8272 fstrcpy(username
,getenv("LOGNAME"));
8278 fstrcpy(workgroup
, lp_workgroup());
8280 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
8283 port_to_use
= atoi(optarg
);
8286 seed
= atoi(optarg
);
8289 fstrcpy(workgroup
,optarg
);
8292 max_protocol
= interpret_protocol(optarg
, max_protocol
);
8295 nprocs
= atoi(optarg
);
8298 torture_numops
= atoi(optarg
);
8301 lp_set_cmdline("log level", optarg
);
8310 local_path
= optarg
;
8313 torture_showall
= True
;
8316 fstrcpy(myname
, optarg
);
8319 client_txt
= optarg
;
8326 use_kerberos
= True
;
8328 d_printf("No kerberos support compiled in\n");
8334 fstrcpy(username
,optarg
);
8335 p
= strchr_m(username
,'%');
8338 fstrcpy(password
, p
+1);
8343 fstrcpy(multishare_conn_fname
, optarg
);
8344 use_multishare_conn
= True
;
8347 torture_blocksize
= atoi(optarg
);
8350 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
8355 d_printf("using seed %d\n", seed
);
8359 if(use_kerberos
&& !gotuser
) gotpass
= True
;
8362 p
= getpass("Password:");
8364 fstrcpy(password
, p
);
8369 printf("host=%s share=%s user=%s myname=%s\n",
8370 host
, share
, username
, myname
);
8372 if (argc
== optind
) {
8373 correct
= run_test("ALL");
8375 for (i
=optind
;i
<argc
;i
++) {
8376 if (!run_test(argv
[i
])) {