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 "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
36 #include "libsmb/nmblib.h"
41 static fstring host
, workgroup
, share
, password
, username
, myname
;
42 static int max_protocol
= PROTOCOL_NT1
;
43 static const char *sockops
="TCP_NODELAY";
45 static int port_to_use
=0;
46 int torture_numops
=100;
47 int torture_blocksize
=1024*1024;
48 static int procnum
; /* records process count number when forking */
49 static struct cli_state
*current_cli
;
50 static fstring randomfname
;
51 static bool use_oplocks
;
52 static bool use_level_II_oplocks
;
53 static const char *client_txt
= "client_oplocks.txt";
54 static bool use_kerberos
;
55 static fstring multishare_conn_fname
;
56 static bool use_multishare_conn
= False
;
57 static bool do_encrypt
;
58 static const char *local_path
= NULL
;
59 static int signing_state
= Undefined
;
61 bool torture_showall
= False
;
63 static double create_procs(bool (*fn
)(int), bool *result
);
66 /* return a pointer to a anonymous shared memory segment of size "size"
67 which will persist across fork() but will disappear when all processes
70 The memory is not zeroed
72 This function uses system5 shared memory. It takes advantage of a property
73 that the memory is not destroyed if it is attached when the id is removed
75 void *shm_setup(int size
)
81 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
83 printf("can't get shared memory\n");
86 shm_unlink("private");
87 if (ftruncate(shmid
, size
) == -1) {
88 printf("can't set shared memory size\n");
91 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
92 if (ret
== MAP_FAILED
) {
93 printf("can't map shared memory\n");
97 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
99 printf("can't get shared memory\n");
102 ret
= (void *)shmat(shmid
, 0, 0);
103 if (!ret
|| ret
== (void *)-1) {
104 printf("can't attach to shared memory\n");
107 /* the following releases the ipc, but note that this process
108 and all its children will still have access to the memory, its
109 just that the shmid is no longer valid for other shm calls. This
110 means we don't leave behind lots of shm segments after we exit
112 See Stevens "advanced programming in unix env" for details
114 shmctl(shmid
, IPC_RMID
, 0);
120 /********************************************************************
121 Ensure a connection is encrypted.
122 ********************************************************************/
124 static bool force_cli_encryption(struct cli_state
*c
,
125 const char *sharename
)
128 uint32 caplow
, caphigh
;
131 if (!SERVER_HAS_UNIX_CIFS(c
)) {
132 d_printf("Encryption required and "
133 "server that doesn't support "
134 "UNIX extensions - failing connect\n");
138 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
140 if (!NT_STATUS_IS_OK(status
)) {
141 d_printf("Encryption required and "
142 "can't get UNIX CIFS extensions "
143 "version from server: %s\n", nt_errstr(status
));
147 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
148 d_printf("Encryption required and "
149 "share %s doesn't support "
150 "encryption.\n", sharename
);
154 if (c
->use_kerberos
) {
155 status
= cli_gss_smb_encryption_start(c
);
157 status
= cli_raw_ntlm_smb_encryption_start(c
,
163 if (!NT_STATUS_IS_OK(status
)) {
164 d_printf("Encryption required and "
165 "setup failed with error %s.\n",
174 static struct cli_state
*open_nbt_connection(void)
176 struct nmb_name called
, calling
;
177 struct sockaddr_storage ss
;
181 make_nmb_name(&calling
, myname
, 0x0);
182 make_nmb_name(&called
, host
, 0x20);
186 if (!(c
= cli_initialise_ex(signing_state
))) {
187 printf("Failed initialize cli_struct to connect with %s\n", host
);
191 c
->port
= port_to_use
;
193 status
= cli_connect(c
, host
, &ss
);
194 if (!NT_STATUS_IS_OK(status
)) {
195 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
199 c
->use_kerberos
= use_kerberos
;
201 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
202 if (use_oplocks
) c
->use_oplocks
= True
;
203 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
205 if (!cli_session_request(c
, &calling
, &called
)) {
207 * Well, that failed, try *SMBSERVER ...
208 * However, we must reconnect as well ...
210 status
= cli_connect(c
, host
, &ss
);
211 if (!NT_STATUS_IS_OK(status
)) {
212 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
216 make_nmb_name(&called
, "*SMBSERVER", 0x20);
217 if (!cli_session_request(c
, &calling
, &called
)) {
218 printf("%s rejected the session\n",host
);
219 printf("We tried with a called name of %s & %s\n",
229 /****************************************************************************
230 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
231 ****************************************************************************/
233 static bool cli_bad_session_request(struct cli_state
*cli
,
234 struct nmb_name
*calling
, struct nmb_name
*called
)
241 memcpy(&(cli
->calling
), calling
, sizeof(*calling
));
242 memcpy(&(cli
->called
), called
, sizeof(*called
));
244 /* put in the destination name */
246 tmp
= name_mangle(talloc_tos(), cli
->called
.name
,
247 cli
->called
.name_type
);
253 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
255 memcpy(p
, tmp
, namelen
);
260 /* Deliberately corrupt the name len (first byte) */
265 tmp
= name_mangle(talloc_tos(), cli
->calling
.name
,
266 cli
->calling
.name_type
);
272 namelen
= name_len((unsigned char *)tmp
, talloc_get_size(tmp
));
274 memcpy(p
, tmp
, namelen
);
278 /* Deliberately corrupt the name len (first byte) */
281 /* send a session request (RFC 1002) */
282 /* setup the packet length
283 * Remove four bytes from the length count, since the length
284 * field in the NBT Session Service header counts the number
285 * of bytes which follow. The cli_send_smb() function knows
286 * about this and accounts for those four bytes.
290 _smb_setlen(cli
->outbuf
,len
);
291 SCVAL(cli
->outbuf
,0,0x81);
294 DEBUG(5,("Sent session request\n"));
296 if (!cli_receive_smb(cli
))
299 if (CVAL(cli
->inbuf
,0) != 0x82) {
300 /* This is the wrong place to put the error... JRA. */
301 cli
->rap_error
= CVAL(cli
->inbuf
,4);
307 static struct cli_state
*open_bad_nbt_connection(void)
309 struct nmb_name called
, calling
;
310 struct sockaddr_storage ss
;
314 make_nmb_name(&calling
, myname
, 0x0);
315 make_nmb_name(&called
, host
, 0x20);
319 if (!(c
= cli_initialise_ex(signing_state
))) {
320 printf("Failed initialize cli_struct to connect with %s\n", host
);
326 status
= cli_connect(c
, host
, &ss
);
327 if (!NT_STATUS_IS_OK(status
)) {
328 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
332 c
->timeout
= 4000; /* set a short timeout (4 seconds) */
334 if (!cli_bad_session_request(c
, &calling
, &called
)) {
335 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
343 /* Insert a NULL at the first separator of the given path and return a pointer
344 * to the remainder of the string.
347 terminate_path_at_separator(char * path
)
355 if ((p
= strchr_m(path
, '/'))) {
360 if ((p
= strchr_m(path
, '\\'))) {
370 parse a //server/share type UNC name
372 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
373 char **hostname
, char **sharename
)
377 *hostname
= *sharename
= NULL
;
379 if (strncmp(unc_name
, "\\\\", 2) &&
380 strncmp(unc_name
, "//", 2)) {
384 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
385 p
= terminate_path_at_separator(*hostname
);
388 *sharename
= talloc_strdup(mem_ctx
, p
);
389 terminate_path_at_separator(*sharename
);
392 if (*hostname
&& *sharename
) {
396 TALLOC_FREE(*hostname
);
397 TALLOC_FREE(*sharename
);
401 static bool torture_open_connection_share(struct cli_state
**c
,
402 const char *hostname
,
403 const char *sharename
)
409 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
411 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
412 if (use_level_II_oplocks
)
413 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
415 status
= cli_full_connection(c
, myname
,
416 hostname
, NULL
, port_to_use
,
419 password
, flags
, signing_state
);
420 if (!NT_STATUS_IS_OK(status
)) {
421 printf("failed to open share connection: //%s/%s port:%d - %s\n",
422 hostname
, sharename
, port_to_use
, nt_errstr(status
));
426 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
429 return force_cli_encryption(*c
,
435 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
437 char **unc_list
= NULL
;
438 int num_unc_names
= 0;
441 if (use_multishare_conn
==True
) {
443 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
444 if (!unc_list
|| num_unc_names
<= 0) {
445 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
449 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
451 printf("Failed to parse UNC name %s\n",
452 unc_list
[conn_index
% num_unc_names
]);
453 TALLOC_FREE(unc_list
);
457 result
= torture_open_connection_share(c
, h
, s
);
459 /* h, s were copied earlier */
460 TALLOC_FREE(unc_list
);
464 return torture_open_connection_share(c
, host
, share
);
467 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
469 uint16 old_vuid
= cli
->vuid
;
470 fstring old_user_name
;
471 size_t passlen
= strlen(password
);
475 fstrcpy(old_user_name
, cli
->user_name
);
477 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
481 *new_vuid
= cli
->vuid
;
482 cli
->vuid
= old_vuid
;
483 status
= cli_set_username(cli
, old_user_name
);
484 if (!NT_STATUS_IS_OK(status
)) {
491 bool torture_close_connection(struct cli_state
*c
)
496 status
= cli_tdis(c
);
497 if (!NT_STATUS_IS_OK(status
)) {
498 printf("tdis failed (%s)\n", nt_errstr(status
));
508 /* check if the server produced the expected error code */
509 static bool check_error(int line
, struct cli_state
*c
,
510 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
512 if (cli_is_dos_error(c
)) {
516 /* Check DOS error */
518 cli_dos_error(c
, &cclass
, &num
);
520 if (eclass
!= cclass
|| ecode
!= num
) {
521 printf("unexpected error code class=%d code=%d\n",
522 (int)cclass
, (int)num
);
523 printf(" expected %d/%d %s (line=%d)\n",
524 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
533 status
= cli_nt_error(c
);
535 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
536 printf("unexpected error code %s\n", nt_errstr(status
));
537 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
546 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
548 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
549 if (!check_error(__LINE__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
555 static bool rw_torture(struct cli_state
*c
)
557 const char *lockfname
= "\\torture.lck";
561 pid_t pid2
, pid
= getpid();
567 memset(buf
, '\0', sizeof(buf
));
569 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
571 if (!NT_STATUS_IS_OK(status
)) {
572 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
574 if (!NT_STATUS_IS_OK(status
)) {
575 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
579 for (i
=0;i
<torture_numops
;i
++) {
580 unsigned n
= (unsigned)sys_random()%10;
582 printf("%d\r", i
); fflush(stdout
);
584 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
586 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
590 if (!NT_STATUS_IS_OK(cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
, &fnum
))) {
591 printf("open failed (%s)\n", cli_errstr(c
));
596 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
597 printf("write failed (%s)\n", cli_errstr(c
));
602 if (cli_write(c
, fnum
, 0, (char *)buf
,
603 sizeof(pid
)+(j
*sizeof(buf
)),
604 sizeof(buf
)) != sizeof(buf
)) {
605 printf("write failed (%s)\n", cli_errstr(c
));
612 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
613 printf("read failed (%s)\n", cli_errstr(c
));
618 printf("data corruption!\n");
622 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
623 printf("close failed (%s)\n", cli_errstr(c
));
627 if (!NT_STATUS_IS_OK(cli_unlink(c
, fname
, aSYSTEM
| aHIDDEN
))) {
628 printf("unlink failed (%s)\n", cli_errstr(c
));
632 if (!NT_STATUS_IS_OK(cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int)))) {
633 printf("unlock failed (%s)\n", cli_errstr(c
));
639 cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
);
646 static bool run_torture(int dummy
)
648 struct cli_state
*cli
;
653 cli_sockopt(cli
, sockops
);
655 ret
= rw_torture(cli
);
657 if (!torture_close_connection(cli
)) {
664 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
666 uint16_t fnum
= (uint16_t)-1;
671 unsigned countprev
= 0;
674 NTSTATUS status
= NT_STATUS_OK
;
677 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
679 SIVAL(buf
, i
, sys_random());
684 if (!NT_STATUS_IS_OK(cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
))) {
685 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c
));
688 if (!NT_STATUS_IS_OK(cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
689 DENY_NONE
, &fnum
))) {
690 printf("first open read/write of %s failed (%s)\n",
691 lockfname
, cli_errstr(c
));
697 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
699 status
= cli_open(c
, lockfname
, O_RDONLY
,
701 if (!NT_STATUS_IS_OK(status
)) {
706 if (!NT_STATUS_IS_OK(status
)) {
707 printf("second open read-only of %s failed (%s)\n",
708 lockfname
, cli_errstr(c
));
714 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
716 if (count
>= countprev
) {
717 printf("%d %8d\r", i
, count
);
720 countprev
+= (sizeof(buf
) / 20);
725 sent
= ((unsigned)sys_random()%(20))+ 1;
726 if (sent
> sizeof(buf
) - count
)
728 sent
= sizeof(buf
) - count
;
731 if (cli_write(c
, fnum
, 0, buf
+count
, count
, (size_t)sent
) != sent
) {
732 printf("write failed (%s)\n", cli_errstr(c
));
738 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
742 printf("read failed offset:%d size:%ld (%s)\n",
743 count
, (unsigned long)sizeof(buf
)-count
,
750 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
752 printf("read/write compare failed\n");
753 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
762 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
763 printf("close failed (%s)\n", cli_errstr(c
));
770 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
772 const char *lockfname
= "\\torture2.lck";
781 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
782 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
785 if (!NT_STATUS_IS_OK(cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
786 DENY_NONE
, &fnum1
))) {
787 printf("first open read/write of %s failed (%s)\n",
788 lockfname
, cli_errstr(c1
));
791 if (!NT_STATUS_IS_OK(cli_open(c2
, lockfname
, O_RDONLY
,
792 DENY_NONE
, &fnum2
))) {
793 printf("second open read-only of %s failed (%s)\n",
794 lockfname
, cli_errstr(c2
));
795 cli_close(c1
, fnum1
);
799 for (i
=0;i
<torture_numops
;i
++)
801 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
803 printf("%d\r", i
); fflush(stdout
);
806 generate_random_buffer((unsigned char *)buf
, buf_size
);
808 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
809 printf("write failed (%s)\n", cli_errstr(c1
));
814 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
815 printf("read failed (%s)\n", cli_errstr(c2
));
816 printf("read %d, expected %ld\n", (int)bytes_read
,
817 (unsigned long)buf_size
);
822 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
824 printf("read/write compare failed\n");
830 if (!NT_STATUS_IS_OK(cli_close(c2
, fnum2
))) {
831 printf("close failed (%s)\n", cli_errstr(c2
));
834 if (!NT_STATUS_IS_OK(cli_close(c1
, fnum1
))) {
835 printf("close failed (%s)\n", cli_errstr(c1
));
839 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
840 printf("unlink failed (%s)\n", cli_errstr(c1
));
847 static bool run_readwritetest(int dummy
)
849 struct cli_state
*cli1
, *cli2
;
850 bool test1
, test2
= False
;
852 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
855 cli_sockopt(cli1
, sockops
);
856 cli_sockopt(cli2
, sockops
);
858 printf("starting readwritetest\n");
860 test1
= rw_torture2(cli1
, cli2
);
861 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
864 test2
= rw_torture2(cli1
, cli1
);
865 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
868 if (!torture_close_connection(cli1
)) {
872 if (!torture_close_connection(cli2
)) {
876 return (test1
&& test2
);
879 static bool run_readwritemulti(int dummy
)
881 struct cli_state
*cli
;
886 cli_sockopt(cli
, sockops
);
888 printf("run_readwritemulti: fname %s\n", randomfname
);
889 test
= rw_torture3(cli
, randomfname
);
891 if (!torture_close_connection(cli
)) {
898 static bool run_readwritelarge_internal(int max_xmit_k
)
900 static struct cli_state
*cli1
;
902 const char *lockfname
= "\\large.dat";
907 if (!torture_open_connection(&cli1
, 0)) {
910 cli_sockopt(cli1
, sockops
);
911 memset(buf
,'\0',sizeof(buf
));
913 cli1
->max_xmit
= max_xmit_k
*1024;
915 if (signing_state
== Required
) {
916 /* Horrible cheat to force
917 multiple signed outstanding
918 packets against a Samba server.
920 cli1
->is_samba
= false;
923 printf("starting readwritelarge_internal\n");
925 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
927 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
928 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
932 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
934 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
935 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
936 NULL
, NULL
, NULL
))) {
937 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
941 if (fsize
== sizeof(buf
))
942 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
943 (unsigned long)fsize
);
945 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
946 (unsigned long)fsize
);
950 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
951 printf("close failed (%s)\n", cli_errstr(cli1
));
955 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
956 printf("unlink failed (%s)\n", cli_errstr(cli1
));
960 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
961 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
965 cli1
->max_xmit
= 4*1024;
967 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
969 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
970 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
971 NULL
, NULL
, NULL
))) {
972 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
976 if (fsize
== sizeof(buf
))
977 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
978 (unsigned long)fsize
);
980 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
981 (unsigned long)fsize
);
986 /* ToDo - set allocation. JRA */
987 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
988 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
991 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
993 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
997 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1000 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1001 printf("close failed (%s)\n", cli_errstr(cli1
));
1005 if (!torture_close_connection(cli1
)) {
1011 static bool run_readwritelarge(int dummy
)
1013 return run_readwritelarge_internal(128);
1016 static bool run_readwritelarge_signtest(int dummy
)
1019 signing_state
= Required
;
1020 ret
= run_readwritelarge_internal(2);
1021 signing_state
= Undefined
;
1028 #define ival(s) strtol(s, NULL, 0)
1030 /* run a test that simulates an approximate netbench client load */
1031 static bool run_netbench(int client
)
1033 struct cli_state
*cli
;
1038 const char *params
[20];
1039 bool correct
= True
;
1045 cli_sockopt(cli
, sockops
);
1049 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1051 f
= fopen(client_txt
, "r");
1058 while (fgets(line
, sizeof(line
)-1, f
)) {
1062 line
[strlen(line
)-1] = 0;
1064 /* printf("[%d] %s\n", line_count, line); */
1066 all_string_sub(line
,"client1", cname
, sizeof(line
));
1068 /* parse the command parameters */
1069 params
[0] = strtok_r(line
, " ", &saveptr
);
1071 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1075 if (i
< 2) continue;
1077 if (!strncmp(params
[0],"SMB", 3)) {
1078 printf("ERROR: You are using a dbench 1 load file\n");
1082 if (!strcmp(params
[0],"NTCreateX")) {
1083 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1085 } else if (!strcmp(params
[0],"Close")) {
1086 nb_close(ival(params
[1]));
1087 } else if (!strcmp(params
[0],"Rename")) {
1088 nb_rename(params
[1], params
[2]);
1089 } else if (!strcmp(params
[0],"Unlink")) {
1090 nb_unlink(params
[1]);
1091 } else if (!strcmp(params
[0],"Deltree")) {
1092 nb_deltree(params
[1]);
1093 } else if (!strcmp(params
[0],"Rmdir")) {
1094 nb_rmdir(params
[1]);
1095 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1096 nb_qpathinfo(params
[1]);
1097 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1098 nb_qfileinfo(ival(params
[1]));
1099 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1100 nb_qfsinfo(ival(params
[1]));
1101 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1102 nb_findfirst(params
[1]);
1103 } else if (!strcmp(params
[0],"WriteX")) {
1104 nb_writex(ival(params
[1]),
1105 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1106 } else if (!strcmp(params
[0],"ReadX")) {
1107 nb_readx(ival(params
[1]),
1108 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1109 } else if (!strcmp(params
[0],"Flush")) {
1110 nb_flush(ival(params
[1]));
1112 printf("Unknown operation %s\n", params
[0]);
1120 if (!torture_close_connection(cli
)) {
1128 /* run a test that simulates an approximate netbench client load */
1129 static bool run_nbench(int dummy
)
1132 bool correct
= True
;
1138 signal(SIGALRM
, nb_alarm
);
1140 t
= create_procs(run_netbench
, &correct
);
1143 printf("\nThroughput %g MB/sec\n",
1144 1.0e-6 * nbio_total() / t
);
1150 This test checks for two things:
1152 1) correct support for retaining locks over a close (ie. the server
1153 must not use posix semantics)
1154 2) support for lock timeouts
1156 static bool run_locktest1(int dummy
)
1158 struct cli_state
*cli1
, *cli2
;
1159 const char *fname
= "\\lockt1.lck";
1160 uint16_t fnum1
, fnum2
, fnum3
;
1162 unsigned lock_timeout
;
1164 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1167 cli_sockopt(cli1
, sockops
);
1168 cli_sockopt(cli2
, sockops
);
1170 printf("starting locktest1\n");
1172 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1174 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1175 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1178 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1179 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1182 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1183 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1187 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1188 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1193 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1194 printf("lock2 succeeded! This is a locking bug\n");
1197 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1198 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1202 lock_timeout
= (1 + (random() % 20));
1203 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1205 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1206 printf("lock3 succeeded! This is a locking bug\n");
1209 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1210 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1214 if (ABS(t2
- t1
) < lock_timeout
-1) {
1215 printf("error: This server appears not to support timed lock requests\n");
1218 printf("server slept for %u seconds for a %u second timeout\n",
1219 (unsigned int)(t2
-t1
), lock_timeout
);
1221 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1222 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1226 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1227 printf("lock4 succeeded! This is a locking bug\n");
1230 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1231 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1234 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1235 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1239 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1240 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1244 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1245 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1250 if (!torture_close_connection(cli1
)) {
1254 if (!torture_close_connection(cli2
)) {
1258 printf("Passed locktest1\n");
1263 this checks to see if a secondary tconx can use open files from an
1266 static bool run_tcon_test(int dummy
)
1268 static struct cli_state
*cli
;
1269 const char *fname
= "\\tcontest.tmp";
1271 uint16 cnum1
, cnum2
, cnum3
;
1272 uint16 vuid1
, vuid2
;
1277 memset(buf
, '\0', sizeof(buf
));
1279 if (!torture_open_connection(&cli
, 0)) {
1282 cli_sockopt(cli
, sockops
);
1284 printf("starting tcontest\n");
1286 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1288 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1289 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1296 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1297 printf("initial write failed (%s)", cli_errstr(cli
));
1301 status
= cli_tcon_andx(cli
, share
, "?????",
1302 password
, strlen(password
)+1);
1303 if (!NT_STATUS_IS_OK(status
)) {
1304 printf("%s refused 2nd tree connect (%s)\n", host
,
1311 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1312 vuid2
= cli
->vuid
+ 1;
1314 /* try a write with the wrong tid */
1317 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1318 printf("* server allows write with wrong TID\n");
1321 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1325 /* try a write with an invalid tid */
1328 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1329 printf("* server allows write with invalid TID\n");
1332 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1335 /* try a write with an invalid vuid */
1339 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1340 printf("* server allows write with invalid VUID\n");
1343 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1349 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1350 printf("close failed (%s)\n", cli_errstr(cli
));
1356 status
= cli_tdis(cli
);
1357 if (!NT_STATUS_IS_OK(status
)) {
1358 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1364 if (!torture_close_connection(cli
)) {
1373 checks for old style tcon support
1375 static bool run_tcon2_test(int dummy
)
1377 static struct cli_state
*cli
;
1378 uint16 cnum
, max_xmit
;
1382 if (!torture_open_connection(&cli
, 0)) {
1385 cli_sockopt(cli
, sockops
);
1387 printf("starting tcon2 test\n");
1389 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1393 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1397 if (!NT_STATUS_IS_OK(status
)) {
1398 printf("tcon2 failed : %s\n", nt_errstr(status
));
1400 printf("tcon OK : max_xmit=%d cnum=%d\n",
1401 (int)max_xmit
, (int)cnum
);
1404 if (!torture_close_connection(cli
)) {
1408 printf("Passed tcon2 test\n");
1412 static bool tcon_devtest(struct cli_state
*cli
,
1413 const char *myshare
, const char *devtype
,
1414 const char *return_devtype
,
1415 NTSTATUS expected_error
)
1420 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1421 password
, strlen(password
)+1);
1423 if (NT_STATUS_IS_OK(expected_error
)) {
1424 if (NT_STATUS_IS_OK(status
)) {
1425 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1428 printf("tconX to share %s with type %s "
1429 "succeeded but returned the wrong "
1430 "device type (got [%s] but should have got [%s])\n",
1431 myshare
, devtype
, cli
->dev
, return_devtype
);
1435 printf("tconX to share %s with type %s "
1436 "should have succeeded but failed\n",
1442 if (NT_STATUS_IS_OK(status
)) {
1443 printf("tconx to share %s with type %s "
1444 "should have failed but succeeded\n",
1448 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1452 printf("Returned unexpected error\n");
1461 checks for correct tconX support
1463 static bool run_tcon_devtype_test(int dummy
)
1465 static struct cli_state
*cli1
= NULL
;
1470 status
= cli_full_connection(&cli1
, myname
,
1471 host
, NULL
, port_to_use
,
1473 username
, workgroup
,
1474 password
, flags
, signing_state
);
1476 if (!NT_STATUS_IS_OK(status
)) {
1477 printf("could not open connection\n");
1481 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1484 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1487 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1490 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1493 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1496 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1499 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1502 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1505 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1508 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1514 printf("Passed tcondevtest\n");
1521 This test checks that
1523 1) the server supports multiple locking contexts on the one SMB
1524 connection, distinguished by PID.
1526 2) the server correctly fails overlapping locks made by the same PID (this
1527 goes against POSIX behaviour, which is why it is tricky to implement)
1529 3) the server denies unlock requests by an incorrect client PID
1531 static bool run_locktest2(int dummy
)
1533 static struct cli_state
*cli
;
1534 const char *fname
= "\\lockt2.lck";
1535 uint16_t fnum1
, fnum2
, fnum3
;
1536 bool correct
= True
;
1538 if (!torture_open_connection(&cli
, 0)) {
1542 cli_sockopt(cli
, sockops
);
1544 printf("starting locktest2\n");
1546 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1550 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1551 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1555 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1556 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1562 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1563 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1569 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1570 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1574 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1575 printf("WRITE lock1 succeeded! This is a locking bug\n");
1578 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1579 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1582 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1583 printf("WRITE lock2 succeeded! This is a locking bug\n");
1586 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1587 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1590 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1591 printf("READ lock2 succeeded! This is a locking bug\n");
1594 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1595 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1598 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1599 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1602 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1603 printf("unlock at 100 succeeded! This is a locking bug\n");
1607 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1608 printf("unlock1 succeeded! This is a locking bug\n");
1611 if (!check_error(__LINE__
, cli
,
1613 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1616 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1617 printf("unlock2 succeeded! This is a locking bug\n");
1620 if (!check_error(__LINE__
, cli
,
1622 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1625 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1626 printf("lock3 succeeded! This is a locking bug\n");
1629 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1634 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1635 printf("close1 failed (%s)\n", cli_errstr(cli
));
1639 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1640 printf("close2 failed (%s)\n", cli_errstr(cli
));
1644 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1645 printf("close3 failed (%s)\n", cli_errstr(cli
));
1649 if (!torture_close_connection(cli
)) {
1653 printf("locktest2 finished\n");
1660 This test checks that
1662 1) the server supports the full offset range in lock requests
1664 static bool run_locktest3(int dummy
)
1666 static struct cli_state
*cli1
, *cli2
;
1667 const char *fname
= "\\lockt3.lck";
1668 uint16_t fnum1
, fnum2
;
1671 bool correct
= True
;
1673 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1675 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1678 cli_sockopt(cli1
, sockops
);
1679 cli_sockopt(cli2
, sockops
);
1681 printf("starting locktest3\n");
1683 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1685 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1686 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1689 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1690 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1694 for (offset
=i
=0;i
<torture_numops
;i
++) {
1696 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1697 printf("lock1 %d failed (%s)\n",
1703 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1704 printf("lock2 %d failed (%s)\n",
1711 for (offset
=i
=0;i
<torture_numops
;i
++) {
1714 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1715 printf("error: lock1 %d succeeded!\n", i
);
1719 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1720 printf("error: lock2 %d succeeded!\n", i
);
1724 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1725 printf("error: lock3 %d succeeded!\n", i
);
1729 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1730 printf("error: lock4 %d succeeded!\n", i
);
1735 for (offset
=i
=0;i
<torture_numops
;i
++) {
1738 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1739 printf("unlock1 %d failed (%s)\n",
1745 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1746 printf("unlock2 %d failed (%s)\n",
1753 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1754 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1758 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1759 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1763 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1764 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1768 if (!torture_close_connection(cli1
)) {
1772 if (!torture_close_connection(cli2
)) {
1776 printf("finished locktest3\n");
1781 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1782 printf("** "); correct = False; \
1786 looks at overlapping locks
1788 static bool run_locktest4(int dummy
)
1790 static struct cli_state
*cli1
, *cli2
;
1791 const char *fname
= "\\lockt4.lck";
1792 uint16_t fnum1
, fnum2
, f
;
1795 bool correct
= True
;
1797 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1801 cli_sockopt(cli1
, sockops
);
1802 cli_sockopt(cli2
, sockops
);
1804 printf("starting locktest4\n");
1806 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1808 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1809 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1811 memset(buf
, 0, sizeof(buf
));
1813 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1814 printf("Failed to create file\n");
1819 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1820 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1821 EXPECTED(ret
, False
);
1822 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1824 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1825 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1826 EXPECTED(ret
, True
);
1827 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1829 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1830 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1831 EXPECTED(ret
, False
);
1832 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1834 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1835 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1836 EXPECTED(ret
, True
);
1837 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1839 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1840 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1841 EXPECTED(ret
, False
);
1842 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1844 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1845 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1846 EXPECTED(ret
, True
);
1847 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1849 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1850 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1851 EXPECTED(ret
, True
);
1852 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1854 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1855 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1856 EXPECTED(ret
, False
);
1857 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1859 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1860 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1861 EXPECTED(ret
, False
);
1862 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1864 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1865 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1866 EXPECTED(ret
, True
);
1867 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1869 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1870 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1871 EXPECTED(ret
, False
);
1872 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1874 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1875 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1876 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1877 EXPECTED(ret
, False
);
1878 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1881 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1882 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1883 EXPECTED(ret
, False
);
1884 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1886 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1887 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1888 EXPECTED(ret
, False
);
1889 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1892 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1893 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1896 EXPECTED(ret
, True
);
1897 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1900 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1901 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1902 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1903 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1904 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1905 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1906 EXPECTED(ret
, True
);
1907 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1909 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1910 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1911 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1912 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1913 EXPECTED(ret
, True
);
1914 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1916 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1917 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1918 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1919 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1920 EXPECTED(ret
, True
);
1921 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1923 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1924 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1925 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1926 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1927 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1928 EXPECTED(ret
, True
);
1929 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1931 cli_close(cli1
, fnum1
);
1932 cli_close(cli2
, fnum2
);
1933 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1934 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1935 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1936 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1937 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1938 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1939 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1941 cli_close(cli1
, fnum1
);
1942 EXPECTED(ret
, True
);
1943 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1946 cli_close(cli1
, fnum1
);
1947 cli_close(cli2
, fnum2
);
1948 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1949 torture_close_connection(cli1
);
1950 torture_close_connection(cli2
);
1952 printf("finished locktest4\n");
1957 looks at lock upgrade/downgrade.
1959 static bool run_locktest5(int dummy
)
1961 static struct cli_state
*cli1
, *cli2
;
1962 const char *fname
= "\\lockt5.lck";
1963 uint16_t fnum1
, fnum2
, fnum3
;
1966 bool correct
= True
;
1968 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1972 cli_sockopt(cli1
, sockops
);
1973 cli_sockopt(cli2
, sockops
);
1975 printf("starting locktest5\n");
1977 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1979 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1980 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1981 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1983 memset(buf
, 0, sizeof(buf
));
1985 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1986 printf("Failed to create file\n");
1991 /* Check for NT bug... */
1992 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1993 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1994 cli_close(cli1
, fnum1
);
1995 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1996 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1997 EXPECTED(ret
, True
);
1998 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1999 cli_close(cli1
, fnum1
);
2000 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2001 cli_unlock(cli1
, fnum3
, 0, 1);
2003 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
2004 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
2005 EXPECTED(ret
, True
);
2006 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2008 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2009 EXPECTED(ret
, False
);
2011 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2013 /* Unlock the process 2 lock. */
2014 cli_unlock(cli2
, fnum2
, 0, 4);
2016 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2017 EXPECTED(ret
, False
);
2019 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2021 /* Unlock the process 1 fnum3 lock. */
2022 cli_unlock(cli1
, fnum3
, 0, 4);
2024 /* Stack 2 more locks here. */
2025 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
2026 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
2028 EXPECTED(ret
, True
);
2029 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2031 /* Unlock the first process lock, then check this was the WRITE lock that was
2034 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2035 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2037 EXPECTED(ret
, True
);
2038 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2040 /* Unlock the process 2 lock. */
2041 cli_unlock(cli2
, fnum2
, 0, 4);
2043 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2045 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2047 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2049 EXPECTED(ret
, True
);
2050 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2052 /* Ensure the next unlock fails. */
2053 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2054 EXPECTED(ret
, False
);
2055 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2057 /* Ensure connection 2 can get a write lock. */
2058 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2059 EXPECTED(ret
, True
);
2061 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2065 cli_close(cli1
, fnum1
);
2066 cli_close(cli2
, fnum2
);
2067 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2068 if (!torture_close_connection(cli1
)) {
2071 if (!torture_close_connection(cli2
)) {
2075 printf("finished locktest5\n");
2081 tries the unusual lockingX locktype bits
2083 static bool run_locktest6(int dummy
)
2085 static struct cli_state
*cli
;
2086 const char *fname
[1] = { "\\lock6.txt" };
2091 if (!torture_open_connection(&cli
, 0)) {
2095 cli_sockopt(cli
, sockops
);
2097 printf("starting locktest6\n");
2100 printf("Testing %s\n", fname
[i
]);
2102 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2104 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2105 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2106 cli_close(cli
, fnum
);
2107 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2109 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2110 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2111 cli_close(cli
, fnum
);
2112 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2114 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2117 torture_close_connection(cli
);
2119 printf("finished locktest6\n");
2123 static bool run_locktest7(int dummy
)
2125 struct cli_state
*cli1
;
2126 const char *fname
= "\\lockt7.lck";
2129 bool correct
= False
;
2131 if (!torture_open_connection(&cli1
, 0)) {
2135 cli_sockopt(cli1
, sockops
);
2137 printf("starting locktest7\n");
2139 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2141 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2143 memset(buf
, 0, sizeof(buf
));
2145 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
2146 printf("Failed to create file\n");
2150 cli_setpid(cli1
, 1);
2152 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
2153 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2156 printf("pid1 successfully locked range 130:4 for READ\n");
2159 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2160 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2163 printf("pid1 successfully read the range 130:4\n");
2166 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2167 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2168 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2169 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2173 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2177 cli_setpid(cli1
, 2);
2179 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2180 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2182 printf("pid2 successfully read the range 130:4\n");
2185 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2186 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2187 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2188 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2192 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2196 cli_setpid(cli1
, 1);
2197 cli_unlock(cli1
, fnum1
, 130, 4);
2199 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2200 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2203 printf("pid1 successfully locked range 130:4 for WRITE\n");
2206 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2207 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2210 printf("pid1 successfully read the range 130:4\n");
2213 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2214 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2217 printf("pid1 successfully wrote to the range 130:4\n");
2220 cli_setpid(cli1
, 2);
2222 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2223 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2224 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2225 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2229 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2233 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2234 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2235 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2236 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2240 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2244 cli_unlock(cli1
, fnum1
, 130, 0);
2248 cli_close(cli1
, fnum1
);
2249 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2250 torture_close_connection(cli1
);
2252 printf("finished locktest7\n");
2257 * This demonstrates a problem with our use of GPFS share modes: A file
2258 * descriptor sitting in the pending close queue holding a GPFS share mode
2259 * blocks opening a file another time. Happens with Word 2007 temp files.
2260 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2261 * open is denied with NT_STATUS_SHARING_VIOLATION.
2264 static bool run_locktest8(int dummy
)
2266 struct cli_state
*cli1
;
2267 const char *fname
= "\\lockt8.lck";
2268 uint16_t fnum1
, fnum2
;
2270 bool correct
= False
;
2273 if (!torture_open_connection(&cli1
, 0)) {
2277 cli_sockopt(cli1
, sockops
);
2279 printf("starting locktest8\n");
2281 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2283 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2285 if (!NT_STATUS_IS_OK(status
)) {
2286 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2290 memset(buf
, 0, sizeof(buf
));
2292 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2293 if (!NT_STATUS_IS_OK(status
)) {
2294 d_fprintf(stderr
, "cli_open second time returned %s\n",
2299 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2300 printf("Unable to apply read lock on range 1:1, error was "
2301 "%s\n", cli_errstr(cli1
));
2305 status
= cli_close(cli1
, fnum1
);
2306 if (!NT_STATUS_IS_OK(status
)) {
2307 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2311 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2312 if (!NT_STATUS_IS_OK(status
)) {
2313 d_fprintf(stderr
, "cli_open third time returned %s\n",
2321 cli_close(cli1
, fnum1
);
2322 cli_close(cli1
, fnum2
);
2323 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2324 torture_close_connection(cli1
);
2326 printf("finished locktest8\n");
2331 * This test is designed to be run in conjunction with
2332 * external NFS or POSIX locks taken in the filesystem.
2333 * It checks that the smbd server will block until the
2334 * lock is released and then acquire it. JRA.
2337 static bool got_alarm
;
2338 static int alarm_fd
;
2340 static void alarm_handler(int dummy
)
2345 static void alarm_handler_parent(int dummy
)
2350 static void do_local_lock(int read_fd
, int write_fd
)
2355 const char *local_pathname
= NULL
;
2358 local_pathname
= talloc_asprintf(talloc_tos(),
2359 "%s/lockt9.lck", local_path
);
2360 if (!local_pathname
) {
2361 printf("child: alloc fail\n");
2365 unlink(local_pathname
);
2366 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2368 printf("child: open of %s failed %s.\n",
2369 local_pathname
, strerror(errno
));
2373 /* Now take a fcntl lock. */
2374 lock
.l_type
= F_WRLCK
;
2375 lock
.l_whence
= SEEK_SET
;
2378 lock
.l_pid
= getpid();
2380 ret
= fcntl(fd
,F_SETLK
,&lock
);
2382 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2383 local_pathname
, strerror(errno
));
2386 printf("child: got lock 0:4 on file %s.\n",
2391 CatchSignal(SIGALRM
, alarm_handler
);
2393 /* Signal the parent. */
2394 if (write(write_fd
, &c
, 1) != 1) {
2395 printf("child: start signal fail %s.\n",
2402 /* Wait for the parent to be ready. */
2403 if (read(read_fd
, &c
, 1) != 1) {
2404 printf("child: reply signal fail %s.\n",
2412 printf("child: released lock 0:4 on file %s.\n",
2418 static bool run_locktest9(int dummy
)
2420 struct cli_state
*cli1
;
2421 const char *fname
= "\\lockt9.lck";
2423 bool correct
= False
;
2424 int pipe_in
[2], pipe_out
[2];
2428 struct timeval start
;
2432 printf("starting locktest9\n");
2434 if (local_path
== NULL
) {
2435 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2439 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2444 if (child_pid
== -1) {
2448 if (child_pid
== 0) {
2450 do_local_lock(pipe_out
[0], pipe_in
[1]);
2460 ret
= read(pipe_in
[0], &c
, 1);
2462 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2467 if (!torture_open_connection(&cli1
, 0)) {
2471 cli_sockopt(cli1
, sockops
);
2473 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2475 if (!NT_STATUS_IS_OK(status
)) {
2476 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2480 /* Ensure the child has the lock. */
2481 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2482 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2485 d_printf("Child has the lock.\n");
2488 /* Tell the child to wait 5 seconds then exit. */
2489 ret
= write(pipe_out
[1], &c
, 1);
2491 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2496 /* Wait 20 seconds for the lock. */
2497 alarm_fd
= cli1
->fd
;
2498 CatchSignal(SIGALRM
, alarm_handler_parent
);
2501 start
= timeval_current();
2503 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2504 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2505 "%s\n", cli_errstr(cli1
));
2510 seconds
= timeval_elapsed(&start
);
2512 printf("Parent got the lock after %.2f seconds.\n",
2515 status
= cli_close(cli1
, fnum
);
2516 if (!NT_STATUS_IS_OK(status
)) {
2517 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2524 cli_close(cli1
, fnum
);
2525 torture_close_connection(cli1
);
2529 printf("finished locktest9\n");
2534 test whether fnums and tids open on one VC are available on another (a major
2537 static bool run_fdpasstest(int dummy
)
2539 struct cli_state
*cli1
, *cli2
;
2540 const char *fname
= "\\fdpass.tst";
2544 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2547 cli_sockopt(cli1
, sockops
);
2548 cli_sockopt(cli2
, sockops
);
2550 printf("starting fdpasstest\n");
2552 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2554 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2555 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2559 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2560 printf("write failed (%s)\n", cli_errstr(cli1
));
2564 cli2
->vuid
= cli1
->vuid
;
2565 cli2
->cnum
= cli1
->cnum
;
2566 cli2
->pid
= cli1
->pid
;
2568 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2569 printf("read succeeded! nasty security hole [%s]\n",
2574 cli_close(cli1
, fnum1
);
2575 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2577 torture_close_connection(cli1
);
2578 torture_close_connection(cli2
);
2580 printf("finished fdpasstest\n");
2584 static bool run_fdsesstest(int dummy
)
2586 struct cli_state
*cli
;
2591 const char *fname
= "\\fdsess.tst";
2592 const char *fname1
= "\\fdsess1.tst";
2598 if (!torture_open_connection(&cli
, 0))
2600 cli_sockopt(cli
, sockops
);
2602 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2605 saved_cnum
= cli
->cnum
;
2606 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2608 new_cnum
= cli
->cnum
;
2609 cli
->cnum
= saved_cnum
;
2611 printf("starting fdsesstest\n");
2613 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2614 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2616 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2617 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2621 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2622 printf("write failed (%s)\n", cli_errstr(cli
));
2626 saved_vuid
= cli
->vuid
;
2627 cli
->vuid
= new_vuid
;
2629 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2630 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2634 /* Try to open a file with different vuid, samba cnum. */
2635 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2636 printf("create with different vuid, same cnum succeeded.\n");
2637 cli_close(cli
, fnum2
);
2638 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2640 printf("create with different vuid, same cnum failed.\n");
2641 printf("This will cause problems with service clients.\n");
2645 cli
->vuid
= saved_vuid
;
2647 /* Try with same vuid, different cnum. */
2648 cli
->cnum
= new_cnum
;
2650 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2651 printf("read succeeded with different cnum![%s]\n",
2656 cli
->cnum
= saved_cnum
;
2657 cli_close(cli
, fnum1
);
2658 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2660 torture_close_connection(cli
);
2662 printf("finished fdsesstest\n");
2667 This test checks that
2669 1) the server does not allow an unlink on a file that is open
2671 static bool run_unlinktest(int dummy
)
2673 struct cli_state
*cli
;
2674 const char *fname
= "\\unlink.tst";
2676 bool correct
= True
;
2678 if (!torture_open_connection(&cli
, 0)) {
2682 cli_sockopt(cli
, sockops
);
2684 printf("starting unlink test\n");
2686 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2690 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2691 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2695 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2696 printf("error: server allowed unlink on an open file\n");
2699 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2700 NT_STATUS_SHARING_VIOLATION
);
2703 cli_close(cli
, fnum
);
2704 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2706 if (!torture_close_connection(cli
)) {
2710 printf("unlink test finished\n");
2717 test how many open files this server supports on the one socket
2719 static bool run_maxfidtest(int dummy
)
2721 struct cli_state
*cli
;
2722 const char *ftemplate
= "\\maxfid.%d.%d";
2724 uint16_t fnums
[0x11000];
2727 bool correct
= True
;
2732 printf("failed to connect\n");
2736 cli_sockopt(cli
, sockops
);
2738 for (i
=0; i
<0x11000; i
++) {
2739 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2740 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2741 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2742 printf("open of %s failed (%s)\n",
2743 fname
, cli_errstr(cli
));
2744 printf("maximum fnum is %d\n", i
);
2752 printf("cleaning up\n");
2754 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2755 cli_close(cli
, fnums
[i
]);
2756 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2757 printf("unlink of %s failed (%s)\n",
2758 fname
, cli_errstr(cli
));
2765 printf("maxfid test finished\n");
2766 if (!torture_close_connection(cli
)) {
2772 /* generate a random buffer */
2773 static void rand_buf(char *buf
, int len
)
2776 *buf
= (char)sys_random();
2781 /* send smb negprot commands, not reading the response */
2782 static bool run_negprot_nowait(int dummy
)
2784 struct tevent_context
*ev
;
2786 struct cli_state
*cli
;
2787 bool correct
= True
;
2789 printf("starting negprot nowait test\n");
2791 ev
= tevent_context_init(talloc_tos());
2796 if (!(cli
= open_nbt_connection())) {
2801 for (i
=0;i
<50000;i
++) {
2802 struct tevent_req
*req
;
2804 req
= cli_negprot_send(ev
, ev
, cli
);
2809 if (!tevent_req_poll(req
, ev
)) {
2810 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
2818 if (torture_close_connection(cli
)) {
2822 printf("finished negprot nowait test\n");
2827 /* send smb negprot commands, not reading the response */
2828 static bool run_bad_nbt_session(int dummy
)
2830 static struct cli_state
*cli
;
2832 printf("starting bad nbt session test\n");
2834 if (!(cli
= open_bad_nbt_connection())) {
2839 printf("finished bad nbt session test\n");
2843 /* send random IPC commands */
2844 static bool run_randomipc(int dummy
)
2846 char *rparam
= NULL
;
2848 unsigned int rdrcnt
,rprcnt
;
2850 int api
, param_len
, i
;
2851 struct cli_state
*cli
;
2852 bool correct
= True
;
2855 printf("starting random ipc test\n");
2857 if (!torture_open_connection(&cli
, 0)) {
2861 for (i
=0;i
<count
;i
++) {
2862 api
= sys_random() % 500;
2863 param_len
= (sys_random() % 64);
2865 rand_buf(param
, param_len
);
2870 param
, param_len
, 8,
2871 NULL
, 0, BUFFER_SIZE
,
2875 printf("%d/%d\r", i
,count
);
2878 printf("%d/%d\n", i
, count
);
2880 if (!torture_close_connection(cli
)) {
2884 printf("finished random ipc test\n");
2891 static void browse_callback(const char *sname
, uint32 stype
,
2892 const char *comment
, void *state
)
2894 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2900 This test checks the browse list code
2903 static bool run_browsetest(int dummy
)
2905 static struct cli_state
*cli
;
2906 bool correct
= True
;
2908 printf("starting browse test\n");
2910 if (!torture_open_connection(&cli
, 0)) {
2914 printf("domain list:\n");
2915 cli_NetServerEnum(cli
, cli
->server_domain
,
2916 SV_TYPE_DOMAIN_ENUM
,
2917 browse_callback
, NULL
);
2919 printf("machine list:\n");
2920 cli_NetServerEnum(cli
, cli
->server_domain
,
2922 browse_callback
, NULL
);
2924 if (!torture_close_connection(cli
)) {
2928 printf("browse test finished\n");
2936 This checks how the getatr calls works
2938 static bool run_attrtest(int dummy
)
2940 struct cli_state
*cli
;
2943 const char *fname
= "\\attrib123456789.tst";
2944 bool correct
= True
;
2946 printf("starting attrib test\n");
2948 if (!torture_open_connection(&cli
, 0)) {
2952 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2953 cli_open(cli
, fname
,
2954 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2955 cli_close(cli
, fnum
);
2956 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2957 printf("getatr failed (%s)\n", cli_errstr(cli
));
2961 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2962 printf("ERROR: SMBgetatr bug. time is %s",
2968 t2
= t
-60*60*24; /* 1 day ago */
2970 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
2971 printf("setatr failed (%s)\n", cli_errstr(cli
));
2975 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2976 printf("getatr failed (%s)\n", cli_errstr(cli
));
2981 printf("ERROR: getatr/setatr bug. times are\n%s",
2983 printf("%s", ctime(&t2
));
2987 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2989 if (!torture_close_connection(cli
)) {
2993 printf("attrib test finished\n");
3000 This checks a couple of trans2 calls
3002 static bool run_trans2test(int dummy
)
3004 struct cli_state
*cli
;
3007 time_t c_time
, a_time
, m_time
;
3008 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3009 const char *fname
= "\\trans2.tst";
3010 const char *dname
= "\\trans2";
3011 const char *fname2
= "\\trans2\\trans2.tst";
3013 bool correct
= True
;
3017 printf("starting trans2 test\n");
3019 if (!torture_open_connection(&cli
, 0)) {
3023 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3024 if (!NT_STATUS_IS_OK(status
)) {
3025 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3030 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3031 cli_open(cli
, fname
,
3032 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3033 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3034 cli
, fnum
, NULL
, &size
, &c_time_ts
,
3035 &a_time_ts
, &w_time_ts
,
3036 &m_time_ts
, NULL
))) {
3037 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
3041 if (!NT_STATUS_IS_OK(cli_qfilename(cli
, fnum
, pname
, sizeof(pname
)))) {
3042 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
3046 if (strcmp(pname
, fname
)) {
3047 printf("qfilename gave different name? [%s] [%s]\n",
3052 cli_close(cli
, fnum
);
3056 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3057 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
3058 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
3059 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
3062 cli_close(cli
, fnum
);
3064 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3066 if (!NT_STATUS_IS_OK(status
)) {
3067 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3070 if (c_time
!= m_time
) {
3071 printf("create time=%s", ctime(&c_time
));
3072 printf("modify time=%s", ctime(&m_time
));
3073 printf("This system appears to have sticky create times\n");
3075 if (a_time
% (60*60) == 0) {
3076 printf("access time=%s", ctime(&a_time
));
3077 printf("This system appears to set a midnight access time\n");
3081 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3082 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3088 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3089 cli_open(cli
, fname
,
3090 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3091 cli_close(cli
, fnum
);
3092 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3093 &m_time_ts
, &size
, NULL
, NULL
);
3094 if (!NT_STATUS_IS_OK(status
)) {
3095 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3098 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3099 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3100 printf("This system appears to set a initial 0 write time\n");
3105 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3108 /* check if the server updates the directory modification time
3109 when creating a new file */
3110 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
3111 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
3115 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3116 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3117 if (!NT_STATUS_IS_OK(status
)) {
3118 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3122 cli_open(cli
, fname2
,
3123 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3124 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
3125 cli_close(cli
, fnum
);
3126 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3127 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3128 if (!NT_STATUS_IS_OK(status
)) {
3129 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3132 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3134 printf("This system does not update directory modification times\n");
3138 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
3139 cli_rmdir(cli
, dname
);
3141 if (!torture_close_connection(cli
)) {
3145 printf("trans2 test finished\n");
3151 This checks new W2K calls.
3154 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3156 uint8_t *buf
= NULL
;
3160 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3161 pcli
->max_xmit
, &buf
, &len
);
3162 if (!NT_STATUS_IS_OK(status
)) {
3163 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3166 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3167 dump_data(0, (uint8
*)buf
, len
);
3174 static bool run_w2ktest(int dummy
)
3176 struct cli_state
*cli
;
3178 const char *fname
= "\\w2ktest\\w2k.tst";
3180 bool correct
= True
;
3182 printf("starting w2k test\n");
3184 if (!torture_open_connection(&cli
, 0)) {
3188 cli_open(cli
, fname
,
3189 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3191 for (level
= 1004; level
< 1040; level
++) {
3192 new_trans(cli
, fnum
, level
);
3195 cli_close(cli
, fnum
);
3197 if (!torture_close_connection(cli
)) {
3201 printf("w2k test finished\n");
3208 this is a harness for some oplock tests
3210 static bool run_oplock1(int dummy
)
3212 struct cli_state
*cli1
;
3213 const char *fname
= "\\lockt1.lck";
3215 bool correct
= True
;
3217 printf("starting oplock test 1\n");
3219 if (!torture_open_connection(&cli1
, 0)) {
3223 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3225 cli_sockopt(cli1
, sockops
);
3227 cli1
->use_oplocks
= True
;
3229 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3230 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3234 cli1
->use_oplocks
= False
;
3236 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3237 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3239 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3240 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3244 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3245 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3249 if (!torture_close_connection(cli1
)) {
3253 printf("finished oplock test 1\n");
3258 static bool run_oplock2(int dummy
)
3260 struct cli_state
*cli1
, *cli2
;
3261 const char *fname
= "\\lockt2.lck";
3262 uint16_t fnum1
, fnum2
;
3263 int saved_use_oplocks
= use_oplocks
;
3265 bool correct
= True
;
3266 volatile bool *shared_correct
;
3268 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3269 *shared_correct
= True
;
3271 use_level_II_oplocks
= True
;
3274 printf("starting oplock test 2\n");
3276 if (!torture_open_connection(&cli1
, 0)) {
3277 use_level_II_oplocks
= False
;
3278 use_oplocks
= saved_use_oplocks
;
3282 cli1
->use_oplocks
= True
;
3283 cli1
->use_level_II_oplocks
= True
;
3285 if (!torture_open_connection(&cli2
, 1)) {
3286 use_level_II_oplocks
= False
;
3287 use_oplocks
= saved_use_oplocks
;
3291 cli2
->use_oplocks
= True
;
3292 cli2
->use_level_II_oplocks
= True
;
3294 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3296 cli_sockopt(cli1
, sockops
);
3297 cli_sockopt(cli2
, sockops
);
3299 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3300 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3304 /* Don't need the globals any more. */
3305 use_level_II_oplocks
= False
;
3306 use_oplocks
= saved_use_oplocks
;
3310 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3311 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3312 *shared_correct
= False
;
3318 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3319 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3320 *shared_correct
= False
;
3328 /* Ensure cli1 processes the break. Empty file should always return 0
3331 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3332 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3336 /* Should now be at level II. */
3337 /* Test if sending a write locks causes a break to none. */
3339 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3340 printf("lock failed (%s)\n", cli_errstr(cli1
));
3344 cli_unlock(cli1
, fnum1
, 0, 4);
3348 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3349 printf("lock failed (%s)\n", cli_errstr(cli1
));
3353 cli_unlock(cli1
, fnum1
, 0, 4);
3357 cli_read(cli1
, fnum1
, buf
, 0, 4);
3360 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3361 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
3366 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3367 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3373 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3374 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3378 if (!torture_close_connection(cli1
)) {
3382 if (!*shared_correct
) {
3386 printf("finished oplock test 2\n");
3391 /* handler for oplock 3 tests */
3392 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3394 printf("got oplock break fnum=%d level=%d\n",
3396 return cli_oplock_ack(cli
, fnum
, level
);
3399 static bool run_oplock3(int dummy
)
3401 struct cli_state
*cli
;
3402 const char *fname
= "\\oplockt3.dat";
3404 char buf
[4] = "abcd";
3405 bool correct
= True
;
3406 volatile bool *shared_correct
;
3408 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3409 *shared_correct
= True
;
3411 printf("starting oplock test 3\n");
3416 use_level_II_oplocks
= True
;
3417 if (!torture_open_connection(&cli
, 0)) {
3418 *shared_correct
= False
;
3422 /* try to trigger a oplock break in parent */
3423 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3424 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3430 use_level_II_oplocks
= True
;
3431 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3434 cli_oplock_handler(cli
, oplock3_handler
);
3435 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3436 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3437 cli_close(cli
, fnum
);
3438 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3439 cli
->timeout
= 20000;
3440 cli_receive_smb(cli
);
3441 printf("finished oplock test 3\n");
3443 return (correct
&& *shared_correct
);
3445 /* What are we looking for here? What's sucess and what's FAILURE? */
3448 /* handler for oplock 4 tests */
3449 bool *oplock4_shared_correct
;
3451 static NTSTATUS
oplock4_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3453 printf("got oplock break fnum=%d level=%d\n",
3455 *oplock4_shared_correct
= true;
3456 cli_oplock_ack(cli
, fnum
, level
);
3457 return NT_STATUS_UNSUCCESSFUL
; /* Cause cli_receive_smb to return. */
3460 static bool run_oplock4(int dummy
)
3462 struct cli_state
*cli1
, *cli2
;
3463 const char *fname
= "\\lockt4.lck";
3464 const char *fname_ln
= "\\lockt4_ln.lck";
3465 uint16_t fnum1
, fnum2
;
3466 int saved_use_oplocks
= use_oplocks
;
3468 bool correct
= true;
3470 oplock4_shared_correct
= (bool *)shm_setup(sizeof(bool));
3471 *oplock4_shared_correct
= false;
3473 printf("starting oplock test 4\n");
3475 if (!torture_open_connection(&cli1
, 0)) {
3476 use_level_II_oplocks
= false;
3477 use_oplocks
= saved_use_oplocks
;
3481 if (!torture_open_connection(&cli2
, 1)) {
3482 use_level_II_oplocks
= false;
3483 use_oplocks
= saved_use_oplocks
;
3487 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3488 cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
);
3490 cli_sockopt(cli1
, sockops
);
3491 cli_sockopt(cli2
, sockops
);
3493 /* Create the file. */
3494 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3495 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3499 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3500 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3504 /* Now create a hardlink. */
3505 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1
, fname
, fname_ln
))) {
3506 printf("nt hardlink failed (%s)\n", cli_errstr(cli1
));
3510 /* Prove that opening hardlinks cause deny modes to conflict. */
3511 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
))) {
3512 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3516 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3517 if (NT_STATUS_IS_OK(status
)) {
3518 printf("open of %s succeeded - should fail with sharing violation.\n",
3523 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3524 printf("open of %s should fail with sharing violation. Got %s\n",
3525 fname_ln
, nt_errstr(status
));
3529 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3530 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3534 cli1
->use_oplocks
= true;
3535 cli1
->use_level_II_oplocks
= true;
3537 cli2
->use_oplocks
= true;
3538 cli2
->use_level_II_oplocks
= true;
3540 cli_oplock_handler(cli1
, oplock4_handler
);
3541 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3542 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3548 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3549 printf("open of %s failed (%s)\n", fname_ln
, cli_errstr(cli1
));
3550 *oplock4_shared_correct
= false;
3554 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3555 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3556 *oplock4_shared_correct
= false;
3564 /* Process the oplock break. */
3565 cli_receive_smb(cli1
);
3567 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3568 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3572 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3573 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3576 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
))) {
3577 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3581 if (!torture_close_connection(cli1
)) {
3585 if (!*oplock4_shared_correct
) {
3589 printf("finished oplock test 4\n");
3596 Test delete on close semantics.
3598 static bool run_deletetest(int dummy
)
3600 struct cli_state
*cli1
= NULL
;
3601 struct cli_state
*cli2
= NULL
;
3602 const char *fname
= "\\delete.file";
3603 uint16_t fnum1
= (uint16_t)-1;
3604 uint16_t fnum2
= (uint16_t)-1;
3605 bool correct
= True
;
3607 printf("starting delete test\n");
3609 if (!torture_open_connection(&cli1
, 0)) {
3613 cli_sockopt(cli1
, sockops
);
3615 /* Test 1 - this should delete the file on close. */
3617 cli_setatr(cli1
, fname
, 0, 0);
3618 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3620 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3621 0, FILE_OVERWRITE_IF
,
3622 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3623 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3628 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3629 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3634 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3635 printf("[1] open of %s succeeded (should fail)\n", fname
);
3640 printf("first delete on close test succeeded.\n");
3642 /* Test 2 - this should delete the file on close. */
3644 cli_setatr(cli1
, fname
, 0, 0);
3645 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3647 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3648 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3649 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3650 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3655 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3656 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3661 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3662 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3667 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3668 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3669 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3670 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3674 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3676 printf("second delete on close test succeeded.\n");
3679 cli_setatr(cli1
, fname
, 0, 0);
3680 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3682 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3683 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3684 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3689 /* This should fail with a sharing violation - open for delete is only compatible
3690 with SHARE_DELETE. */
3692 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3693 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3694 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3699 /* This should succeed. */
3701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3702 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3703 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3708 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3709 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3714 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3715 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3720 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3721 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3726 /* This should fail - file should no longer be there. */
3728 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3729 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3730 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3731 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3733 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3737 printf("third delete on close test succeeded.\n");
3740 cli_setatr(cli1
, fname
, 0, 0);
3741 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3743 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3744 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3745 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3750 /* This should succeed. */
3751 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3752 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3753 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3758 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3759 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3764 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3765 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3770 /* This should fail - no more opens once delete on close set. */
3771 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3772 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3773 FILE_OPEN
, 0, 0, &fnum2
))) {
3774 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3778 printf("fourth delete on close test succeeded.\n");
3780 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3781 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3787 cli_setatr(cli1
, fname
, 0, 0);
3788 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3790 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3791 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3796 /* This should fail - only allowed on NT opens with DELETE access. */
3798 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3799 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3804 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3805 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3810 printf("fifth delete on close test succeeded.\n");
3813 cli_setatr(cli1
, fname
, 0, 0);
3814 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3816 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3817 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3818 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3819 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3824 /* This should fail - only allowed on NT opens with DELETE access. */
3826 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3827 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3832 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3833 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3838 printf("sixth delete on close test succeeded.\n");
3841 cli_setatr(cli1
, fname
, 0, 0);
3842 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3844 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3845 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3846 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3851 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3852 printf("[7] setting delete_on_close on file failed !\n");
3857 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3858 printf("[7] unsetting delete_on_close on file failed !\n");
3863 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3864 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3869 /* This next open should succeed - we reset the flag. */
3871 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3872 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3877 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3878 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3883 printf("seventh delete on close test succeeded.\n");
3886 cli_setatr(cli1
, fname
, 0, 0);
3887 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3889 if (!torture_open_connection(&cli2
, 1)) {
3890 printf("[8] failed to open second connection.\n");
3895 cli_sockopt(cli1
, sockops
);
3897 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3898 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3899 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3900 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3905 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3906 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3907 FILE_OPEN
, 0, 0, &fnum2
))) {
3908 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3913 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3914 printf("[8] setting delete_on_close on file failed !\n");
3919 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3920 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3925 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3926 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3931 /* This should fail.. */
3932 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3933 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3937 printf("eighth delete on close test succeeded.\n");
3939 /* This should fail - we need to set DELETE_ACCESS. */
3940 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3941 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3942 printf("[9] open of %s succeeded should have failed!\n", fname
);
3947 printf("ninth delete on close test succeeded.\n");
3949 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3950 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3951 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3956 /* This should delete the file. */
3957 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3958 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3963 /* This should fail.. */
3964 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3965 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3969 printf("tenth delete on close test succeeded.\n");
3971 cli_setatr(cli1
, fname
, 0, 0);
3972 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3974 /* What error do we get when attempting to open a read-only file with
3977 /* Create a readonly file. */
3978 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3979 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3980 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3985 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3986 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3991 /* Now try open for delete access. */
3992 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3993 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3994 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3995 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3996 cli_close(cli1
, fnum1
);
4000 NTSTATUS nterr
= cli_nt_error(cli1
);
4001 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
4002 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
4006 printf("eleventh delete on close test succeeded.\n");
4010 printf("finished delete test\n");
4013 /* FIXME: This will crash if we aborted before cli2 got
4014 * intialized, because these functions don't handle
4015 * uninitialized connections. */
4017 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4018 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4019 cli_setatr(cli1
, fname
, 0, 0);
4020 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4022 if (cli1
&& !torture_close_connection(cli1
)) {
4025 if (cli2
&& !torture_close_connection(cli2
)) {
4031 static bool run_deletetest_ln(int dummy
)
4033 struct cli_state
*cli
;
4034 const char *fname
= "\\delete1";
4035 const char *fname_ln
= "\\delete1_ln";
4039 bool correct
= true;
4042 printf("starting deletetest-ln\n");
4044 if (!torture_open_connection(&cli
, 0)) {
4048 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4049 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4051 cli_sockopt(cli
, sockops
);
4053 /* Create the file. */
4054 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4055 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4059 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum
))) {
4060 printf("close1 failed (%s)\n", cli_errstr(cli
));
4064 /* Now create a hardlink. */
4065 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli
, fname
, fname_ln
))) {
4066 printf("nt hardlink failed (%s)\n", cli_errstr(cli
));
4070 /* Open the original file. */
4071 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4072 FILE_ATTRIBUTE_NORMAL
,
4073 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4074 FILE_OPEN_IF
, 0, 0, &fnum
);
4075 if (!NT_STATUS_IS_OK(status
)) {
4076 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4080 /* Unlink the hard link path. */
4081 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4082 FILE_ATTRIBUTE_NORMAL
,
4083 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4084 FILE_OPEN_IF
, 0, 0, &fnum1
);
4085 if (!NT_STATUS_IS_OK(status
)) {
4086 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4089 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4090 if (!NT_STATUS_IS_OK(status
)) {
4091 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4092 __location__
, fname_ln
, nt_errstr(status
));
4096 status
= cli_close(cli
, fnum1
);
4097 if (!NT_STATUS_IS_OK(status
)) {
4098 printf("close %s failed (%s)\n",
4099 fname_ln
, nt_errstr(status
));
4103 status
= cli_close(cli
, fnum
);
4104 if (!NT_STATUS_IS_OK(status
)) {
4105 printf("close %s failed (%s)\n",
4106 fname
, nt_errstr(status
));
4110 /* Ensure the original file is still there. */
4111 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4112 if (!NT_STATUS_IS_OK(status
)) {
4113 printf("%s getatr on file %s failed (%s)\n",
4120 /* Ensure the link path is gone. */
4121 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4122 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4123 printf("%s, getatr for file %s returned wrong error code %s "
4124 "- should have been deleted\n",
4126 fname_ln
, nt_errstr(status
));
4130 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4131 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4133 if (!torture_close_connection(cli
)) {
4137 printf("finished deletetest-ln\n");
4143 print out server properties
4145 static bool run_properties(int dummy
)
4147 struct cli_state
*cli
;
4148 bool correct
= True
;
4150 printf("starting properties test\n");
4154 if (!torture_open_connection(&cli
, 0)) {
4158 cli_sockopt(cli
, sockops
);
4160 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
4162 if (!torture_close_connection(cli
)) {
4171 /* FIRST_DESIRED_ACCESS 0xf019f */
4172 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4173 FILE_READ_EA| /* 0xf */ \
4174 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4175 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4176 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4177 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4178 /* SECOND_DESIRED_ACCESS 0xe0080 */
4179 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4180 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4181 WRITE_OWNER_ACCESS /* 0xe0000 */
4184 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4185 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4187 WRITE_OWNER_ACCESS /* */
4191 Test ntcreate calls made by xcopy
4193 static bool run_xcopy(int dummy
)
4195 static struct cli_state
*cli1
;
4196 const char *fname
= "\\test.txt";
4197 bool correct
= True
;
4198 uint16_t fnum1
, fnum2
;
4200 printf("starting xcopy test\n");
4202 if (!torture_open_connection(&cli1
, 0)) {
4206 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4207 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
4208 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
4209 0x4044, 0, &fnum1
))) {
4210 printf("First open failed - %s\n", cli_errstr(cli1
));
4214 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4215 SECOND_DESIRED_ACCESS
, 0,
4216 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
4217 0x200000, 0, &fnum2
))) {
4218 printf("second open failed - %s\n", cli_errstr(cli1
));
4222 if (!torture_close_connection(cli1
)) {
4230 Test rename on files open with share delete and no share delete.
4232 static bool run_rename(int dummy
)
4234 static struct cli_state
*cli1
;
4235 const char *fname
= "\\test.txt";
4236 const char *fname1
= "\\test1.txt";
4237 bool correct
= True
;
4242 printf("starting rename test\n");
4244 if (!torture_open_connection(&cli1
, 0)) {
4248 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4249 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4250 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4251 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4252 printf("First open failed - %s\n", cli_errstr(cli1
));
4256 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4257 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
4259 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4263 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4264 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
4268 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4269 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4270 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4272 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4274 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4276 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4277 if (!NT_STATUS_IS_OK(status
)) {
4278 printf("Second open failed - %s\n", cli_errstr(cli1
));
4282 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4283 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
4286 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4289 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4290 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
4294 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4295 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4297 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4298 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4299 printf("Third open failed - %s\n", cli_errstr(cli1
));
4308 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4309 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4310 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4313 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4314 printf("[8] setting delete_on_close on file failed !\n");
4318 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4319 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4325 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4326 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
4329 printf("Third rename succeeded (SHARE_NONE)\n");
4332 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4333 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
4337 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4338 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4342 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4343 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4344 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4348 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4349 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
4351 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4355 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4356 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4360 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4361 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4365 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4366 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4367 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
4371 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4372 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4376 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
4380 * Now check if the first name still exists ...
4383 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4384 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4385 printf("Opening original file after rename of open file fails: %s\n",
4389 printf("Opening original file after rename of open file works ...\n");
4390 (void)cli_close(cli1, fnum2);
4394 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4395 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
4399 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4400 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
))) {
4401 printf("getatr on file %s failed - %s ! \n",
4406 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4407 printf("Renamed file %s has wrong attr 0x%x "
4408 "(should be 0x%x)\n",
4411 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4414 printf("Renamed file %s has archive bit set\n", fname1
);
4418 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4419 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4421 if (!torture_close_connection(cli1
)) {
4428 static bool run_pipe_number(int dummy
)
4430 struct cli_state
*cli1
;
4431 const char *pipe_name
= "\\SPOOLSS";
4435 printf("starting pipenumber test\n");
4436 if (!torture_open_connection(&cli1
, 0)) {
4440 cli_sockopt(cli1
, sockops
);
4442 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4443 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
4444 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
4448 printf("\r%6d", num_pipes
);
4451 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4452 torture_close_connection(cli1
);
4457 Test open mode returns on read-only files.
4459 static bool run_opentest(int dummy
)
4461 static struct cli_state
*cli1
;
4462 static struct cli_state
*cli2
;
4463 const char *fname
= "\\readonly.file";
4464 uint16_t fnum1
, fnum2
;
4467 bool correct
= True
;
4471 printf("starting open test\n");
4473 if (!torture_open_connection(&cli1
, 0)) {
4477 cli_setatr(cli1
, fname
, 0, 0);
4478 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4480 cli_sockopt(cli1
, sockops
);
4482 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4483 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4487 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4488 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4492 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4493 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
4497 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4498 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4502 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4503 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4505 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4506 NT_STATUS_ACCESS_DENIED
)) {
4507 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4510 printf("finished open test 1\n");
4512 cli_close(cli1
, fnum1
);
4514 /* Now try not readonly and ensure ERRbadshare is returned. */
4516 cli_setatr(cli1
, fname
, 0, 0);
4518 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4519 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4523 /* This will fail - but the error should be ERRshare. */
4524 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4526 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4527 NT_STATUS_SHARING_VIOLATION
)) {
4528 printf("correct error code ERRDOS/ERRbadshare returned\n");
4531 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4532 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4536 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4538 printf("finished open test 2\n");
4540 /* Test truncate open disposition on file opened for read. */
4542 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4543 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4547 /* write 20 bytes. */
4549 memset(buf
, '\0', 20);
4551 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4552 printf("write failed (%s)\n", cli_errstr(cli1
));
4556 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4557 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4561 /* Ensure size == 20. */
4562 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4563 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4568 printf("(3) file size != 20\n");
4572 /* Now test if we can truncate a file opened for readonly. */
4574 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4575 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4579 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4580 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4584 /* Ensure size == 0. */
4585 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4586 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4591 printf("(3) file size != 0\n");
4594 printf("finished open test 3\n");
4596 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4598 printf("Do ctemp tests\n");
4599 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4600 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4603 printf("ctemp gave path %s\n", tmp_path
);
4604 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4605 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4607 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4608 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4611 /* Test the non-io opens... */
4613 if (!torture_open_connection(&cli2
, 1)) {
4617 cli_setatr(cli2
, fname
, 0, 0);
4618 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4620 cli_sockopt(cli2
, sockops
);
4622 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4624 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4625 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4626 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4630 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4631 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4632 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4636 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4637 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4640 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4641 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4645 printf("non-io open test #1 passed.\n");
4647 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4649 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4651 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4652 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4653 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4657 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4658 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4659 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4663 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4664 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4667 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4668 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4672 printf("non-io open test #2 passed.\n");
4674 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4676 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4678 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4679 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4680 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4684 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4685 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4686 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4690 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4691 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4694 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4695 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4699 printf("non-io open test #3 passed.\n");
4701 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4703 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4705 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4706 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4707 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4711 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4712 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4713 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4717 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4719 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4720 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4724 printf("non-io open test #4 passed.\n");
4726 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4728 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4730 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4731 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4732 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4736 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4737 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4738 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4742 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4743 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4747 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4748 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4752 printf("non-io open test #5 passed.\n");
4754 printf("TEST #6 testing 1 non-io open, one io open\n");
4756 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4758 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4759 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4760 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4764 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4765 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4766 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4770 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4771 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4775 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4776 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4780 printf("non-io open test #6 passed.\n");
4782 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4784 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4787 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4788 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4792 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4793 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4794 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4798 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4800 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4801 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4805 printf("non-io open test #7 passed.\n");
4807 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4809 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4810 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
4811 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4812 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4813 if (!NT_STATUS_IS_OK(status
)) {
4814 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
4819 /* Write to ensure we have to update the file time. */
4820 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4821 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1
));
4826 status
= cli_close(cli1
, fnum1
);
4827 if (!NT_STATUS_IS_OK(status
)) {
4828 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
4834 if (!torture_close_connection(cli1
)) {
4837 if (!torture_close_connection(cli2
)) {
4844 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4846 uint16 major
, minor
;
4847 uint32 caplow
, caphigh
;
4850 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4851 printf("Server doesn't support UNIX CIFS extensions.\n");
4852 return NT_STATUS_NOT_SUPPORTED
;
4855 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4857 if (!NT_STATUS_IS_OK(status
)) {
4858 printf("Server didn't return UNIX CIFS extensions: %s\n",
4863 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4865 if (!NT_STATUS_IS_OK(status
)) {
4866 printf("Server doesn't support setting UNIX CIFS extensions: "
4867 "%s.\n", nt_errstr(status
));
4871 return NT_STATUS_OK
;
4875 Test POSIX open /mkdir calls.
4877 static bool run_simple_posix_open_test(int dummy
)
4879 static struct cli_state
*cli1
;
4880 const char *fname
= "posix:file";
4881 const char *hname
= "posix:hlink";
4882 const char *sname
= "posix:symlink";
4883 const char *dname
= "posix:dir";
4886 uint16_t fnum1
= (uint16_t)-1;
4887 SMB_STRUCT_STAT sbuf
;
4888 bool correct
= false;
4891 printf("Starting simple POSIX open test\n");
4893 if (!torture_open_connection(&cli1
, 0)) {
4897 cli_sockopt(cli1
, sockops
);
4899 status
= torture_setup_unix_extensions(cli1
);
4900 if (!NT_STATUS_IS_OK(status
)) {
4904 cli_setatr(cli1
, fname
, 0, 0);
4905 cli_posix_unlink(cli1
, fname
);
4906 cli_setatr(cli1
, dname
, 0, 0);
4907 cli_posix_rmdir(cli1
, dname
);
4908 cli_setatr(cli1
, hname
, 0, 0);
4909 cli_posix_unlink(cli1
, hname
);
4910 cli_setatr(cli1
, sname
, 0, 0);
4911 cli_posix_unlink(cli1
, sname
);
4913 /* Create a directory. */
4914 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4915 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4919 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4920 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4924 /* Test ftruncate - set file size. */
4925 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4926 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4930 /* Ensure st_size == 1000 */
4931 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4932 printf("stat failed (%s)\n", cli_errstr(cli1
));
4936 if (sbuf
.st_ex_size
!= 1000) {
4937 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4941 /* Test ftruncate - set file size back to zero. */
4942 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4943 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4947 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4948 printf("close failed (%s)\n", cli_errstr(cli1
));
4952 /* Now open the file again for read only. */
4953 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4954 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4958 /* Now unlink while open. */
4959 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
4960 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4964 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4965 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4969 /* Ensure the file has gone. */
4970 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4971 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4975 /* What happens when we try and POSIX open a directory ? */
4976 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
4977 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
4980 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
4981 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4986 /* Create the file. */
4987 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4988 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4992 /* Write some data into it. */
4993 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4994 printf("cli_write failed: %s\n", cli_errstr(cli1
));
4998 cli_close(cli1
, fnum1
);
5000 /* Now create a hardlink. */
5001 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
5002 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5006 /* Now create a symlink. */
5007 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
5008 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
5012 /* Open the hardlink for read. */
5013 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
5014 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5018 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
5019 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5023 if (memcmp(buf
, "TEST DATA\n", 10)) {
5024 printf("invalid data read from hardlink\n");
5028 /* Do a POSIX lock/unlock. */
5029 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
5030 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
5034 /* Punch a hole in the locked area. */
5035 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
5036 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
5040 cli_close(cli1
, fnum1
);
5042 /* Open the symlink for read - this should fail. A POSIX
5043 client should not be doing opens on a symlink. */
5044 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
5045 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5048 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
5049 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5050 printf("POSIX open of %s should have failed "
5051 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5052 "failed with %s instead.\n",
5053 sname
, cli_errstr(cli1
));
5058 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
5059 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
5063 if (strcmp(namebuf
, fname
) != 0) {
5064 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5065 sname
, fname
, namebuf
);
5069 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
5070 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
5074 printf("Simple POSIX open test passed\n");
5079 if (fnum1
!= (uint16_t)-1) {
5080 cli_close(cli1
, fnum1
);
5081 fnum1
= (uint16_t)-1;
5084 cli_setatr(cli1
, sname
, 0, 0);
5085 cli_posix_unlink(cli1
, sname
);
5086 cli_setatr(cli1
, hname
, 0, 0);
5087 cli_posix_unlink(cli1
, hname
);
5088 cli_setatr(cli1
, fname
, 0, 0);
5089 cli_posix_unlink(cli1
, fname
);
5090 cli_setatr(cli1
, dname
, 0, 0);
5091 cli_posix_rmdir(cli1
, dname
);
5093 if (!torture_close_connection(cli1
)) {
5101 static uint32 open_attrs_table
[] = {
5102 FILE_ATTRIBUTE_NORMAL
,
5103 FILE_ATTRIBUTE_ARCHIVE
,
5104 FILE_ATTRIBUTE_READONLY
,
5105 FILE_ATTRIBUTE_HIDDEN
,
5106 FILE_ATTRIBUTE_SYSTEM
,
5108 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5109 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5110 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5111 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5112 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5113 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5115 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5116 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5117 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5118 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5121 struct trunc_open_results
{
5128 static struct trunc_open_results attr_results
[] = {
5129 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5130 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5131 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5132 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5133 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5134 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5135 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5136 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5137 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5138 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5139 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5140 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5141 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5142 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5143 { 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
},
5144 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5145 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5146 { 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
},
5147 { 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
},
5148 { 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
},
5149 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5150 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5151 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5152 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5153 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5154 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5157 static bool run_openattrtest(int dummy
)
5159 static struct cli_state
*cli1
;
5160 const char *fname
= "\\openattr.file";
5162 bool correct
= True
;
5164 unsigned int i
, j
, k
, l
;
5166 printf("starting open attr test\n");
5168 if (!torture_open_connection(&cli1
, 0)) {
5172 cli_sockopt(cli1
, sockops
);
5174 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5175 cli_setatr(cli1
, fname
, 0, 0);
5176 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5177 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
5178 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
5179 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5183 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5184 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5188 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5189 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
5190 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
5191 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5192 if (attr_results
[l
].num
== k
) {
5193 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5194 k
, open_attrs_table
[i
],
5195 open_attrs_table
[j
],
5196 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
5200 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
5201 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5202 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5207 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5213 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5214 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
5218 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
5219 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
5224 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5225 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5228 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5229 if (attr_results
[l
].num
== k
) {
5230 if (attr
!= attr_results
[l
].result_attr
||
5231 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5232 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5233 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5234 open_attrs_table
[i
],
5235 open_attrs_table
[j
],
5237 attr_results
[l
].result_attr
);
5247 cli_setatr(cli1
, fname
, 0, 0);
5248 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5250 printf("open attr test %s.\n", correct
? "passed" : "failed");
5252 if (!torture_close_connection(cli1
)) {
5258 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5259 const char *name
, void *state
)
5261 int *matched
= (int *)state
;
5262 if (matched
!= NULL
) {
5265 return NT_STATUS_OK
;
5269 test directory listing speed
5271 static bool run_dirtest(int dummy
)
5274 static struct cli_state
*cli
;
5276 struct timeval core_start
;
5277 bool correct
= True
;
5280 printf("starting directory test\n");
5282 if (!torture_open_connection(&cli
, 0)) {
5286 cli_sockopt(cli
, sockops
);
5289 for (i
=0;i
<torture_numops
;i
++) {
5291 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5292 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5293 fprintf(stderr
,"Failed to open %s\n", fname
);
5296 cli_close(cli
, fnum
);
5299 core_start
= timeval_current();
5302 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5303 printf("Matched %d\n", matched
);
5306 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5307 printf("Matched %d\n", matched
);
5310 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5311 printf("Matched %d\n", matched
);
5313 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5316 for (i
=0;i
<torture_numops
;i
++) {
5318 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5319 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5322 if (!torture_close_connection(cli
)) {
5326 printf("finished dirtest\n");
5331 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5334 struct cli_state
*pcli
= (struct cli_state
*)state
;
5336 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5338 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5339 return NT_STATUS_OK
;
5341 if (finfo
->mode
& aDIR
) {
5342 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5343 printf("del_fn: failed to rmdir %s\n,", fname
);
5345 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
5346 printf("del_fn: failed to unlink %s\n,", fname
);
5348 return NT_STATUS_OK
;
5353 sees what IOCTLs are supported
5355 bool torture_ioctl_test(int dummy
)
5357 static struct cli_state
*cli
;
5358 uint16_t device
, function
;
5360 const char *fname
= "\\ioctl.dat";
5364 if (!torture_open_connection(&cli
, 0)) {
5368 printf("starting ioctl test\n");
5370 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5372 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5373 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
5377 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5378 printf("ioctl device info: %s\n", nt_errstr(status
));
5380 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5381 printf("ioctl job info: %s\n", nt_errstr(status
));
5383 for (device
=0;device
<0x100;device
++) {
5384 printf("ioctl test with device = 0x%x\n", device
);
5385 for (function
=0;function
<0x100;function
++) {
5386 uint32 code
= (device
<<16) | function
;
5388 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5390 if (NT_STATUS_IS_OK(status
)) {
5391 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5393 data_blob_free(&blob
);
5398 if (!torture_close_connection(cli
)) {
5407 tries varients of chkpath
5409 bool torture_chkpath_test(int dummy
)
5411 static struct cli_state
*cli
;
5415 if (!torture_open_connection(&cli
, 0)) {
5419 printf("starting chkpath test\n");
5421 /* cleanup from an old run */
5422 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5423 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5424 cli_rmdir(cli
, "\\chkpath.dir");
5426 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
5427 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
5431 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
5432 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
5436 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5437 printf("open1 failed (%s)\n", cli_errstr(cli
));
5440 cli_close(cli
, fnum
);
5442 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
5443 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
5447 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
5448 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
5452 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
5453 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5454 NT_STATUS_NOT_A_DIRECTORY
);
5456 printf("* chkpath on a file should fail\n");
5460 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
5461 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
5462 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
5464 printf("* chkpath on a non existant file should fail\n");
5468 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5469 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5470 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
5472 printf("* chkpath on a non existent component should fail\n");
5476 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5477 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5478 cli_rmdir(cli
, "\\chkpath.dir");
5480 if (!torture_close_connection(cli
)) {
5487 static bool run_eatest(int dummy
)
5489 static struct cli_state
*cli
;
5490 const char *fname
= "\\eatest.txt";
5491 bool correct
= True
;
5495 struct ea_struct
*ea_list
= NULL
;
5496 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5499 printf("starting eatest\n");
5501 if (!torture_open_connection(&cli
, 0)) {
5502 talloc_destroy(mem_ctx
);
5506 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5507 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5508 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5509 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5510 0x4044, 0, &fnum
))) {
5511 printf("open failed - %s\n", cli_errstr(cli
));
5512 talloc_destroy(mem_ctx
);
5516 for (i
= 0; i
< 10; i
++) {
5517 fstring ea_name
, ea_val
;
5519 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5520 memset(ea_val
, (char)i
+1, i
+1);
5521 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
5522 if (!NT_STATUS_IS_OK(status
)) {
5523 printf("ea_set of name %s failed - %s\n", ea_name
,
5525 talloc_destroy(mem_ctx
);
5530 cli_close(cli
, fnum
);
5531 for (i
= 0; i
< 10; i
++) {
5532 fstring ea_name
, ea_val
;
5534 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5535 memset(ea_val
, (char)i
+1, i
+1);
5536 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
5537 if (!NT_STATUS_IS_OK(status
)) {
5538 printf("ea_set of name %s failed - %s\n", ea_name
,
5540 talloc_destroy(mem_ctx
);
5545 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5546 if (!NT_STATUS_IS_OK(status
)) {
5547 printf("ea_get list failed - %s\n", nt_errstr(status
));
5551 printf("num_eas = %d\n", (int)num_eas
);
5553 if (num_eas
!= 20) {
5554 printf("Should be 20 EA's stored... failing.\n");
5558 for (i
= 0; i
< num_eas
; i
++) {
5559 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5560 dump_data(0, ea_list
[i
].value
.data
,
5561 ea_list
[i
].value
.length
);
5564 /* Setting EA's to zero length deletes them. Test this */
5565 printf("Now deleting all EA's - case indepenent....\n");
5568 cli_set_ea_path(cli
, fname
, "", "", 0);
5570 for (i
= 0; i
< 20; i
++) {
5572 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5573 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
5574 if (!NT_STATUS_IS_OK(status
)) {
5575 printf("ea_set of name %s failed - %s\n", ea_name
,
5577 talloc_destroy(mem_ctx
);
5583 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5584 if (!NT_STATUS_IS_OK(status
)) {
5585 printf("ea_get list failed - %s\n", nt_errstr(status
));
5589 printf("num_eas = %d\n", (int)num_eas
);
5590 for (i
= 0; i
< num_eas
; i
++) {
5591 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5592 dump_data(0, ea_list
[i
].value
.data
,
5593 ea_list
[i
].value
.length
);
5597 printf("deleting EA's failed.\n");
5601 /* Try and delete a non existant EA. */
5602 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
5603 if (!NT_STATUS_IS_OK(status
)) {
5604 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5609 talloc_destroy(mem_ctx
);
5610 if (!torture_close_connection(cli
)) {
5617 static bool run_dirtest1(int dummy
)
5620 static struct cli_state
*cli
;
5623 bool correct
= True
;
5625 printf("starting directory test\n");
5627 if (!torture_open_connection(&cli
, 0)) {
5631 cli_sockopt(cli
, sockops
);
5633 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5634 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5635 cli_rmdir(cli
, "\\LISTDIR");
5636 cli_mkdir(cli
, "\\LISTDIR");
5638 /* Create 1000 files and 1000 directories. */
5639 for (i
=0;i
<1000;i
++) {
5641 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5642 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5643 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5644 fprintf(stderr
,"Failed to open %s\n", fname
);
5647 cli_close(cli
, fnum
);
5649 for (i
=0;i
<1000;i
++) {
5651 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5652 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5653 fprintf(stderr
,"Failed to open %s\n", fname
);
5658 /* Now ensure that doing an old list sees both files and directories. */
5660 cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, &num_seen
);
5661 printf("num_seen = %d\n", num_seen
);
5662 /* We should see 100 files + 1000 directories + . and .. */
5663 if (num_seen
!= 2002)
5666 /* Ensure if we have the "must have" bits we only see the
5670 cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, &num_seen
);
5671 printf("num_seen = %d\n", num_seen
);
5672 if (num_seen
!= 1002)
5676 cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, &num_seen
);
5677 printf("num_seen = %d\n", num_seen
);
5678 if (num_seen
!= 1000)
5681 /* Delete everything. */
5682 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5683 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5684 cli_rmdir(cli
, "\\LISTDIR");
5687 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5688 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5689 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5692 if (!torture_close_connection(cli
)) {
5696 printf("finished dirtest1\n");
5701 static bool run_error_map_extract(int dummy
) {
5703 static struct cli_state
*c_dos
;
5704 static struct cli_state
*c_nt
;
5709 uint32 flgs2
, errnum
;
5716 /* NT-Error connection */
5718 if (!(c_nt
= open_nbt_connection())) {
5722 c_nt
->use_spnego
= False
;
5724 status
= cli_negprot(c_nt
);
5726 if (!NT_STATUS_IS_OK(status
)) {
5727 printf("%s rejected the NT-error negprot (%s)\n", host
,
5733 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5735 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5739 /* DOS-Error connection */
5741 if (!(c_dos
= open_nbt_connection())) {
5745 c_dos
->use_spnego
= False
;
5746 c_dos
->force_dos_errors
= True
;
5748 status
= cli_negprot(c_dos
);
5749 if (!NT_STATUS_IS_OK(status
)) {
5750 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5752 cli_shutdown(c_dos
);
5756 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5758 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5762 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5763 fstr_sprintf(user
, "%X", error
);
5765 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5766 password
, strlen(password
),
5767 password
, strlen(password
),
5769 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5772 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5774 /* Case #1: 32-bit NT errors */
5775 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5776 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5778 printf("/** Dos error on NT connection! (%s) */\n",
5780 nt_status
= NT_STATUS(0xc0000000);
5783 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5784 password
, strlen(password
),
5785 password
, strlen(password
),
5787 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5789 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5791 /* Case #1: 32-bit NT errors */
5792 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5793 printf("/** NT error on DOS connection! (%s) */\n",
5795 errnum
= errclass
= 0;
5797 cli_dos_error(c_dos
, &errclass
, &errnum
);
5800 if (NT_STATUS_V(nt_status
) != error
) {
5801 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5802 get_nt_error_c_code(NT_STATUS(error
)),
5803 get_nt_error_c_code(nt_status
));
5806 printf("\t{%s,\t%s,\t%s},\n",
5807 smb_dos_err_class(errclass
),
5808 smb_dos_err_name(errclass
, errnum
),
5809 get_nt_error_c_code(NT_STATUS(error
)));
5814 static bool run_sesssetup_bench(int dummy
)
5816 static struct cli_state
*c
;
5817 const char *fname
= "\\file.dat";
5822 if (!torture_open_connection(&c
, 0)) {
5826 if (!NT_STATUS_IS_OK(cli_ntcreate(
5827 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5828 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5829 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5830 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5834 for (i
=0; i
<torture_numops
; i
++) {
5835 status
= cli_session_setup(
5837 password
, strlen(password
),
5838 password
, strlen(password
),
5840 if (!NT_STATUS_IS_OK(status
)) {
5841 d_printf("(%s) cli_session_setup failed: %s\n",
5842 __location__
, nt_errstr(status
));
5846 d_printf("\r%d ", (int)c
->vuid
);
5848 status
= cli_ulogoff(c
);
5849 if (!NT_STATUS_IS_OK(status
)) {
5850 d_printf("(%s) cli_ulogoff failed: %s\n",
5851 __location__
, nt_errstr(status
));
5860 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5861 uid_t uid
, gid_t gid
, const char *expected
)
5866 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5868 if (strcmp(subst
, expected
) != 0) {
5869 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5870 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5879 static void chain1_open_completion(struct tevent_req
*req
)
5883 status
= cli_open_recv(req
, &fnum
);
5886 d_printf("cli_open_recv returned %s: %d\n",
5888 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5891 static void chain1_write_completion(struct tevent_req
*req
)
5895 status
= cli_write_andx_recv(req
, &written
);
5898 d_printf("cli_write_andx_recv returned %s: %d\n",
5900 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5903 static void chain1_close_completion(struct tevent_req
*req
)
5906 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5908 status
= cli_close_recv(req
);
5913 d_printf("cli_close returned %s\n", nt_errstr(status
));
5916 static bool run_chain1(int dummy
)
5918 struct cli_state
*cli1
;
5919 struct event_context
*evt
= event_context_init(NULL
);
5920 struct tevent_req
*reqs
[3], *smbreqs
[3];
5922 const char *str
= "foobar";
5925 printf("starting chain1 test\n");
5926 if (!torture_open_connection(&cli1
, 0)) {
5930 cli_sockopt(cli1
, sockops
);
5932 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5933 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5934 if (reqs
[0] == NULL
) return false;
5935 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5938 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5939 (uint8_t *)str
, 0, strlen(str
)+1,
5940 smbreqs
, 1, &smbreqs
[1]);
5941 if (reqs
[1] == NULL
) return false;
5942 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5944 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5945 if (reqs
[2] == NULL
) return false;
5946 tevent_req_set_callback(reqs
[2], chain1_close_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
);
5961 static void chain2_sesssetup_completion(struct tevent_req
*req
)
5964 status
= cli_session_setup_guest_recv(req
);
5965 d_printf("sesssetup returned %s\n", nt_errstr(status
));
5968 static void chain2_tcon_completion(struct tevent_req
*req
)
5970 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5972 status
= cli_tcon_andx_recv(req
);
5973 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
5977 static bool run_chain2(int dummy
)
5979 struct cli_state
*cli1
;
5980 struct event_context
*evt
= event_context_init(NULL
);
5981 struct tevent_req
*reqs
[2], *smbreqs
[2];
5985 printf("starting chain2 test\n");
5986 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
5987 port_to_use
, Undefined
, 0);
5988 if (!NT_STATUS_IS_OK(status
)) {
5992 cli_sockopt(cli1
, sockops
);
5994 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
5996 if (reqs
[0] == NULL
) return false;
5997 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
5999 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6000 "?????", NULL
, 0, &smbreqs
[1]);
6001 if (reqs
[1] == NULL
) return false;
6002 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6004 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6005 if (!NT_STATUS_IS_OK(status
)) {
6010 event_loop_once(evt
);
6013 torture_close_connection(cli1
);
6018 struct torture_createdel_state
{
6019 struct tevent_context
*ev
;
6020 struct cli_state
*cli
;
6023 static void torture_createdel_created(struct tevent_req
*subreq
);
6024 static void torture_createdel_closed(struct tevent_req
*subreq
);
6026 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6027 struct tevent_context
*ev
,
6028 struct cli_state
*cli
,
6031 struct tevent_req
*req
, *subreq
;
6032 struct torture_createdel_state
*state
;
6034 req
= tevent_req_create(mem_ctx
, &state
,
6035 struct torture_createdel_state
);
6042 subreq
= cli_ntcreate_send(
6043 state
, ev
, cli
, name
, 0,
6044 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6045 FILE_ATTRIBUTE_NORMAL
,
6046 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6047 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6049 if (tevent_req_nomem(subreq
, req
)) {
6050 return tevent_req_post(req
, ev
);
6052 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6056 static void torture_createdel_created(struct tevent_req
*subreq
)
6058 struct tevent_req
*req
= tevent_req_callback_data(
6059 subreq
, struct tevent_req
);
6060 struct torture_createdel_state
*state
= tevent_req_data(
6061 req
, struct torture_createdel_state
);
6065 status
= cli_ntcreate_recv(subreq
, &fnum
);
6066 TALLOC_FREE(subreq
);
6067 if (!NT_STATUS_IS_OK(status
)) {
6068 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6069 nt_errstr(status
)));
6070 tevent_req_nterror(req
, status
);
6074 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6075 if (tevent_req_nomem(subreq
, req
)) {
6078 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6081 static void torture_createdel_closed(struct tevent_req
*subreq
)
6083 struct tevent_req
*req
= tevent_req_callback_data(
6084 subreq
, struct tevent_req
);
6087 status
= cli_close_recv(subreq
);
6088 if (!NT_STATUS_IS_OK(status
)) {
6089 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6090 tevent_req_nterror(req
, status
);
6093 tevent_req_done(req
);
6096 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6098 return tevent_req_simple_recv_ntstatus(req
);
6101 struct torture_createdels_state
{
6102 struct tevent_context
*ev
;
6103 struct cli_state
*cli
;
6104 const char *base_name
;
6108 struct tevent_req
**reqs
;
6111 static void torture_createdels_done(struct tevent_req
*subreq
);
6113 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6114 struct tevent_context
*ev
,
6115 struct cli_state
*cli
,
6116 const char *base_name
,
6120 struct tevent_req
*req
;
6121 struct torture_createdels_state
*state
;
6124 req
= tevent_req_create(mem_ctx
, &state
,
6125 struct torture_createdels_state
);
6131 state
->base_name
= talloc_strdup(state
, base_name
);
6132 if (tevent_req_nomem(state
->base_name
, req
)) {
6133 return tevent_req_post(req
, ev
);
6135 state
->num_files
= MAX(num_parallel
, num_files
);
6137 state
->received
= 0;
6139 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6140 if (tevent_req_nomem(state
->reqs
, req
)) {
6141 return tevent_req_post(req
, ev
);
6144 for (i
=0; i
<num_parallel
; i
++) {
6147 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6149 if (tevent_req_nomem(name
, req
)) {
6150 return tevent_req_post(req
, ev
);
6152 state
->reqs
[i
] = torture_createdel_send(
6153 state
->reqs
, state
->ev
, state
->cli
, name
);
6154 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6155 return tevent_req_post(req
, ev
);
6157 name
= talloc_move(state
->reqs
[i
], &name
);
6158 tevent_req_set_callback(state
->reqs
[i
],
6159 torture_createdels_done
, req
);
6165 static void torture_createdels_done(struct tevent_req
*subreq
)
6167 struct tevent_req
*req
= tevent_req_callback_data(
6168 subreq
, struct tevent_req
);
6169 struct torture_createdels_state
*state
= tevent_req_data(
6170 req
, struct torture_createdels_state
);
6171 size_t num_parallel
= talloc_array_length(state
->reqs
);
6176 status
= torture_createdel_recv(subreq
);
6177 if (!NT_STATUS_IS_OK(status
)){
6178 DEBUG(10, ("torture_createdel_recv returned %s\n",
6179 nt_errstr(status
)));
6180 TALLOC_FREE(subreq
);
6181 tevent_req_nterror(req
, status
);
6185 for (i
=0; i
<num_parallel
; i
++) {
6186 if (subreq
== state
->reqs
[i
]) {
6190 if (i
== num_parallel
) {
6191 DEBUG(10, ("received something we did not send\n"));
6192 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6195 TALLOC_FREE(state
->reqs
[i
]);
6197 if (state
->sent
>= state
->num_files
) {
6198 tevent_req_done(req
);
6202 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6204 if (tevent_req_nomem(name
, req
)) {
6207 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6209 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6212 name
= talloc_move(state
->reqs
[i
], &name
);
6213 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6217 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6219 return tevent_req_simple_recv_ntstatus(req
);
6222 struct swallow_notify_state
{
6223 struct tevent_context
*ev
;
6224 struct cli_state
*cli
;
6226 uint32_t completion_filter
;
6228 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6232 static void swallow_notify_done(struct tevent_req
*subreq
);
6234 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6235 struct tevent_context
*ev
,
6236 struct cli_state
*cli
,
6238 uint32_t completion_filter
,
6240 bool (*fn
)(uint32_t action
,
6245 struct tevent_req
*req
, *subreq
;
6246 struct swallow_notify_state
*state
;
6248 req
= tevent_req_create(mem_ctx
, &state
,
6249 struct swallow_notify_state
);
6256 state
->completion_filter
= completion_filter
;
6257 state
->recursive
= recursive
;
6261 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6262 0xffff, state
->completion_filter
,
6264 if (tevent_req_nomem(subreq
, req
)) {
6265 return tevent_req_post(req
, ev
);
6267 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6271 static void swallow_notify_done(struct tevent_req
*subreq
)
6273 struct tevent_req
*req
= tevent_req_callback_data(
6274 subreq
, struct tevent_req
);
6275 struct swallow_notify_state
*state
= tevent_req_data(
6276 req
, struct swallow_notify_state
);
6278 uint32_t i
, num_changes
;
6279 struct notify_change
*changes
;
6281 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6282 TALLOC_FREE(subreq
);
6283 if (!NT_STATUS_IS_OK(status
)) {
6284 DEBUG(10, ("cli_notify_recv returned %s\n",
6285 nt_errstr(status
)));
6286 tevent_req_nterror(req
, status
);
6290 for (i
=0; i
<num_changes
; i
++) {
6291 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6293 TALLOC_FREE(changes
);
6295 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6296 0xffff, state
->completion_filter
,
6298 if (tevent_req_nomem(subreq
, req
)) {
6301 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6304 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6306 if (DEBUGLEVEL
> 5) {
6307 d_printf("%d %s\n", (int)action
, name
);
6312 static void notify_bench_done(struct tevent_req
*req
)
6314 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6318 static bool run_notify_bench(int dummy
)
6320 const char *dname
= "\\notify-bench";
6321 struct tevent_context
*ev
;
6324 struct tevent_req
*req1
;
6325 struct tevent_req
*req2
= NULL
;
6326 int i
, num_unc_names
;
6327 int num_finished
= 0;
6329 printf("starting notify-bench test\n");
6331 if (use_multishare_conn
) {
6333 unc_list
= file_lines_load(multishare_conn_fname
,
6334 &num_unc_names
, 0, NULL
);
6335 if (!unc_list
|| num_unc_names
<= 0) {
6336 d_printf("Failed to load unc names list from '%s'\n",
6337 multishare_conn_fname
);
6340 TALLOC_FREE(unc_list
);
6345 ev
= tevent_context_init(talloc_tos());
6347 d_printf("tevent_context_init failed\n");
6351 for (i
=0; i
<num_unc_names
; i
++) {
6352 struct cli_state
*cli
;
6355 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6357 if (base_fname
== NULL
) {
6361 if (!torture_open_connection(&cli
, i
)) {
6365 status
= cli_ntcreate(cli
, dname
, 0,
6366 MAXIMUM_ALLOWED_ACCESS
,
6367 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6369 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6372 if (!NT_STATUS_IS_OK(status
)) {
6373 d_printf("Could not create %s: %s\n", dname
,
6378 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6379 FILE_NOTIFY_CHANGE_FILE_NAME
|
6380 FILE_NOTIFY_CHANGE_DIR_NAME
|
6381 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6382 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6383 false, print_notifies
, NULL
);
6385 d_printf("Could not create notify request\n");
6389 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6390 base_fname
, 10, torture_numops
);
6392 d_printf("Could not create createdels request\n");
6395 TALLOC_FREE(base_fname
);
6397 tevent_req_set_callback(req2
, notify_bench_done
,
6401 while (num_finished
< num_unc_names
) {
6403 ret
= tevent_loop_once(ev
);
6405 d_printf("tevent_loop_once failed\n");
6410 if (!tevent_req_poll(req2
, ev
)) {
6411 d_printf("tevent_req_poll failed\n");
6414 status
= torture_createdels_recv(req2
);
6415 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
6420 static bool run_mangle1(int dummy
)
6422 struct cli_state
*cli
;
6423 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
6427 time_t change_time
, access_time
, write_time
;
6431 printf("starting mangle1 test\n");
6432 if (!torture_open_connection(&cli
, 0)) {
6436 cli_sockopt(cli
, sockops
);
6438 if (!NT_STATUS_IS_OK(cli_ntcreate(
6439 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6440 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6441 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
6444 cli_close(cli
, fnum
);
6446 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
6447 if (!NT_STATUS_IS_OK(status
)) {
6448 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6452 d_printf("alt_name: %s\n", alt_name
);
6454 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
6455 d_printf("cli_open(%s) failed: %s\n", alt_name
,
6459 cli_close(cli
, fnum
);
6461 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
6462 &write_time
, &size
, &mode
);
6463 if (!NT_STATUS_IS_OK(status
)) {
6464 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
6472 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
6474 size_t *to_pull
= (size_t *)priv
;
6475 size_t thistime
= *to_pull
;
6477 thistime
= MIN(thistime
, n
);
6478 if (thistime
== 0) {
6482 memset(buf
, 0, thistime
);
6483 *to_pull
-= thistime
;
6487 static bool run_windows_write(int dummy
)
6489 struct cli_state
*cli1
;
6493 const char *fname
= "\\writetest.txt";
6494 struct timeval start_time
;
6498 printf("starting windows_write test\n");
6499 if (!torture_open_connection(&cli1
, 0)) {
6503 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
6504 printf("open failed (%s)\n", cli_errstr(cli1
));
6508 cli_sockopt(cli1
, sockops
);
6510 start_time
= timeval_current();
6512 for (i
=0; i
<torture_numops
; i
++) {
6514 off_t start
= i
* torture_blocksize
;
6516 size_t to_pull
= torture_blocksize
- 1;
6518 if (cli_write(cli1
, fnum
, 0, &c
,
6519 start
+ torture_blocksize
- 1, 1) != 1) {
6520 printf("cli_write failed: %s\n", cli_errstr(cli1
));
6524 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6525 null_source
, &to_pull
);
6526 if (!NT_STATUS_IS_OK(status
)) {
6527 printf("cli_push returned: %s\n", nt_errstr(status
));
6532 seconds
= timeval_elapsed(&start_time
);
6533 kbytes
= (double)torture_blocksize
* torture_numops
;
6536 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6537 (double)seconds
, (int)(kbytes
/seconds
));
6541 cli_close(cli1
, fnum
);
6542 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6543 torture_close_connection(cli1
);
6547 static bool run_cli_echo(int dummy
)
6549 struct cli_state
*cli
;
6552 printf("starting cli_echo test\n");
6553 if (!torture_open_connection(&cli
, 0)) {
6556 cli_sockopt(cli
, sockops
);
6558 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6560 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6562 torture_close_connection(cli
);
6563 return NT_STATUS_IS_OK(status
);
6566 static bool run_uid_regression_test(int dummy
)
6568 static struct cli_state
*cli
;
6571 bool correct
= True
;
6574 printf("starting uid regression test\n");
6576 if (!torture_open_connection(&cli
, 0)) {
6580 cli_sockopt(cli
, sockops
);
6582 /* Ok - now save then logoff our current user. */
6583 old_vuid
= cli
->vuid
;
6585 status
= cli_ulogoff(cli
);
6586 if (!NT_STATUS_IS_OK(status
)) {
6587 d_printf("(%s) cli_ulogoff failed: %s\n",
6588 __location__
, nt_errstr(status
));
6593 cli
->vuid
= old_vuid
;
6595 /* Try an operation. */
6596 status
= cli_mkdir(cli
, "\\uid_reg_test");
6597 if (NT_STATUS_IS_OK(status
)) {
6598 d_printf("(%s) cli_mkdir succeeded\n",
6603 /* Should be bad uid. */
6604 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6605 NT_STATUS_USER_SESSION_DELETED
)) {
6611 old_cnum
= cli
->cnum
;
6613 /* Now try a SMBtdis with the invald vuid set to zero. */
6616 /* This should succeed. */
6617 status
= cli_tdis(cli
);
6619 if (NT_STATUS_IS_OK(status
)) {
6620 d_printf("First tdis with invalid vuid should succeed.\n");
6622 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
6627 cli
->vuid
= old_vuid
;
6628 cli
->cnum
= old_cnum
;
6630 /* This should fail. */
6631 status
= cli_tdis(cli
);
6632 if (NT_STATUS_IS_OK(status
)) {
6633 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6637 /* Should be bad tid. */
6638 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6639 NT_STATUS_NETWORK_NAME_DELETED
)) {
6645 cli_rmdir(cli
, "\\uid_reg_test");
6654 static const char *illegal_chars
= "*\\/?<>|\":";
6655 static char force_shortname_chars
[] = " +,.[];=\177";
6657 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
6658 const char *mask
, void *state
)
6660 struct cli_state
*pcli
= (struct cli_state
*)state
;
6662 NTSTATUS status
= NT_STATUS_OK
;
6664 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6666 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6667 return NT_STATUS_OK
;
6669 if (finfo
->mode
& aDIR
) {
6670 status
= cli_rmdir(pcli
, fname
);
6671 if (!NT_STATUS_IS_OK(status
)) {
6672 printf("del_fn: failed to rmdir %s\n,", fname
);
6675 status
= cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
);
6676 if (!NT_STATUS_IS_OK(status
)) {
6677 printf("del_fn: failed to unlink %s\n,", fname
);
6689 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
6690 const char *name
, void *state
)
6692 struct sn_state
*s
= (struct sn_state
*)state
;
6696 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6697 i
, finfo
->name
, finfo
->short_name
);
6700 if (strchr(force_shortname_chars
, i
)) {
6701 if (!finfo
->short_name
[0]) {
6702 /* Shortname not created when it should be. */
6703 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6704 __location__
, finfo
->name
, i
);
6707 } else if (finfo
->short_name
[0]){
6708 /* Shortname created when it should not be. */
6709 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6710 __location__
, finfo
->short_name
, finfo
->name
);
6714 return NT_STATUS_OK
;
6717 static bool run_shortname_test(int dummy
)
6719 static struct cli_state
*cli
;
6720 bool correct
= True
;
6725 printf("starting shortname test\n");
6727 if (!torture_open_connection(&cli
, 0)) {
6731 cli_sockopt(cli
, sockops
);
6733 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6734 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6735 cli_rmdir(cli
, "\\shortname");
6737 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6738 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6739 __location__
, cli_errstr(cli
));
6744 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6745 strlcat(fname
, "test .txt", sizeof(fname
));
6749 for (i
= 32; i
< 128; i
++) {
6751 uint16_t fnum
= (uint16_t)-1;
6755 if (strchr(illegal_chars
, i
)) {
6760 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6761 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6762 if (!NT_STATUS_IS_OK(status
)) {
6763 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6764 __location__
, fname
, cli_errstr(cli
));
6768 cli_close(cli
, fnum
);
6771 cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
,
6773 if (s
.matched
!= 1) {
6774 d_printf("(%s) failed to list %s: %s\n",
6775 __location__
, fname
, cli_errstr(cli
));
6779 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6780 d_printf("(%s) failed to delete %s: %s\n",
6781 __location__
, fname
, cli_errstr(cli
));
6794 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6795 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6796 cli_rmdir(cli
, "\\shortname");
6797 torture_close_connection(cli
);
6801 static void pagedsearch_cb(struct tevent_req
*req
)
6804 struct tldap_message
*msg
;
6807 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6808 if (rc
!= TLDAP_SUCCESS
) {
6809 d_printf("tldap_search_paged_recv failed: %s\n",
6810 tldap_err2string(rc
));
6813 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6817 if (!tldap_entry_dn(msg
, &dn
)) {
6818 d_printf("tldap_entry_dn failed\n");
6821 d_printf("%s\n", dn
);
6825 static bool run_tldap(int dummy
)
6827 struct tldap_context
*ld
;
6830 struct sockaddr_storage addr
;
6831 struct tevent_context
*ev
;
6832 struct tevent_req
*req
;
6836 if (!resolve_name(host
, &addr
, 0, false)) {
6837 d_printf("could not find host %s\n", host
);
6840 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6841 if (!NT_STATUS_IS_OK(status
)) {
6842 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6846 ld
= tldap_context_create(talloc_tos(), fd
);
6849 d_printf("tldap_context_create failed\n");
6853 rc
= tldap_fetch_rootdse(ld
);
6854 if (rc
!= TLDAP_SUCCESS
) {
6855 d_printf("tldap_fetch_rootdse failed: %s\n",
6856 tldap_errstr(talloc_tos(), ld
, rc
));
6860 basedn
= tldap_talloc_single_attribute(
6861 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6862 if (basedn
== NULL
) {
6863 d_printf("no defaultNamingContext\n");
6866 d_printf("defaultNamingContext: %s\n", basedn
);
6868 ev
= tevent_context_init(talloc_tos());
6870 d_printf("tevent_context_init failed\n");
6874 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6875 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6877 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6879 d_printf("tldap_search_paged_send failed\n");
6882 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6884 tevent_req_poll(req
, ev
);
6888 /* test search filters against rootDSE */
6889 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6890 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6892 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
6893 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
6894 talloc_tos(), NULL
, NULL
);
6895 if (rc
!= TLDAP_SUCCESS
) {
6896 d_printf("tldap_search with complex filter failed: %s\n",
6897 tldap_errstr(talloc_tos(), ld
, rc
));
6905 /* Torture test to ensure no regression of :
6906 https://bugzilla.samba.org/show_bug.cgi?id=7084
6909 static bool run_dir_createtime(int dummy
)
6911 struct cli_state
*cli
;
6912 const char *dname
= "\\testdir";
6913 const char *fname
= "\\testdir\\testfile";
6915 struct timespec create_time
;
6916 struct timespec create_time1
;
6920 if (!torture_open_connection(&cli
, 0)) {
6924 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6925 cli_rmdir(cli
, dname
);
6927 status
= cli_mkdir(cli
, dname
);
6928 if (!NT_STATUS_IS_OK(status
)) {
6929 printf("mkdir failed: %s\n", nt_errstr(status
));
6933 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
6935 if (!NT_STATUS_IS_OK(status
)) {
6936 printf("cli_qpathinfo2 returned %s\n",
6941 /* Sleep 3 seconds, then create a file. */
6944 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
6946 if (!NT_STATUS_IS_OK(status
)) {
6947 printf("cli_open failed: %s\n", nt_errstr(status
));
6951 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
6953 if (!NT_STATUS_IS_OK(status
)) {
6954 printf("cli_qpathinfo2 (2) returned %s\n",
6959 if (timespec_compare(&create_time1
, &create_time
)) {
6960 printf("run_dir_createtime: create time was updated (error)\n");
6962 printf("run_dir_createtime: create time was not updated (correct)\n");
6968 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6969 cli_rmdir(cli
, dname
);
6970 if (!torture_close_connection(cli
)) {
6977 static bool run_streamerror(int dummy
)
6979 struct cli_state
*cli
;
6980 const char *dname
= "\\testdir";
6981 const char *streamname
=
6982 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6984 time_t change_time
, access_time
, write_time
;
6986 uint16_t mode
, fnum
;
6989 if (!torture_open_connection(&cli
, 0)) {
6993 cli_unlink(cli
, "\\testdir\\*", aSYSTEM
| aHIDDEN
);
6994 cli_rmdir(cli
, dname
);
6996 status
= cli_mkdir(cli
, dname
);
6997 if (!NT_STATUS_IS_OK(status
)) {
6998 printf("mkdir failed: %s\n", nt_errstr(status
));
7002 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
7004 status
= cli_nt_error(cli
);
7006 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7007 printf("pathinfo returned %s, expected "
7008 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7013 status
= cli_ntcreate(cli
, streamname
, 0x16,
7014 FILE_READ_DATA
|FILE_READ_EA
|
7015 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7016 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7017 FILE_OPEN
, 0, 0, &fnum
);
7019 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7020 printf("ntcreate returned %s, expected "
7021 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7027 cli_rmdir(cli
, dname
);
7031 static bool run_local_substitute(int dummy
)
7035 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7036 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7037 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7038 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7039 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7040 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7041 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7042 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7044 /* Different captialization rules in sub_basic... */
7046 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7052 static bool run_local_base64(int dummy
)
7057 for (i
=1; i
<2000; i
++) {
7058 DATA_BLOB blob1
, blob2
;
7061 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7063 generate_random_buffer(blob1
.data
, blob1
.length
);
7065 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7067 d_fprintf(stderr
, "base64_encode_data_blob failed "
7068 "for %d bytes\n", i
);
7071 blob2
= base64_decode_data_blob(b64
);
7074 if (data_blob_cmp(&blob1
, &blob2
)) {
7075 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7079 TALLOC_FREE(blob1
.data
);
7080 data_blob_free(&blob2
);
7085 static bool run_local_gencache(int dummy
)
7091 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7092 d_printf("%s: gencache_set() failed\n", __location__
);
7096 if (!gencache_get("foo", NULL
, NULL
)) {
7097 d_printf("%s: gencache_get() failed\n", __location__
);
7101 if (!gencache_get("foo", &val
, &tm
)) {
7102 d_printf("%s: gencache_get() failed\n", __location__
);
7106 if (strcmp(val
, "bar") != 0) {
7107 d_printf("%s: gencache_get() returned %s, expected %s\n",
7108 __location__
, val
, "bar");
7115 if (!gencache_del("foo")) {
7116 d_printf("%s: gencache_del() failed\n", __location__
);
7119 if (gencache_del("foo")) {
7120 d_printf("%s: second gencache_del() succeeded\n",
7125 if (gencache_get("foo", &val
, &tm
)) {
7126 d_printf("%s: gencache_get() on deleted entry "
7127 "succeeded\n", __location__
);
7131 blob
= data_blob_string_const_null("bar");
7132 tm
= time(NULL
) + 60;
7134 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7135 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7139 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7140 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7144 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7145 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7146 __location__
, (const char *)blob
.data
, "bar");
7147 data_blob_free(&blob
);
7151 data_blob_free(&blob
);
7153 if (!gencache_del("foo")) {
7154 d_printf("%s: gencache_del() failed\n", __location__
);
7157 if (gencache_del("foo")) {
7158 d_printf("%s: second gencache_del() succeeded\n",
7163 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7164 d_printf("%s: gencache_get_data_blob() on deleted entry "
7165 "succeeded\n", __location__
);
7172 static bool rbt_testval(struct db_context
*db
, const char *key
,
7175 struct db_record
*rec
;
7176 TDB_DATA data
= string_tdb_data(value
);
7180 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7182 d_fprintf(stderr
, "fetch_locked failed\n");
7185 status
= rec
->store(rec
, data
, 0);
7186 if (!NT_STATUS_IS_OK(status
)) {
7187 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7192 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7194 d_fprintf(stderr
, "second fetch_locked failed\n");
7197 if ((rec
->value
.dsize
!= data
.dsize
)
7198 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7199 d_fprintf(stderr
, "Got wrong data back\n");
7209 static bool run_local_rbtree(int dummy
)
7211 struct db_context
*db
;
7215 db
= db_open_rbt(NULL
);
7218 d_fprintf(stderr
, "db_open_rbt failed\n");
7222 for (i
=0; i
<1000; i
++) {
7225 if (asprintf(&key
, "key%ld", random()) == -1) {
7228 if (asprintf(&value
, "value%ld", random()) == -1) {
7233 if (!rbt_testval(db
, key
, value
)) {
7240 if (asprintf(&value
, "value%ld", random()) == -1) {
7245 if (!rbt_testval(db
, key
, value
)) {
7262 struct talloc_dict_test
{
7266 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7268 int *count
= (int *)priv
;
7273 static bool run_local_talloc_dict(int dummy
)
7275 struct talloc_dict
*dict
;
7276 struct talloc_dict_test
*t
;
7279 dict
= talloc_dict_init(talloc_tos());
7284 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7291 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7296 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
7309 static bool run_local_string_to_sid(int dummy
) {
7312 if (string_to_sid(&sid
, "S--1-5-32-545")) {
7313 printf("allowing S--1-5-32-545\n");
7316 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
7317 printf("allowing S-1-5-32-+545\n");
7320 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")) {
7321 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7324 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
7325 printf("allowing S-1-5-32-545-abc\n");
7328 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
7329 printf("could not parse S-1-5-32-545\n");
7332 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
7333 printf("mis-parsed S-1-5-32-545 as %s\n",
7334 sid_string_tos(&sid
));
7340 static bool run_local_binary_to_sid(int dummy
) {
7341 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
7342 static const char good_binary_sid
[] = {
7343 0x1, /* revision number */
7345 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7346 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7359 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7360 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7363 static const char long_binary_sid
[] = {
7364 0x1, /* revision number */
7366 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7367 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7380 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7381 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7382 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7383 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7384 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7387 static const char long_binary_sid2
[] = {
7388 0x1, /* revision number */
7390 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7391 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7393 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7394 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7410 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7411 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7412 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7413 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7414 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7415 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7422 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7425 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
7428 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
7431 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
7437 /* Split a path name into filename and stream name components. Canonicalise
7438 * such that an implicit $DATA token is always explicit.
7440 * The "specification" of this function can be found in the
7441 * run_local_stream_name() function in torture.c, I've tried those
7442 * combinations against a W2k3 server.
7445 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
7446 char **pbase
, char **pstream
)
7449 char *stream
= NULL
;
7450 char *sname
; /* stream name */
7451 const char *stype
; /* stream type */
7453 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
7455 sname
= strchr_m(fname
, ':');
7457 if (lp_posix_pathnames() || (sname
== NULL
)) {
7458 if (pbase
!= NULL
) {
7459 base
= talloc_strdup(mem_ctx
, fname
);
7460 NT_STATUS_HAVE_NO_MEMORY(base
);
7465 if (pbase
!= NULL
) {
7466 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
7467 NT_STATUS_HAVE_NO_MEMORY(base
);
7472 stype
= strchr_m(sname
, ':');
7474 if (stype
== NULL
) {
7475 sname
= talloc_strdup(mem_ctx
, sname
);
7479 if (StrCaseCmp(stype
, ":$DATA") != 0) {
7481 * If there is an explicit stream type, so far we only
7482 * allow $DATA. Is there anything else allowed? -- vl
7484 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
7486 return NT_STATUS_OBJECT_NAME_INVALID
;
7488 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
7492 if (sname
== NULL
) {
7494 return NT_STATUS_NO_MEMORY
;
7497 if (sname
[0] == '\0') {
7499 * no stream name, so no stream
7504 if (pstream
!= NULL
) {
7505 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
7506 if (stream
== NULL
) {
7509 return NT_STATUS_NO_MEMORY
;
7512 * upper-case the type field
7514 strupper_m(strchr_m(stream
, ':')+1);
7518 if (pbase
!= NULL
) {
7521 if (pstream
!= NULL
) {
7524 return NT_STATUS_OK
;
7527 static bool test_stream_name(const char *fname
, const char *expected_base
,
7528 const char *expected_stream
,
7529 NTSTATUS expected_status
)
7533 char *stream
= NULL
;
7535 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
7536 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
7540 if (!NT_STATUS_IS_OK(status
)) {
7544 if (base
== NULL
) goto error
;
7546 if (strcmp(expected_base
, base
) != 0) goto error
;
7548 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
7549 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
7551 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
7555 TALLOC_FREE(stream
);
7559 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
7560 fname
, expected_base
? expected_base
: "<NULL>",
7561 expected_stream
? expected_stream
: "<NULL>",
7562 nt_errstr(expected_status
));
7563 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
7564 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
7567 TALLOC_FREE(stream
);
7571 static bool run_local_stream_name(int dummy
)
7575 ret
&= test_stream_name(
7576 "bla", "bla", NULL
, NT_STATUS_OK
);
7577 ret
&= test_stream_name(
7578 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
7579 ret
&= test_stream_name(
7580 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7581 ret
&= test_stream_name(
7582 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7583 ret
&= test_stream_name(
7584 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7585 ret
&= test_stream_name(
7586 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
7587 ret
&= test_stream_name(
7588 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
7589 ret
&= test_stream_name(
7590 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
7595 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
7597 if (a
.length
!= b
.length
) {
7598 printf("a.length=%d != b.length=%d\n",
7599 (int)a
.length
, (int)b
.length
);
7602 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
7603 printf("a.data and b.data differ\n");
7609 static bool run_local_memcache(int dummy
)
7611 struct memcache
*cache
;
7613 DATA_BLOB d1
, d2
, d3
;
7614 DATA_BLOB v1
, v2
, v3
;
7616 TALLOC_CTX
*mem_ctx
;
7618 size_t size1
, size2
;
7621 cache
= memcache_init(NULL
, 100);
7623 if (cache
== NULL
) {
7624 printf("memcache_init failed\n");
7628 d1
= data_blob_const("d1", 2);
7629 d2
= data_blob_const("d2", 2);
7630 d3
= data_blob_const("d3", 2);
7632 k1
= data_blob_const("d1", 2);
7633 k2
= data_blob_const("d2", 2);
7635 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
7636 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
7638 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
7639 printf("could not find k1\n");
7642 if (!data_blob_equal(d1
, v1
)) {
7646 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7647 printf("could not find k2\n");
7650 if (!data_blob_equal(d2
, v2
)) {
7654 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
7656 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
7657 printf("could not find replaced k1\n");
7660 if (!data_blob_equal(d3
, v3
)) {
7664 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
7666 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7667 printf("Did find k2, should have been purged\n");
7673 cache
= memcache_init(NULL
, 0);
7675 mem_ctx
= talloc_init("foo");
7677 str1
= talloc_strdup(mem_ctx
, "string1");
7678 str2
= talloc_strdup(mem_ctx
, "string2");
7680 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7681 data_blob_string_const("torture"), &str1
);
7682 size1
= talloc_total_size(cache
);
7684 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7685 data_blob_string_const("torture"), &str2
);
7686 size2
= talloc_total_size(cache
);
7688 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
7690 if (size2
> size1
) {
7691 printf("memcache leaks memory!\n");
7701 static void wbclient_done(struct tevent_req
*req
)
7704 struct winbindd_response
*wb_resp
;
7705 int *i
= (int *)tevent_req_callback_data_void(req
);
7707 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
7710 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
7713 static bool run_local_wbclient(int dummy
)
7715 struct event_context
*ev
;
7716 struct wb_context
**wb_ctx
;
7717 struct winbindd_request wb_req
;
7718 bool result
= false;
7721 BlockSignals(True
, SIGPIPE
);
7723 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
7728 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
7729 if (wb_ctx
== NULL
) {
7733 ZERO_STRUCT(wb_req
);
7734 wb_req
.cmd
= WINBINDD_PING
;
7736 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
7738 for (i
=0; i
<nprocs
; i
++) {
7739 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
7740 if (wb_ctx
[i
] == NULL
) {
7743 for (j
=0; j
<torture_numops
; j
++) {
7744 struct tevent_req
*req
;
7745 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
7746 (j
% 2) == 0, &wb_req
);
7750 tevent_req_set_callback(req
, wbclient_done
, &i
);
7756 while (i
< nprocs
* torture_numops
) {
7757 event_loop_once(ev
);
7766 static void getaddrinfo_finished(struct tevent_req
*req
)
7768 char *name
= (char *)tevent_req_callback_data_void(req
);
7769 struct addrinfo
*ainfo
;
7772 res
= getaddrinfo_recv(req
, &ainfo
);
7774 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7777 d_printf("gai(%s) succeeded\n", name
);
7778 freeaddrinfo(ainfo
);
7781 static bool run_getaddrinfo_send(int dummy
)
7783 TALLOC_CTX
*frame
= talloc_stackframe();
7784 struct fncall_context
*ctx
;
7785 struct tevent_context
*ev
;
7786 bool result
= false;
7787 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7788 "www.slashdot.org", "heise.de" };
7789 struct tevent_req
*reqs
[4];
7792 ev
= event_context_init(frame
);
7797 ctx
= fncall_context_init(frame
, 4);
7799 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7800 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7802 if (reqs
[i
] == NULL
) {
7805 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7809 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7810 tevent_loop_once(ev
);
7819 static bool dbtrans_inc(struct db_context
*db
)
7821 struct db_record
*rec
;
7826 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7828 printf(__location__
"fetch_lock failed\n");
7832 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
7833 printf(__location__
"value.dsize = %d\n",
7834 (int)rec
->value
.dsize
);
7838 val
= (uint32_t *)rec
->value
.dptr
;
7841 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
7844 if (!NT_STATUS_IS_OK(status
)) {
7845 printf(__location__
"store failed: %s\n",
7856 static bool run_local_dbtrans(int dummy
)
7858 struct db_context
*db
;
7859 struct db_record
*rec
;
7864 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
7865 O_RDWR
|O_CREAT
, 0600);
7867 printf("Could not open transtest.db\n");
7871 res
= db
->transaction_start(db
);
7873 printf(__location__
"transaction_start failed\n");
7877 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7879 printf(__location__
"fetch_lock failed\n");
7883 if (rec
->value
.dptr
== NULL
) {
7885 status
= rec
->store(
7886 rec
, make_tdb_data((uint8_t *)&initial
,
7889 if (!NT_STATUS_IS_OK(status
)) {
7890 printf(__location__
"store returned %s\n",
7898 res
= db
->transaction_commit(db
);
7900 printf(__location__
"transaction_commit failed\n");
7908 res
= db
->transaction_start(db
);
7910 printf(__location__
"transaction_start failed\n");
7914 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
7915 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7919 for (i
=0; i
<10; i
++) {
7920 if (!dbtrans_inc(db
)) {
7925 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
7926 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7930 if (val2
!= val
+ 10) {
7931 printf(__location__
"val=%d, val2=%d\n",
7932 (int)val
, (int)val2
);
7936 printf("val2=%d\r", val2
);
7938 res
= db
->transaction_commit(db
);
7940 printf(__location__
"transaction_commit failed\n");
7950 * Just a dummy test to be run under a debugger. There's no real way
7951 * to inspect the tevent_select specific function from outside of
7955 static bool run_local_tevent_select(int dummy
)
7957 struct tevent_context
*ev
;
7958 struct tevent_fd
*fd1
, *fd2
;
7959 bool result
= false;
7961 ev
= tevent_context_init_byname(NULL
, "select");
7963 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
7967 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
7969 d_fprintf(stderr
, "tevent_add_fd failed\n");
7972 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
7974 d_fprintf(stderr
, "tevent_add_fd failed\n");
7979 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
7981 d_fprintf(stderr
, "tevent_add_fd failed\n");
7991 static double create_procs(bool (*fn
)(int), bool *result
)
7994 volatile pid_t
*child_status
;
7995 volatile bool *child_status_out
;
7998 struct timeval start
;
8002 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
8003 if (!child_status
) {
8004 printf("Failed to setup shared memory\n");
8008 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
8009 if (!child_status_out
) {
8010 printf("Failed to setup result status shared memory\n");
8014 for (i
= 0; i
< nprocs
; i
++) {
8015 child_status
[i
] = 0;
8016 child_status_out
[i
] = True
;
8019 start
= timeval_current();
8021 for (i
=0;i
<nprocs
;i
++) {
8024 pid_t mypid
= getpid();
8025 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8027 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8030 if (torture_open_connection(¤t_cli
, i
)) break;
8032 printf("pid %d failed to start\n", (int)getpid());
8038 child_status
[i
] = getpid();
8040 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8042 child_status_out
[i
] = fn(i
);
8049 for (i
=0;i
<nprocs
;i
++) {
8050 if (child_status
[i
]) synccount
++;
8052 if (synccount
== nprocs
) break;
8054 } while (timeval_elapsed(&start
) < 30);
8056 if (synccount
!= nprocs
) {
8057 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8059 return timeval_elapsed(&start
);
8062 /* start the client load */
8063 start
= timeval_current();
8065 for (i
=0;i
<nprocs
;i
++) {
8066 child_status
[i
] = 0;
8069 printf("%d clients started\n", nprocs
);
8071 for (i
=0;i
<nprocs
;i
++) {
8072 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8077 for (i
=0;i
<nprocs
;i
++) {
8078 if (!child_status_out
[i
]) {
8082 return timeval_elapsed(&start
);
8085 #define FLAG_MULTIPROC 1
8092 {"FDPASS", run_fdpasstest
, 0},
8093 {"LOCK1", run_locktest1
, 0},
8094 {"LOCK2", run_locktest2
, 0},
8095 {"LOCK3", run_locktest3
, 0},
8096 {"LOCK4", run_locktest4
, 0},
8097 {"LOCK5", run_locktest5
, 0},
8098 {"LOCK6", run_locktest6
, 0},
8099 {"LOCK7", run_locktest7
, 0},
8100 {"LOCK8", run_locktest8
, 0},
8101 {"LOCK9", run_locktest9
, 0},
8102 {"UNLINK", run_unlinktest
, 0},
8103 {"BROWSE", run_browsetest
, 0},
8104 {"ATTR", run_attrtest
, 0},
8105 {"TRANS2", run_trans2test
, 0},
8106 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8107 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8108 {"RANDOMIPC", run_randomipc
, 0},
8109 {"NEGNOWAIT", run_negprot_nowait
, 0},
8110 {"NBENCH", run_nbench
, 0},
8111 {"NBENCH2", run_nbench2
, 0},
8112 {"OPLOCK1", run_oplock1
, 0},
8113 {"OPLOCK2", run_oplock2
, 0},
8114 {"OPLOCK3", run_oplock3
, 0},
8115 {"OPLOCK4", run_oplock4
, 0},
8116 {"DIR", run_dirtest
, 0},
8117 {"DIR1", run_dirtest1
, 0},
8118 {"DIR-CREATETIME", run_dir_createtime
, 0},
8119 {"DENY1", torture_denytest1
, 0},
8120 {"DENY2", torture_denytest2
, 0},
8121 {"TCON", run_tcon_test
, 0},
8122 {"TCONDEV", run_tcon_devtype_test
, 0},
8123 {"RW1", run_readwritetest
, 0},
8124 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8125 {"RW3", run_readwritelarge
, 0},
8126 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8127 {"OPEN", run_opentest
, 0},
8128 {"POSIX", run_simple_posix_open_test
, 0},
8129 {"POSIX-APPEND", run_posix_append
, 0},
8130 {"ASYNC-ECHO", run_async_echo
, 0},
8131 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8132 { "SHORTNAME-TEST", run_shortname_test
, 0},
8133 { "ADDRCHANGE", run_addrchange
, 0},
8135 {"OPENATTR", run_openattrtest
, 0},
8137 {"XCOPY", run_xcopy
, 0},
8138 {"RENAME", run_rename
, 0},
8139 {"DELETE", run_deletetest
, 0},
8140 {"DELETE-LN", run_deletetest_ln
, 0},
8141 {"PROPERTIES", run_properties
, 0},
8142 {"MANGLE", torture_mangle
, 0},
8143 {"MANGLE1", run_mangle1
, 0},
8144 {"W2K", run_w2ktest
, 0},
8145 {"TRANS2SCAN", torture_trans2_scan
, 0},
8146 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8147 {"UTABLE", torture_utable
, 0},
8148 {"CASETABLE", torture_casetable
, 0},
8149 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8150 {"PIPE_NUMBER", run_pipe_number
, 0},
8151 {"TCON2", run_tcon2_test
, 0},
8152 {"IOCTL", torture_ioctl_test
, 0},
8153 {"CHKPATH", torture_chkpath_test
, 0},
8154 {"FDSESS", run_fdsesstest
, 0},
8155 { "EATEST", run_eatest
, 0},
8156 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8157 { "CHAIN1", run_chain1
, 0},
8158 { "CHAIN2", run_chain2
, 0},
8159 { "WINDOWS-WRITE", run_windows_write
, 0},
8160 { "CLI_ECHO", run_cli_echo
, 0},
8161 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8162 { "TLDAP", run_tldap
},
8163 { "STREAMERROR", run_streamerror
},
8164 { "NOTIFY-BENCH", run_notify_bench
},
8165 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8166 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8167 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8168 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8169 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8170 { "LOCAL-BASE64", run_local_base64
, 0},
8171 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8172 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8173 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8174 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8175 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8176 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8177 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8178 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8183 /****************************************************************************
8184 run a specified test or "ALL"
8185 ****************************************************************************/
8186 static bool run_test(const char *name
)
8193 if (strequal(name
,"ALL")) {
8194 for (i
=0;torture_ops
[i
].name
;i
++) {
8195 run_test(torture_ops
[i
].name
);
8200 for (i
=0;torture_ops
[i
].name
;i
++) {
8201 fstr_sprintf(randomfname
, "\\XX%x",
8202 (unsigned)random());
8204 if (strequal(name
, torture_ops
[i
].name
)) {
8206 printf("Running %s\n", name
);
8207 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8208 t
= create_procs(torture_ops
[i
].fn
, &result
);
8211 printf("TEST %s FAILED!\n", name
);
8214 struct timeval start
;
8215 start
= timeval_current();
8216 if (!torture_ops
[i
].fn(0)) {
8218 printf("TEST %s FAILED!\n", name
);
8220 t
= timeval_elapsed(&start
);
8222 printf("%s took %g secs\n\n", name
, t
);
8227 printf("Did not find a test named %s\n", name
);
8235 static void usage(void)
8239 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8240 printf("Please use samba4 torture.\n\n");
8242 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8244 printf("\t-d debuglevel\n");
8245 printf("\t-U user%%pass\n");
8246 printf("\t-k use kerberos\n");
8247 printf("\t-N numprocs\n");
8248 printf("\t-n my_netbios_name\n");
8249 printf("\t-W workgroup\n");
8250 printf("\t-o num_operations\n");
8251 printf("\t-O socket_options\n");
8252 printf("\t-m maximum protocol\n");
8253 printf("\t-L use oplocks\n");
8254 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8255 printf("\t-A showall\n");
8256 printf("\t-p port\n");
8257 printf("\t-s seed\n");
8258 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8261 printf("tests are:");
8262 for (i
=0;torture_ops
[i
].name
;i
++) {
8263 printf(" %s", torture_ops
[i
].name
);
8267 printf("default test is ALL\n");
8272 /****************************************************************************
8274 ****************************************************************************/
8275 int main(int argc
,char *argv
[])
8281 bool correct
= True
;
8282 TALLOC_CTX
*frame
= talloc_stackframe();
8283 int seed
= time(NULL
);
8285 #ifdef HAVE_SETBUFFER
8286 setbuffer(stdout
, NULL
, 0);
8289 setup_logging("smbtorture", DEBUG_STDOUT
);
8293 if (is_default_dyn_CONFIGFILE()) {
8294 if(getenv("SMB_CONF_PATH")) {
8295 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8298 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
8305 for(p
= argv
[1]; *p
; p
++)
8309 if (strncmp(argv
[1], "//", 2)) {
8313 fstrcpy(host
, &argv
[1][2]);
8314 p
= strchr_m(&host
[2],'/');
8319 fstrcpy(share
, p
+1);
8321 fstrcpy(myname
, get_myname(talloc_tos()));
8323 fprintf(stderr
, "Failed to get my hostname.\n");
8327 if (*username
== 0 && getenv("LOGNAME")) {
8328 fstrcpy(username
,getenv("LOGNAME"));
8334 fstrcpy(workgroup
, lp_workgroup());
8336 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
8339 port_to_use
= atoi(optarg
);
8342 seed
= atoi(optarg
);
8345 fstrcpy(workgroup
,optarg
);
8348 max_protocol
= interpret_protocol(optarg
, max_protocol
);
8351 nprocs
= atoi(optarg
);
8354 torture_numops
= atoi(optarg
);
8357 lp_set_cmdline("log level", optarg
);
8366 local_path
= optarg
;
8369 torture_showall
= True
;
8372 fstrcpy(myname
, optarg
);
8375 client_txt
= optarg
;
8382 use_kerberos
= True
;
8384 d_printf("No kerberos support compiled in\n");
8390 fstrcpy(username
,optarg
);
8391 p
= strchr_m(username
,'%');
8394 fstrcpy(password
, p
+1);
8399 fstrcpy(multishare_conn_fname
, optarg
);
8400 use_multishare_conn
= True
;
8403 torture_blocksize
= atoi(optarg
);
8406 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
8411 d_printf("using seed %d\n", seed
);
8415 if(use_kerberos
&& !gotuser
) gotpass
= True
;
8418 p
= getpass("Password:");
8420 fstrcpy(password
, p
);
8425 printf("host=%s share=%s user=%s myname=%s\n",
8426 host
, share
, username
, myname
);
8428 if (argc
== optind
) {
8429 correct
= run_test("ALL");
8431 for (i
=optind
;i
<argc
;i
++) {
8432 if (!run_test(argv
[i
])) {