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;
583 printf("%d\r", i
); fflush(stdout
);
585 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
587 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
591 if (!NT_STATUS_IS_OK(cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
, &fnum
))) {
592 printf("open failed (%s)\n", cli_errstr(c
));
597 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
599 if (!NT_STATUS_IS_OK(status
)) {
600 printf("write failed (%s)\n", nt_errstr(status
));
605 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
606 sizeof(pid
)+(j
*sizeof(buf
)),
608 if (!NT_STATUS_IS_OK(status
)) {
609 printf("write failed (%s)\n",
617 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
618 printf("read failed (%s)\n", cli_errstr(c
));
623 printf("data corruption!\n");
627 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
628 printf("close failed (%s)\n", cli_errstr(c
));
632 if (!NT_STATUS_IS_OK(cli_unlink(c
, fname
, aSYSTEM
| aHIDDEN
))) {
633 printf("unlink failed (%s)\n", cli_errstr(c
));
637 if (!NT_STATUS_IS_OK(cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int)))) {
638 printf("unlock failed (%s)\n", cli_errstr(c
));
644 cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
);
651 static bool run_torture(int dummy
)
653 struct cli_state
*cli
;
658 cli_sockopt(cli
, sockops
);
660 ret
= rw_torture(cli
);
662 if (!torture_close_connection(cli
)) {
669 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
671 uint16_t fnum
= (uint16_t)-1;
676 unsigned countprev
= 0;
679 NTSTATUS status
= NT_STATUS_OK
;
682 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
684 SIVAL(buf
, i
, sys_random());
689 if (!NT_STATUS_IS_OK(cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
))) {
690 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c
));
693 if (!NT_STATUS_IS_OK(cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
694 DENY_NONE
, &fnum
))) {
695 printf("first open read/write of %s failed (%s)\n",
696 lockfname
, cli_errstr(c
));
702 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
704 status
= cli_open(c
, lockfname
, O_RDONLY
,
706 if (!NT_STATUS_IS_OK(status
)) {
711 if (!NT_STATUS_IS_OK(status
)) {
712 printf("second open read-only of %s failed (%s)\n",
713 lockfname
, cli_errstr(c
));
719 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
721 if (count
>= countprev
) {
722 printf("%d %8d\r", i
, count
);
725 countprev
+= (sizeof(buf
) / 20);
730 sent
= ((unsigned)sys_random()%(20))+ 1;
731 if (sent
> sizeof(buf
) - count
)
733 sent
= sizeof(buf
) - count
;
736 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
737 count
, (size_t)sent
, NULL
);
738 if (!NT_STATUS_IS_OK(status
)) {
739 printf("write failed (%s)\n",
746 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
750 printf("read failed offset:%d size:%ld (%s)\n",
751 count
, (unsigned long)sizeof(buf
)-count
,
758 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
760 printf("read/write compare failed\n");
761 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
770 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
771 printf("close failed (%s)\n", cli_errstr(c
));
778 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
780 const char *lockfname
= "\\torture2.lck";
789 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
790 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
793 if (!NT_STATUS_IS_OK(cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
794 DENY_NONE
, &fnum1
))) {
795 printf("first open read/write of %s failed (%s)\n",
796 lockfname
, cli_errstr(c1
));
799 if (!NT_STATUS_IS_OK(cli_open(c2
, lockfname
, O_RDONLY
,
800 DENY_NONE
, &fnum2
))) {
801 printf("second open read-only of %s failed (%s)\n",
802 lockfname
, cli_errstr(c2
));
803 cli_close(c1
, fnum1
);
807 for (i
=0;i
<torture_numops
;i
++)
810 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
812 printf("%d\r", i
); fflush(stdout
);
815 generate_random_buffer((unsigned char *)buf
, buf_size
);
817 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
819 if (!NT_STATUS_IS_OK(status
)) {
820 printf("write failed (%s)\n", nt_errstr(status
));
825 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
826 printf("read failed (%s)\n", cli_errstr(c2
));
827 printf("read %d, expected %ld\n", (int)bytes_read
,
828 (unsigned long)buf_size
);
833 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
835 printf("read/write compare failed\n");
841 if (!NT_STATUS_IS_OK(cli_close(c2
, fnum2
))) {
842 printf("close failed (%s)\n", cli_errstr(c2
));
845 if (!NT_STATUS_IS_OK(cli_close(c1
, fnum1
))) {
846 printf("close failed (%s)\n", cli_errstr(c1
));
850 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
851 printf("unlink failed (%s)\n", cli_errstr(c1
));
858 static bool run_readwritetest(int dummy
)
860 struct cli_state
*cli1
, *cli2
;
861 bool test1
, test2
= False
;
863 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
866 cli_sockopt(cli1
, sockops
);
867 cli_sockopt(cli2
, sockops
);
869 printf("starting readwritetest\n");
871 test1
= rw_torture2(cli1
, cli2
);
872 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
875 test2
= rw_torture2(cli1
, cli1
);
876 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
879 if (!torture_close_connection(cli1
)) {
883 if (!torture_close_connection(cli2
)) {
887 return (test1
&& test2
);
890 static bool run_readwritemulti(int dummy
)
892 struct cli_state
*cli
;
897 cli_sockopt(cli
, sockops
);
899 printf("run_readwritemulti: fname %s\n", randomfname
);
900 test
= rw_torture3(cli
, randomfname
);
902 if (!torture_close_connection(cli
)) {
909 static bool run_readwritelarge_internal(int max_xmit_k
)
911 static struct cli_state
*cli1
;
913 const char *lockfname
= "\\large.dat";
918 if (!torture_open_connection(&cli1
, 0)) {
921 cli_sockopt(cli1
, sockops
);
922 memset(buf
,'\0',sizeof(buf
));
924 cli1
->max_xmit
= max_xmit_k
*1024;
926 if (signing_state
== Required
) {
927 /* Horrible cheat to force
928 multiple signed outstanding
929 packets against a Samba server.
931 cli1
->is_samba
= false;
934 printf("starting readwritelarge_internal\n");
936 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
938 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
939 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
943 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
945 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
946 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
947 NULL
, NULL
, NULL
))) {
948 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
952 if (fsize
== sizeof(buf
))
953 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
954 (unsigned long)fsize
);
956 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
957 (unsigned long)fsize
);
961 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
962 printf("close failed (%s)\n", cli_errstr(cli1
));
966 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
967 printf("unlink failed (%s)\n", cli_errstr(cli1
));
971 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
972 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
976 cli1
->max_xmit
= 4*1024;
978 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
980 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
981 cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
982 NULL
, NULL
, NULL
))) {
983 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
987 if (fsize
== sizeof(buf
))
988 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
989 (unsigned long)fsize
);
991 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
992 (unsigned long)fsize
);
997 /* ToDo - set allocation. JRA */
998 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
999 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1002 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1004 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1008 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1011 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1012 printf("close failed (%s)\n", cli_errstr(cli1
));
1016 if (!torture_close_connection(cli1
)) {
1022 static bool run_readwritelarge(int dummy
)
1024 return run_readwritelarge_internal(128);
1027 static bool run_readwritelarge_signtest(int dummy
)
1030 signing_state
= Required
;
1031 ret
= run_readwritelarge_internal(2);
1032 signing_state
= Undefined
;
1039 #define ival(s) strtol(s, NULL, 0)
1041 /* run a test that simulates an approximate netbench client load */
1042 static bool run_netbench(int client
)
1044 struct cli_state
*cli
;
1049 const char *params
[20];
1050 bool correct
= True
;
1056 cli_sockopt(cli
, sockops
);
1060 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1062 f
= fopen(client_txt
, "r");
1069 while (fgets(line
, sizeof(line
)-1, f
)) {
1073 line
[strlen(line
)-1] = 0;
1075 /* printf("[%d] %s\n", line_count, line); */
1077 all_string_sub(line
,"client1", cname
, sizeof(line
));
1079 /* parse the command parameters */
1080 params
[0] = strtok_r(line
, " ", &saveptr
);
1082 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1086 if (i
< 2) continue;
1088 if (!strncmp(params
[0],"SMB", 3)) {
1089 printf("ERROR: You are using a dbench 1 load file\n");
1093 if (!strcmp(params
[0],"NTCreateX")) {
1094 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1096 } else if (!strcmp(params
[0],"Close")) {
1097 nb_close(ival(params
[1]));
1098 } else if (!strcmp(params
[0],"Rename")) {
1099 nb_rename(params
[1], params
[2]);
1100 } else if (!strcmp(params
[0],"Unlink")) {
1101 nb_unlink(params
[1]);
1102 } else if (!strcmp(params
[0],"Deltree")) {
1103 nb_deltree(params
[1]);
1104 } else if (!strcmp(params
[0],"Rmdir")) {
1105 nb_rmdir(params
[1]);
1106 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1107 nb_qpathinfo(params
[1]);
1108 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1109 nb_qfileinfo(ival(params
[1]));
1110 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1111 nb_qfsinfo(ival(params
[1]));
1112 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1113 nb_findfirst(params
[1]);
1114 } else if (!strcmp(params
[0],"WriteX")) {
1115 nb_writex(ival(params
[1]),
1116 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1117 } else if (!strcmp(params
[0],"ReadX")) {
1118 nb_readx(ival(params
[1]),
1119 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1120 } else if (!strcmp(params
[0],"Flush")) {
1121 nb_flush(ival(params
[1]));
1123 printf("Unknown operation %s\n", params
[0]);
1131 if (!torture_close_connection(cli
)) {
1139 /* run a test that simulates an approximate netbench client load */
1140 static bool run_nbench(int dummy
)
1143 bool correct
= True
;
1149 signal(SIGALRM
, nb_alarm
);
1151 t
= create_procs(run_netbench
, &correct
);
1154 printf("\nThroughput %g MB/sec\n",
1155 1.0e-6 * nbio_total() / t
);
1161 This test checks for two things:
1163 1) correct support for retaining locks over a close (ie. the server
1164 must not use posix semantics)
1165 2) support for lock timeouts
1167 static bool run_locktest1(int dummy
)
1169 struct cli_state
*cli1
, *cli2
;
1170 const char *fname
= "\\lockt1.lck";
1171 uint16_t fnum1
, fnum2
, fnum3
;
1173 unsigned lock_timeout
;
1175 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1178 cli_sockopt(cli1
, sockops
);
1179 cli_sockopt(cli2
, sockops
);
1181 printf("starting locktest1\n");
1183 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1185 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1186 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1189 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1190 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1193 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1194 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1198 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1199 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1204 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1205 printf("lock2 succeeded! This is a locking bug\n");
1208 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1209 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1213 lock_timeout
= (1 + (random() % 20));
1214 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1216 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1217 printf("lock3 succeeded! This is a locking bug\n");
1220 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1221 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1225 if (ABS(t2
- t1
) < lock_timeout
-1) {
1226 printf("error: This server appears not to support timed lock requests\n");
1229 printf("server slept for %u seconds for a %u second timeout\n",
1230 (unsigned int)(t2
-t1
), lock_timeout
);
1232 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1233 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1237 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1238 printf("lock4 succeeded! This is a locking bug\n");
1241 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1242 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1245 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1246 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1250 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1251 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1255 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1256 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1261 if (!torture_close_connection(cli1
)) {
1265 if (!torture_close_connection(cli2
)) {
1269 printf("Passed locktest1\n");
1274 this checks to see if a secondary tconx can use open files from an
1277 static bool run_tcon_test(int dummy
)
1279 static struct cli_state
*cli
;
1280 const char *fname
= "\\tcontest.tmp";
1282 uint16 cnum1
, cnum2
, cnum3
;
1283 uint16 vuid1
, vuid2
;
1288 memset(buf
, '\0', sizeof(buf
));
1290 if (!torture_open_connection(&cli
, 0)) {
1293 cli_sockopt(cli
, sockops
);
1295 printf("starting tcontest\n");
1297 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1299 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1300 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1307 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1308 if (!NT_STATUS_IS_OK(status
)) {
1309 printf("initial write failed (%s)", nt_errstr(status
));
1313 status
= cli_tcon_andx(cli
, share
, "?????",
1314 password
, strlen(password
)+1);
1315 if (!NT_STATUS_IS_OK(status
)) {
1316 printf("%s refused 2nd tree connect (%s)\n", host
,
1323 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1324 vuid2
= cli
->vuid
+ 1;
1326 /* try a write with the wrong tid */
1329 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1330 if (NT_STATUS_IS_OK(status
)) {
1331 printf("* server allows write with wrong TID\n");
1334 printf("server fails write with wrong TID : %s\n",
1339 /* try a write with an invalid tid */
1342 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1343 if (NT_STATUS_IS_OK(status
)) {
1344 printf("* server allows write with invalid TID\n");
1347 printf("server fails write with invalid TID : %s\n",
1351 /* try a write with an invalid vuid */
1355 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1356 if (NT_STATUS_IS_OK(status
)) {
1357 printf("* server allows write with invalid VUID\n");
1360 printf("server fails write with invalid VUID : %s\n",
1367 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1368 printf("close failed (%s)\n", cli_errstr(cli
));
1374 status
= cli_tdis(cli
);
1375 if (!NT_STATUS_IS_OK(status
)) {
1376 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1382 if (!torture_close_connection(cli
)) {
1391 checks for old style tcon support
1393 static bool run_tcon2_test(int dummy
)
1395 static struct cli_state
*cli
;
1396 uint16 cnum
, max_xmit
;
1400 if (!torture_open_connection(&cli
, 0)) {
1403 cli_sockopt(cli
, sockops
);
1405 printf("starting tcon2 test\n");
1407 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1411 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1415 if (!NT_STATUS_IS_OK(status
)) {
1416 printf("tcon2 failed : %s\n", nt_errstr(status
));
1418 printf("tcon OK : max_xmit=%d cnum=%d\n",
1419 (int)max_xmit
, (int)cnum
);
1422 if (!torture_close_connection(cli
)) {
1426 printf("Passed tcon2 test\n");
1430 static bool tcon_devtest(struct cli_state
*cli
,
1431 const char *myshare
, const char *devtype
,
1432 const char *return_devtype
,
1433 NTSTATUS expected_error
)
1438 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1439 password
, strlen(password
)+1);
1441 if (NT_STATUS_IS_OK(expected_error
)) {
1442 if (NT_STATUS_IS_OK(status
)) {
1443 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1446 printf("tconX to share %s with type %s "
1447 "succeeded but returned the wrong "
1448 "device type (got [%s] but should have got [%s])\n",
1449 myshare
, devtype
, cli
->dev
, return_devtype
);
1453 printf("tconX to share %s with type %s "
1454 "should have succeeded but failed\n",
1460 if (NT_STATUS_IS_OK(status
)) {
1461 printf("tconx to share %s with type %s "
1462 "should have failed but succeeded\n",
1466 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1470 printf("Returned unexpected error\n");
1479 checks for correct tconX support
1481 static bool run_tcon_devtype_test(int dummy
)
1483 static struct cli_state
*cli1
= NULL
;
1488 status
= cli_full_connection(&cli1
, myname
,
1489 host
, NULL
, port_to_use
,
1491 username
, workgroup
,
1492 password
, flags
, signing_state
);
1494 if (!NT_STATUS_IS_OK(status
)) {
1495 printf("could not open connection\n");
1499 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1502 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1505 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1508 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1511 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1514 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1517 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1520 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1523 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1526 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1532 printf("Passed tcondevtest\n");
1539 This test checks that
1541 1) the server supports multiple locking contexts on the one SMB
1542 connection, distinguished by PID.
1544 2) the server correctly fails overlapping locks made by the same PID (this
1545 goes against POSIX behaviour, which is why it is tricky to implement)
1547 3) the server denies unlock requests by an incorrect client PID
1549 static bool run_locktest2(int dummy
)
1551 static struct cli_state
*cli
;
1552 const char *fname
= "\\lockt2.lck";
1553 uint16_t fnum1
, fnum2
, fnum3
;
1554 bool correct
= True
;
1556 if (!torture_open_connection(&cli
, 0)) {
1560 cli_sockopt(cli
, sockops
);
1562 printf("starting locktest2\n");
1564 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1568 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1569 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1573 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1574 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1580 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1581 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1587 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1588 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1592 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1593 printf("WRITE lock1 succeeded! This is a locking bug\n");
1596 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1597 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1600 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1601 printf("WRITE lock2 succeeded! This is a locking bug\n");
1604 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1605 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1608 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1609 printf("READ lock2 succeeded! This is a locking bug\n");
1612 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1613 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1616 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1617 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1620 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1621 printf("unlock at 100 succeeded! This is a locking bug\n");
1625 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1626 printf("unlock1 succeeded! This is a locking bug\n");
1629 if (!check_error(__LINE__
, cli
,
1631 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1634 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1635 printf("unlock2 succeeded! This is a locking bug\n");
1638 if (!check_error(__LINE__
, cli
,
1640 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1643 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1644 printf("lock3 succeeded! This is a locking bug\n");
1647 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1652 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1653 printf("close1 failed (%s)\n", cli_errstr(cli
));
1657 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1658 printf("close2 failed (%s)\n", cli_errstr(cli
));
1662 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1663 printf("close3 failed (%s)\n", cli_errstr(cli
));
1667 if (!torture_close_connection(cli
)) {
1671 printf("locktest2 finished\n");
1678 This test checks that
1680 1) the server supports the full offset range in lock requests
1682 static bool run_locktest3(int dummy
)
1684 static struct cli_state
*cli1
, *cli2
;
1685 const char *fname
= "\\lockt3.lck";
1686 uint16_t fnum1
, fnum2
;
1689 bool correct
= True
;
1691 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1693 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1696 cli_sockopt(cli1
, sockops
);
1697 cli_sockopt(cli2
, sockops
);
1699 printf("starting locktest3\n");
1701 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1703 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1704 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1707 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1708 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1712 for (offset
=i
=0;i
<torture_numops
;i
++) {
1714 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1715 printf("lock1 %d failed (%s)\n",
1721 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1722 printf("lock2 %d failed (%s)\n",
1729 for (offset
=i
=0;i
<torture_numops
;i
++) {
1732 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1733 printf("error: lock1 %d succeeded!\n", i
);
1737 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1738 printf("error: lock2 %d succeeded!\n", i
);
1742 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1743 printf("error: lock3 %d succeeded!\n", i
);
1747 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1748 printf("error: lock4 %d succeeded!\n", i
);
1753 for (offset
=i
=0;i
<torture_numops
;i
++) {
1756 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1757 printf("unlock1 %d failed (%s)\n",
1763 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1764 printf("unlock2 %d failed (%s)\n",
1771 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1772 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1776 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1777 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1781 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1782 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1786 if (!torture_close_connection(cli1
)) {
1790 if (!torture_close_connection(cli2
)) {
1794 printf("finished locktest3\n");
1799 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1800 printf("** "); correct = False; \
1804 looks at overlapping locks
1806 static bool run_locktest4(int dummy
)
1808 static struct cli_state
*cli1
, *cli2
;
1809 const char *fname
= "\\lockt4.lck";
1810 uint16_t fnum1
, fnum2
, f
;
1813 bool correct
= True
;
1816 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1820 cli_sockopt(cli1
, sockops
);
1821 cli_sockopt(cli2
, sockops
);
1823 printf("starting locktest4\n");
1825 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1827 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1828 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1830 memset(buf
, 0, sizeof(buf
));
1832 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1834 if (!NT_STATUS_IS_OK(status
)) {
1835 printf("Failed to create file: %s\n", nt_errstr(status
));
1840 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1841 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1842 EXPECTED(ret
, False
);
1843 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1845 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1846 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1847 EXPECTED(ret
, True
);
1848 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1850 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1851 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1852 EXPECTED(ret
, False
);
1853 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1855 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1856 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1857 EXPECTED(ret
, True
);
1858 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1860 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1861 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1862 EXPECTED(ret
, False
);
1863 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1865 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1866 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1867 EXPECTED(ret
, True
);
1868 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1870 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1871 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1872 EXPECTED(ret
, True
);
1873 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1875 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1876 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1877 EXPECTED(ret
, False
);
1878 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1880 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1881 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1882 EXPECTED(ret
, False
);
1883 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1885 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1886 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1887 EXPECTED(ret
, True
);
1888 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1890 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1891 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1892 EXPECTED(ret
, False
);
1893 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1895 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1896 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1897 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1898 EXPECTED(ret
, False
);
1899 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1902 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1903 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1904 EXPECTED(ret
, False
);
1905 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1907 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
1909 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
1911 ret
= NT_STATUS_IS_OK(status
);
1913 EXPECTED(ret
, False
);
1914 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1917 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1918 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1919 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1921 EXPECTED(ret
, True
);
1922 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1925 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1926 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1927 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1928 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1929 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
1931 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1932 EXPECTED(ret
, True
);
1933 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1935 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1936 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1937 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
1939 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1940 EXPECTED(ret
, True
);
1941 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1943 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1944 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1945 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
1947 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1948 EXPECTED(ret
, True
);
1949 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1951 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1952 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1953 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1954 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
1956 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1957 EXPECTED(ret
, True
);
1958 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1960 cli_close(cli1
, fnum1
);
1961 cli_close(cli2
, fnum2
);
1962 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1963 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1964 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1965 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1966 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1967 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1968 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1970 cli_close(cli1
, fnum1
);
1971 EXPECTED(ret
, True
);
1972 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1975 cli_close(cli1
, fnum1
);
1976 cli_close(cli2
, fnum2
);
1977 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1978 torture_close_connection(cli1
);
1979 torture_close_connection(cli2
);
1981 printf("finished locktest4\n");
1986 looks at lock upgrade/downgrade.
1988 static bool run_locktest5(int dummy
)
1990 static struct cli_state
*cli1
, *cli2
;
1991 const char *fname
= "\\lockt5.lck";
1992 uint16_t fnum1
, fnum2
, fnum3
;
1995 bool correct
= True
;
1998 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2002 cli_sockopt(cli1
, sockops
);
2003 cli_sockopt(cli2
, sockops
);
2005 printf("starting locktest5\n");
2007 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2009 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2010 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2011 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2013 memset(buf
, 0, sizeof(buf
));
2015 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2017 if (!NT_STATUS_IS_OK(status
)) {
2018 printf("Failed to create file: %s\n", nt_errstr(status
));
2023 /* Check for NT bug... */
2024 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
2025 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
2026 cli_close(cli1
, fnum1
);
2027 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2028 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2029 EXPECTED(ret
, True
);
2030 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2031 cli_close(cli1
, fnum1
);
2032 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2033 cli_unlock(cli1
, fnum3
, 0, 1);
2035 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
2036 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
2037 EXPECTED(ret
, True
);
2038 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2040 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2041 EXPECTED(ret
, False
);
2043 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2045 /* Unlock the process 2 lock. */
2046 cli_unlock(cli2
, fnum2
, 0, 4);
2048 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2049 EXPECTED(ret
, False
);
2051 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2053 /* Unlock the process 1 fnum3 lock. */
2054 cli_unlock(cli1
, fnum3
, 0, 4);
2056 /* Stack 2 more locks here. */
2057 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
2058 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
2060 EXPECTED(ret
, True
);
2061 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2063 /* Unlock the first process lock, then check this was the WRITE lock that was
2066 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2067 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2069 EXPECTED(ret
, True
);
2070 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2072 /* Unlock the process 2 lock. */
2073 cli_unlock(cli2
, fnum2
, 0, 4);
2075 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2077 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2078 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2079 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2081 EXPECTED(ret
, True
);
2082 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2084 /* Ensure the next unlock fails. */
2085 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2086 EXPECTED(ret
, False
);
2087 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2089 /* Ensure connection 2 can get a write lock. */
2090 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2091 EXPECTED(ret
, True
);
2093 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2097 cli_close(cli1
, fnum1
);
2098 cli_close(cli2
, fnum2
);
2099 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2100 if (!torture_close_connection(cli1
)) {
2103 if (!torture_close_connection(cli2
)) {
2107 printf("finished locktest5\n");
2113 tries the unusual lockingX locktype bits
2115 static bool run_locktest6(int dummy
)
2117 static struct cli_state
*cli
;
2118 const char *fname
[1] = { "\\lock6.txt" };
2123 if (!torture_open_connection(&cli
, 0)) {
2127 cli_sockopt(cli
, sockops
);
2129 printf("starting locktest6\n");
2132 printf("Testing %s\n", fname
[i
]);
2134 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2136 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2137 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2138 cli_close(cli
, fnum
);
2139 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2141 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2142 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2143 cli_close(cli
, fnum
);
2144 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2146 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
2149 torture_close_connection(cli
);
2151 printf("finished locktest6\n");
2155 static bool run_locktest7(int dummy
)
2157 struct cli_state
*cli1
;
2158 const char *fname
= "\\lockt7.lck";
2161 bool correct
= False
;
2164 if (!torture_open_connection(&cli1
, 0)) {
2168 cli_sockopt(cli1
, sockops
);
2170 printf("starting locktest7\n");
2172 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2174 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2176 memset(buf
, 0, sizeof(buf
));
2178 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2180 if (!NT_STATUS_IS_OK(status
)) {
2181 printf("Failed to create file: %s\n", nt_errstr(status
));
2185 cli_setpid(cli1
, 1);
2187 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
2188 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2191 printf("pid1 successfully locked range 130:4 for READ\n");
2194 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2195 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2198 printf("pid1 successfully read the range 130:4\n");
2201 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2202 if (!NT_STATUS_IS_OK(status
)) {
2203 printf("pid1 unable to write to the range 130:4, error was "
2204 "%s\n", nt_errstr(status
));
2205 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2206 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2210 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2214 cli_setpid(cli1
, 2);
2216 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2217 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2219 printf("pid2 successfully read the range 130:4\n");
2222 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2223 if (!NT_STATUS_IS_OK(status
)) {
2224 printf("pid2 unable to write to the range 130:4, error was "
2225 "%s\n", nt_errstr(status
));
2226 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2227 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2231 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2235 cli_setpid(cli1
, 1);
2236 cli_unlock(cli1
, fnum1
, 130, 4);
2238 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2239 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2242 printf("pid1 successfully locked range 130:4 for WRITE\n");
2245 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2246 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2249 printf("pid1 successfully read the range 130:4\n");
2252 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2253 if (!NT_STATUS_IS_OK(status
)) {
2254 printf("pid1 unable to write to the range 130:4, error was "
2255 "%s\n", nt_errstr(status
));
2258 printf("pid1 successfully wrote to the range 130:4\n");
2261 cli_setpid(cli1
, 2);
2263 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2264 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2265 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2266 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2270 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2274 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2275 if (!NT_STATUS_IS_OK(status
)) {
2276 printf("pid2 unable to write to the range 130:4, error was "
2277 "%s\n", nt_errstr(status
));
2278 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2279 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2283 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2287 cli_unlock(cli1
, fnum1
, 130, 0);
2291 cli_close(cli1
, fnum1
);
2292 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2293 torture_close_connection(cli1
);
2295 printf("finished locktest7\n");
2300 * This demonstrates a problem with our use of GPFS share modes: A file
2301 * descriptor sitting in the pending close queue holding a GPFS share mode
2302 * blocks opening a file another time. Happens with Word 2007 temp files.
2303 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2304 * open is denied with NT_STATUS_SHARING_VIOLATION.
2307 static bool run_locktest8(int dummy
)
2309 struct cli_state
*cli1
;
2310 const char *fname
= "\\lockt8.lck";
2311 uint16_t fnum1
, fnum2
;
2313 bool correct
= False
;
2316 if (!torture_open_connection(&cli1
, 0)) {
2320 cli_sockopt(cli1
, sockops
);
2322 printf("starting locktest8\n");
2324 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2326 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2328 if (!NT_STATUS_IS_OK(status
)) {
2329 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2333 memset(buf
, 0, sizeof(buf
));
2335 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2336 if (!NT_STATUS_IS_OK(status
)) {
2337 d_fprintf(stderr
, "cli_open second time returned %s\n",
2342 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2343 printf("Unable to apply read lock on range 1:1, error was "
2344 "%s\n", cli_errstr(cli1
));
2348 status
= cli_close(cli1
, fnum1
);
2349 if (!NT_STATUS_IS_OK(status
)) {
2350 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2354 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2355 if (!NT_STATUS_IS_OK(status
)) {
2356 d_fprintf(stderr
, "cli_open third time returned %s\n",
2364 cli_close(cli1
, fnum1
);
2365 cli_close(cli1
, fnum2
);
2366 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2367 torture_close_connection(cli1
);
2369 printf("finished locktest8\n");
2374 * This test is designed to be run in conjunction with
2375 * external NFS or POSIX locks taken in the filesystem.
2376 * It checks that the smbd server will block until the
2377 * lock is released and then acquire it. JRA.
2380 static bool got_alarm
;
2381 static int alarm_fd
;
2383 static void alarm_handler(int dummy
)
2388 static void alarm_handler_parent(int dummy
)
2393 static void do_local_lock(int read_fd
, int write_fd
)
2398 const char *local_pathname
= NULL
;
2401 local_pathname
= talloc_asprintf(talloc_tos(),
2402 "%s/lockt9.lck", local_path
);
2403 if (!local_pathname
) {
2404 printf("child: alloc fail\n");
2408 unlink(local_pathname
);
2409 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2411 printf("child: open of %s failed %s.\n",
2412 local_pathname
, strerror(errno
));
2416 /* Now take a fcntl lock. */
2417 lock
.l_type
= F_WRLCK
;
2418 lock
.l_whence
= SEEK_SET
;
2421 lock
.l_pid
= getpid();
2423 ret
= fcntl(fd
,F_SETLK
,&lock
);
2425 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2426 local_pathname
, strerror(errno
));
2429 printf("child: got lock 0:4 on file %s.\n",
2434 CatchSignal(SIGALRM
, alarm_handler
);
2436 /* Signal the parent. */
2437 if (write(write_fd
, &c
, 1) != 1) {
2438 printf("child: start signal fail %s.\n",
2445 /* Wait for the parent to be ready. */
2446 if (read(read_fd
, &c
, 1) != 1) {
2447 printf("child: reply signal fail %s.\n",
2455 printf("child: released lock 0:4 on file %s.\n",
2461 static bool run_locktest9(int dummy
)
2463 struct cli_state
*cli1
;
2464 const char *fname
= "\\lockt9.lck";
2466 bool correct
= False
;
2467 int pipe_in
[2], pipe_out
[2];
2471 struct timeval start
;
2475 printf("starting locktest9\n");
2477 if (local_path
== NULL
) {
2478 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2482 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2487 if (child_pid
== -1) {
2491 if (child_pid
== 0) {
2493 do_local_lock(pipe_out
[0], pipe_in
[1]);
2503 ret
= read(pipe_in
[0], &c
, 1);
2505 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2510 if (!torture_open_connection(&cli1
, 0)) {
2514 cli_sockopt(cli1
, sockops
);
2516 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2518 if (!NT_STATUS_IS_OK(status
)) {
2519 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2523 /* Ensure the child has the lock. */
2524 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2525 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2528 d_printf("Child has the lock.\n");
2531 /* Tell the child to wait 5 seconds then exit. */
2532 ret
= write(pipe_out
[1], &c
, 1);
2534 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2539 /* Wait 20 seconds for the lock. */
2540 alarm_fd
= cli1
->fd
;
2541 CatchSignal(SIGALRM
, alarm_handler_parent
);
2544 start
= timeval_current();
2546 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2547 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2548 "%s\n", cli_errstr(cli1
));
2553 seconds
= timeval_elapsed(&start
);
2555 printf("Parent got the lock after %.2f seconds.\n",
2558 status
= cli_close(cli1
, fnum
);
2559 if (!NT_STATUS_IS_OK(status
)) {
2560 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2567 cli_close(cli1
, fnum
);
2568 torture_close_connection(cli1
);
2572 printf("finished locktest9\n");
2577 test whether fnums and tids open on one VC are available on another (a major
2580 static bool run_fdpasstest(int dummy
)
2582 struct cli_state
*cli1
, *cli2
;
2583 const char *fname
= "\\fdpass.tst";
2588 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2591 cli_sockopt(cli1
, sockops
);
2592 cli_sockopt(cli2
, sockops
);
2594 printf("starting fdpasstest\n");
2596 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2598 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2599 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2603 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)"hello world\n", 0,
2605 if (!NT_STATUS_IS_OK(status
)) {
2606 printf("write failed (%s)\n", nt_errstr(status
));
2610 cli2
->vuid
= cli1
->vuid
;
2611 cli2
->cnum
= cli1
->cnum
;
2612 cli2
->pid
= cli1
->pid
;
2614 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2615 printf("read succeeded! nasty security hole [%s]\n",
2620 cli_close(cli1
, fnum1
);
2621 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2623 torture_close_connection(cli1
);
2624 torture_close_connection(cli2
);
2626 printf("finished fdpasstest\n");
2630 static bool run_fdsesstest(int dummy
)
2632 struct cli_state
*cli
;
2637 const char *fname
= "\\fdsess.tst";
2638 const char *fname1
= "\\fdsess1.tst";
2645 if (!torture_open_connection(&cli
, 0))
2647 cli_sockopt(cli
, sockops
);
2649 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2652 saved_cnum
= cli
->cnum
;
2653 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2655 new_cnum
= cli
->cnum
;
2656 cli
->cnum
= saved_cnum
;
2658 printf("starting fdsesstest\n");
2660 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2661 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2663 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2664 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2668 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)"hello world\n", 0, 13,
2670 if (!NT_STATUS_IS_OK(status
)) {
2671 printf("write failed (%s)\n", nt_errstr(status
));
2675 saved_vuid
= cli
->vuid
;
2676 cli
->vuid
= new_vuid
;
2678 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2679 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2683 /* Try to open a file with different vuid, samba cnum. */
2684 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2685 printf("create with different vuid, same cnum succeeded.\n");
2686 cli_close(cli
, fnum2
);
2687 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2689 printf("create with different vuid, same cnum failed.\n");
2690 printf("This will cause problems with service clients.\n");
2694 cli
->vuid
= saved_vuid
;
2696 /* Try with same vuid, different cnum. */
2697 cli
->cnum
= new_cnum
;
2699 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2700 printf("read succeeded with different cnum![%s]\n",
2705 cli
->cnum
= saved_cnum
;
2706 cli_close(cli
, fnum1
);
2707 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2709 torture_close_connection(cli
);
2711 printf("finished fdsesstest\n");
2716 This test checks that
2718 1) the server does not allow an unlink on a file that is open
2720 static bool run_unlinktest(int dummy
)
2722 struct cli_state
*cli
;
2723 const char *fname
= "\\unlink.tst";
2725 bool correct
= True
;
2727 if (!torture_open_connection(&cli
, 0)) {
2731 cli_sockopt(cli
, sockops
);
2733 printf("starting unlink test\n");
2735 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2739 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2740 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2744 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2745 printf("error: server allowed unlink on an open file\n");
2748 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2749 NT_STATUS_SHARING_VIOLATION
);
2752 cli_close(cli
, fnum
);
2753 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2755 if (!torture_close_connection(cli
)) {
2759 printf("unlink test finished\n");
2766 test how many open files this server supports on the one socket
2768 static bool run_maxfidtest(int dummy
)
2770 struct cli_state
*cli
;
2771 const char *ftemplate
= "\\maxfid.%d.%d";
2773 uint16_t fnums
[0x11000];
2776 bool correct
= True
;
2781 printf("failed to connect\n");
2785 cli_sockopt(cli
, sockops
);
2787 for (i
=0; i
<0x11000; i
++) {
2788 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2789 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2790 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2791 printf("open of %s failed (%s)\n",
2792 fname
, cli_errstr(cli
));
2793 printf("maximum fnum is %d\n", i
);
2801 printf("cleaning up\n");
2803 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2804 cli_close(cli
, fnums
[i
]);
2805 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2806 printf("unlink of %s failed (%s)\n",
2807 fname
, cli_errstr(cli
));
2814 printf("maxfid test finished\n");
2815 if (!torture_close_connection(cli
)) {
2821 /* generate a random buffer */
2822 static void rand_buf(char *buf
, int len
)
2825 *buf
= (char)sys_random();
2830 /* send smb negprot commands, not reading the response */
2831 static bool run_negprot_nowait(int dummy
)
2833 struct tevent_context
*ev
;
2835 struct cli_state
*cli
;
2836 bool correct
= True
;
2838 printf("starting negprot nowait test\n");
2840 ev
= tevent_context_init(talloc_tos());
2845 if (!(cli
= open_nbt_connection())) {
2850 for (i
=0;i
<50000;i
++) {
2851 struct tevent_req
*req
;
2853 req
= cli_negprot_send(ev
, ev
, cli
);
2858 if (!tevent_req_poll(req
, ev
)) {
2859 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
2867 if (torture_close_connection(cli
)) {
2871 printf("finished negprot nowait test\n");
2876 /* send smb negprot commands, not reading the response */
2877 static bool run_bad_nbt_session(int dummy
)
2879 static struct cli_state
*cli
;
2881 printf("starting bad nbt session test\n");
2883 if (!(cli
= open_bad_nbt_connection())) {
2888 printf("finished bad nbt session test\n");
2892 /* send random IPC commands */
2893 static bool run_randomipc(int dummy
)
2895 char *rparam
= NULL
;
2897 unsigned int rdrcnt
,rprcnt
;
2899 int api
, param_len
, i
;
2900 struct cli_state
*cli
;
2901 bool correct
= True
;
2904 printf("starting random ipc test\n");
2906 if (!torture_open_connection(&cli
, 0)) {
2910 for (i
=0;i
<count
;i
++) {
2911 api
= sys_random() % 500;
2912 param_len
= (sys_random() % 64);
2914 rand_buf(param
, param_len
);
2919 param
, param_len
, 8,
2920 NULL
, 0, BUFFER_SIZE
,
2924 printf("%d/%d\r", i
,count
);
2927 printf("%d/%d\n", i
, count
);
2929 if (!torture_close_connection(cli
)) {
2933 printf("finished random ipc test\n");
2940 static void browse_callback(const char *sname
, uint32 stype
,
2941 const char *comment
, void *state
)
2943 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2949 This test checks the browse list code
2952 static bool run_browsetest(int dummy
)
2954 static struct cli_state
*cli
;
2955 bool correct
= True
;
2957 printf("starting browse test\n");
2959 if (!torture_open_connection(&cli
, 0)) {
2963 printf("domain list:\n");
2964 cli_NetServerEnum(cli
, cli
->server_domain
,
2965 SV_TYPE_DOMAIN_ENUM
,
2966 browse_callback
, NULL
);
2968 printf("machine list:\n");
2969 cli_NetServerEnum(cli
, cli
->server_domain
,
2971 browse_callback
, NULL
);
2973 if (!torture_close_connection(cli
)) {
2977 printf("browse test finished\n");
2985 This checks how the getatr calls works
2987 static bool run_attrtest(int dummy
)
2989 struct cli_state
*cli
;
2992 const char *fname
= "\\attrib123456789.tst";
2993 bool correct
= True
;
2995 printf("starting attrib test\n");
2997 if (!torture_open_connection(&cli
, 0)) {
3001 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3002 cli_open(cli
, fname
,
3003 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3004 cli_close(cli
, fnum
);
3005 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
3006 printf("getatr failed (%s)\n", cli_errstr(cli
));
3010 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3011 printf("ERROR: SMBgetatr bug. time is %s",
3017 t2
= t
-60*60*24; /* 1 day ago */
3019 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
3020 printf("setatr failed (%s)\n", cli_errstr(cli
));
3024 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
3025 printf("getatr failed (%s)\n", cli_errstr(cli
));
3030 printf("ERROR: getatr/setatr bug. times are\n%s",
3032 printf("%s", ctime(&t2
));
3036 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3038 if (!torture_close_connection(cli
)) {
3042 printf("attrib test finished\n");
3049 This checks a couple of trans2 calls
3051 static bool run_trans2test(int dummy
)
3053 struct cli_state
*cli
;
3056 time_t c_time
, a_time
, m_time
;
3057 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3058 const char *fname
= "\\trans2.tst";
3059 const char *dname
= "\\trans2";
3060 const char *fname2
= "\\trans2\\trans2.tst";
3062 bool correct
= True
;
3066 printf("starting trans2 test\n");
3068 if (!torture_open_connection(&cli
, 0)) {
3072 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3073 if (!NT_STATUS_IS_OK(status
)) {
3074 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3079 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3080 cli_open(cli
, fname
,
3081 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3082 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3083 cli
, fnum
, NULL
, &size
, &c_time_ts
,
3084 &a_time_ts
, &w_time_ts
,
3085 &m_time_ts
, NULL
))) {
3086 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
3090 if (!NT_STATUS_IS_OK(cli_qfilename(cli
, fnum
, pname
, sizeof(pname
)))) {
3091 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
3095 if (strcmp(pname
, fname
)) {
3096 printf("qfilename gave different name? [%s] [%s]\n",
3101 cli_close(cli
, fnum
);
3105 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3106 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
3107 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
3108 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
3111 cli_close(cli
, fnum
);
3113 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3115 if (!NT_STATUS_IS_OK(status
)) {
3116 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3119 if (c_time
!= m_time
) {
3120 printf("create time=%s", ctime(&c_time
));
3121 printf("modify time=%s", ctime(&m_time
));
3122 printf("This system appears to have sticky create times\n");
3124 if (a_time
% (60*60) == 0) {
3125 printf("access time=%s", ctime(&a_time
));
3126 printf("This system appears to set a midnight access time\n");
3130 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3131 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3137 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3138 cli_open(cli
, fname
,
3139 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3140 cli_close(cli
, fnum
);
3141 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3142 &m_time_ts
, &size
, NULL
, NULL
);
3143 if (!NT_STATUS_IS_OK(status
)) {
3144 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3147 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3148 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3149 printf("This system appears to set a initial 0 write time\n");
3154 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
3157 /* check if the server updates the directory modification time
3158 when creating a new file */
3159 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
3160 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
3164 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3165 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3166 if (!NT_STATUS_IS_OK(status
)) {
3167 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3171 cli_open(cli
, fname2
,
3172 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3173 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3174 cli_close(cli
, fnum
);
3175 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3176 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3177 if (!NT_STATUS_IS_OK(status
)) {
3178 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3181 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3183 printf("This system does not update directory modification times\n");
3187 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
3188 cli_rmdir(cli
, dname
);
3190 if (!torture_close_connection(cli
)) {
3194 printf("trans2 test finished\n");
3200 This checks new W2K calls.
3203 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3205 uint8_t *buf
= NULL
;
3209 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3210 pcli
->max_xmit
, &buf
, &len
);
3211 if (!NT_STATUS_IS_OK(status
)) {
3212 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3215 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3216 dump_data(0, (uint8
*)buf
, len
);
3223 static bool run_w2ktest(int dummy
)
3225 struct cli_state
*cli
;
3227 const char *fname
= "\\w2ktest\\w2k.tst";
3229 bool correct
= True
;
3231 printf("starting w2k test\n");
3233 if (!torture_open_connection(&cli
, 0)) {
3237 cli_open(cli
, fname
,
3238 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3240 for (level
= 1004; level
< 1040; level
++) {
3241 new_trans(cli
, fnum
, level
);
3244 cli_close(cli
, fnum
);
3246 if (!torture_close_connection(cli
)) {
3250 printf("w2k test finished\n");
3257 this is a harness for some oplock tests
3259 static bool run_oplock1(int dummy
)
3261 struct cli_state
*cli1
;
3262 const char *fname
= "\\lockt1.lck";
3264 bool correct
= True
;
3266 printf("starting oplock test 1\n");
3268 if (!torture_open_connection(&cli1
, 0)) {
3272 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3274 cli_sockopt(cli1
, sockops
);
3276 cli1
->use_oplocks
= True
;
3278 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3279 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3283 cli1
->use_oplocks
= False
;
3285 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3286 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3288 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3289 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3293 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3294 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3298 if (!torture_close_connection(cli1
)) {
3302 printf("finished oplock test 1\n");
3307 static bool run_oplock2(int dummy
)
3309 struct cli_state
*cli1
, *cli2
;
3310 const char *fname
= "\\lockt2.lck";
3311 uint16_t fnum1
, fnum2
;
3312 int saved_use_oplocks
= use_oplocks
;
3314 bool correct
= True
;
3315 volatile bool *shared_correct
;
3317 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3318 *shared_correct
= True
;
3320 use_level_II_oplocks
= True
;
3323 printf("starting oplock test 2\n");
3325 if (!torture_open_connection(&cli1
, 0)) {
3326 use_level_II_oplocks
= False
;
3327 use_oplocks
= saved_use_oplocks
;
3331 cli1
->use_oplocks
= True
;
3332 cli1
->use_level_II_oplocks
= True
;
3334 if (!torture_open_connection(&cli2
, 1)) {
3335 use_level_II_oplocks
= False
;
3336 use_oplocks
= saved_use_oplocks
;
3340 cli2
->use_oplocks
= True
;
3341 cli2
->use_level_II_oplocks
= True
;
3343 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3345 cli_sockopt(cli1
, sockops
);
3346 cli_sockopt(cli2
, sockops
);
3348 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3349 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3353 /* Don't need the globals any more. */
3354 use_level_II_oplocks
= False
;
3355 use_oplocks
= saved_use_oplocks
;
3359 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3360 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3361 *shared_correct
= False
;
3367 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3368 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3369 *shared_correct
= False
;
3377 /* Ensure cli1 processes the break. Empty file should always return 0
3380 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3381 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3385 /* Should now be at level II. */
3386 /* Test if sending a write locks causes a break to none. */
3388 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3389 printf("lock failed (%s)\n", cli_errstr(cli1
));
3393 cli_unlock(cli1
, fnum1
, 0, 4);
3397 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3398 printf("lock failed (%s)\n", cli_errstr(cli1
));
3402 cli_unlock(cli1
, fnum1
, 0, 4);
3406 cli_read(cli1
, fnum1
, buf
, 0, 4);
3408 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3409 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3415 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3416 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3420 if (!torture_close_connection(cli1
)) {
3424 if (!*shared_correct
) {
3428 printf("finished oplock test 2\n");
3433 /* handler for oplock 3 tests */
3434 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3436 printf("got oplock break fnum=%d level=%d\n",
3438 return cli_oplock_ack(cli
, fnum
, level
);
3441 static bool run_oplock3(int dummy
)
3443 struct cli_state
*cli
;
3444 const char *fname
= "\\oplockt3.dat";
3446 char buf
[4] = "abcd";
3447 bool correct
= True
;
3448 volatile bool *shared_correct
;
3450 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3451 *shared_correct
= True
;
3453 printf("starting oplock test 3\n");
3458 use_level_II_oplocks
= True
;
3459 if (!torture_open_connection(&cli
, 0)) {
3460 *shared_correct
= False
;
3464 /* try to trigger a oplock break in parent */
3465 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3466 cli_writeall(cli
, fnum
, 0, (uint8_t *)buf
, 0, 4, NULL
);
3472 use_level_II_oplocks
= True
;
3473 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3476 cli_oplock_handler(cli
, oplock3_handler
);
3477 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3478 cli_writeall(cli
, fnum
, 0, (uint8_t *)buf
, 0, 4, NULL
);
3479 cli_close(cli
, fnum
);
3480 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3481 cli
->timeout
= 20000;
3482 cli_receive_smb(cli
);
3483 printf("finished oplock test 3\n");
3485 return (correct
&& *shared_correct
);
3487 /* What are we looking for here? What's sucess and what's FAILURE? */
3490 /* handler for oplock 4 tests */
3491 bool *oplock4_shared_correct
;
3493 static NTSTATUS
oplock4_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3495 printf("got oplock break fnum=%d level=%d\n",
3497 *oplock4_shared_correct
= true;
3498 cli_oplock_ack(cli
, fnum
, level
);
3499 return NT_STATUS_UNSUCCESSFUL
; /* Cause cli_receive_smb to return. */
3502 static bool run_oplock4(int dummy
)
3504 struct cli_state
*cli1
, *cli2
;
3505 const char *fname
= "\\lockt4.lck";
3506 const char *fname_ln
= "\\lockt4_ln.lck";
3507 uint16_t fnum1
, fnum2
;
3508 int saved_use_oplocks
= use_oplocks
;
3510 bool correct
= true;
3512 oplock4_shared_correct
= (bool *)shm_setup(sizeof(bool));
3513 *oplock4_shared_correct
= false;
3515 printf("starting oplock test 4\n");
3517 if (!torture_open_connection(&cli1
, 0)) {
3518 use_level_II_oplocks
= false;
3519 use_oplocks
= saved_use_oplocks
;
3523 if (!torture_open_connection(&cli2
, 1)) {
3524 use_level_II_oplocks
= false;
3525 use_oplocks
= saved_use_oplocks
;
3529 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3530 cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
);
3532 cli_sockopt(cli1
, sockops
);
3533 cli_sockopt(cli2
, sockops
);
3535 /* Create the file. */
3536 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3537 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3541 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3542 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3546 /* Now create a hardlink. */
3547 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1
, fname
, fname_ln
))) {
3548 printf("nt hardlink failed (%s)\n", cli_errstr(cli1
));
3552 /* Prove that opening hardlinks cause deny modes to conflict. */
3553 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
))) {
3554 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3558 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3559 if (NT_STATUS_IS_OK(status
)) {
3560 printf("open of %s succeeded - should fail with sharing violation.\n",
3565 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3566 printf("open of %s should fail with sharing violation. Got %s\n",
3567 fname_ln
, nt_errstr(status
));
3571 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3572 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3576 cli1
->use_oplocks
= true;
3577 cli1
->use_level_II_oplocks
= true;
3579 cli2
->use_oplocks
= true;
3580 cli2
->use_level_II_oplocks
= true;
3582 cli_oplock_handler(cli1
, oplock4_handler
);
3583 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3584 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3590 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3591 printf("open of %s failed (%s)\n", fname_ln
, cli_errstr(cli1
));
3592 *oplock4_shared_correct
= false;
3596 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3597 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3598 *oplock4_shared_correct
= false;
3606 /* Process the oplock break. */
3607 cli_receive_smb(cli1
);
3609 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3610 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3614 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3615 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3618 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname_ln
, aSYSTEM
| aHIDDEN
))) {
3619 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3623 if (!torture_close_connection(cli1
)) {
3627 if (!*oplock4_shared_correct
) {
3631 printf("finished oplock test 4\n");
3638 Test delete on close semantics.
3640 static bool run_deletetest(int dummy
)
3642 struct cli_state
*cli1
= NULL
;
3643 struct cli_state
*cli2
= NULL
;
3644 const char *fname
= "\\delete.file";
3645 uint16_t fnum1
= (uint16_t)-1;
3646 uint16_t fnum2
= (uint16_t)-1;
3647 bool correct
= True
;
3649 printf("starting delete test\n");
3651 if (!torture_open_connection(&cli1
, 0)) {
3655 cli_sockopt(cli1
, sockops
);
3657 /* Test 1 - this should delete the file on close. */
3659 cli_setatr(cli1
, fname
, 0, 0);
3660 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3662 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3663 0, FILE_OVERWRITE_IF
,
3664 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3665 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3670 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3671 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3676 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3677 printf("[1] open of %s succeeded (should fail)\n", fname
);
3682 printf("first delete on close test succeeded.\n");
3684 /* Test 2 - this should delete the file on close. */
3686 cli_setatr(cli1
, fname
, 0, 0);
3687 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3689 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3690 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3691 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3692 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3697 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3698 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3703 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3704 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3709 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3710 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3711 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3712 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3716 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3718 printf("second delete on close test succeeded.\n");
3721 cli_setatr(cli1
, fname
, 0, 0);
3722 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3724 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3725 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3726 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3731 /* This should fail with a sharing violation - open for delete is only compatible
3732 with SHARE_DELETE. */
3734 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3735 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3736 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3741 /* This should succeed. */
3743 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3744 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3745 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3750 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3751 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3756 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3757 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3762 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3763 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3768 /* This should fail - file should no longer be there. */
3770 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3771 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3772 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3773 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3775 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3779 printf("third delete on close test succeeded.\n");
3782 cli_setatr(cli1
, fname
, 0, 0);
3783 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3785 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3786 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3787 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3792 /* This should succeed. */
3793 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3794 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3795 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3800 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3801 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3806 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3807 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3812 /* This should fail - no more opens once delete on close set. */
3813 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3814 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3815 FILE_OPEN
, 0, 0, &fnum2
))) {
3816 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3820 printf("fourth delete on close test succeeded.\n");
3822 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3823 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3829 cli_setatr(cli1
, fname
, 0, 0);
3830 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3832 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3833 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3838 /* This should fail - only allowed on NT opens with DELETE access. */
3840 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3841 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3846 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3847 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3852 printf("fifth delete on close test succeeded.\n");
3855 cli_setatr(cli1
, fname
, 0, 0);
3856 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3858 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3859 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3860 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3861 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3866 /* This should fail - only allowed on NT opens with DELETE access. */
3868 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3869 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3874 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3875 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3880 printf("sixth delete on close test succeeded.\n");
3883 cli_setatr(cli1
, fname
, 0, 0);
3884 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3886 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3887 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3888 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3893 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3894 printf("[7] setting delete_on_close on file failed !\n");
3899 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3900 printf("[7] unsetting delete_on_close on file failed !\n");
3905 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3906 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3911 /* This next open should succeed - we reset the flag. */
3913 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3914 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3919 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3920 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3925 printf("seventh delete on close test succeeded.\n");
3928 cli_setatr(cli1
, fname
, 0, 0);
3929 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3931 if (!torture_open_connection(&cli2
, 1)) {
3932 printf("[8] failed to open second connection.\n");
3937 cli_sockopt(cli1
, sockops
);
3939 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3940 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3941 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3942 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3947 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3948 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3949 FILE_OPEN
, 0, 0, &fnum2
))) {
3950 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3955 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3956 printf("[8] setting delete_on_close on file failed !\n");
3961 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3962 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3967 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3968 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3973 /* This should fail.. */
3974 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3975 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3979 printf("eighth delete on close test succeeded.\n");
3981 /* This should fail - we need to set DELETE_ACCESS. */
3982 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3983 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3984 printf("[9] open of %s succeeded should have failed!\n", fname
);
3989 printf("ninth delete on close test succeeded.\n");
3991 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3992 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3993 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3998 /* This should delete the file. */
3999 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4000 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
4005 /* This should fail.. */
4006 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4007 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4011 printf("tenth delete on close test succeeded.\n");
4013 cli_setatr(cli1
, fname
, 0, 0);
4014 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4016 /* What error do we get when attempting to open a read-only file with
4019 /* Create a readonly file. */
4020 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4021 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4022 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4027 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4028 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
4033 /* Now try open for delete access. */
4034 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4035 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4036 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4037 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
4038 cli_close(cli1
, fnum1
);
4042 NTSTATUS nterr
= cli_nt_error(cli1
);
4043 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
4044 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
4048 printf("eleventh delete on close test succeeded.\n");
4052 printf("finished delete test\n");
4055 /* FIXME: This will crash if we aborted before cli2 got
4056 * intialized, because these functions don't handle
4057 * uninitialized connections. */
4059 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4060 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4061 cli_setatr(cli1
, fname
, 0, 0);
4062 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4064 if (cli1
&& !torture_close_connection(cli1
)) {
4067 if (cli2
&& !torture_close_connection(cli2
)) {
4073 static bool run_deletetest_ln(int dummy
)
4075 struct cli_state
*cli
;
4076 const char *fname
= "\\delete1";
4077 const char *fname_ln
= "\\delete1_ln";
4081 bool correct
= true;
4084 printf("starting deletetest-ln\n");
4086 if (!torture_open_connection(&cli
, 0)) {
4090 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4091 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4093 cli_sockopt(cli
, sockops
);
4095 /* Create the file. */
4096 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4097 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4101 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum
))) {
4102 printf("close1 failed (%s)\n", cli_errstr(cli
));
4106 /* Now create a hardlink. */
4107 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli
, fname
, fname_ln
))) {
4108 printf("nt hardlink failed (%s)\n", cli_errstr(cli
));
4112 /* Open the original file. */
4113 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4114 FILE_ATTRIBUTE_NORMAL
,
4115 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4116 FILE_OPEN_IF
, 0, 0, &fnum
);
4117 if (!NT_STATUS_IS_OK(status
)) {
4118 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4122 /* Unlink the hard link path. */
4123 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4124 FILE_ATTRIBUTE_NORMAL
,
4125 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4126 FILE_OPEN_IF
, 0, 0, &fnum1
);
4127 if (!NT_STATUS_IS_OK(status
)) {
4128 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4131 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4132 if (!NT_STATUS_IS_OK(status
)) {
4133 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4134 __location__
, fname_ln
, nt_errstr(status
));
4138 status
= cli_close(cli
, fnum1
);
4139 if (!NT_STATUS_IS_OK(status
)) {
4140 printf("close %s failed (%s)\n",
4141 fname_ln
, nt_errstr(status
));
4145 status
= cli_close(cli
, fnum
);
4146 if (!NT_STATUS_IS_OK(status
)) {
4147 printf("close %s failed (%s)\n",
4148 fname
, nt_errstr(status
));
4152 /* Ensure the original file is still there. */
4153 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4154 if (!NT_STATUS_IS_OK(status
)) {
4155 printf("%s getatr on file %s failed (%s)\n",
4162 /* Ensure the link path is gone. */
4163 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4164 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4165 printf("%s, getatr for file %s returned wrong error code %s "
4166 "- should have been deleted\n",
4168 fname_ln
, nt_errstr(status
));
4172 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4173 cli_unlink(cli
, fname_ln
, aSYSTEM
| aHIDDEN
);
4175 if (!torture_close_connection(cli
)) {
4179 printf("finished deletetest-ln\n");
4185 print out server properties
4187 static bool run_properties(int dummy
)
4189 struct cli_state
*cli
;
4190 bool correct
= True
;
4192 printf("starting properties test\n");
4196 if (!torture_open_connection(&cli
, 0)) {
4200 cli_sockopt(cli
, sockops
);
4202 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
4204 if (!torture_close_connection(cli
)) {
4213 /* FIRST_DESIRED_ACCESS 0xf019f */
4214 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4215 FILE_READ_EA| /* 0xf */ \
4216 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4217 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4218 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4219 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4220 /* SECOND_DESIRED_ACCESS 0xe0080 */
4221 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4222 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4223 WRITE_OWNER_ACCESS /* 0xe0000 */
4226 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4227 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4229 WRITE_OWNER_ACCESS /* */
4233 Test ntcreate calls made by xcopy
4235 static bool run_xcopy(int dummy
)
4237 static struct cli_state
*cli1
;
4238 const char *fname
= "\\test.txt";
4239 bool correct
= True
;
4240 uint16_t fnum1
, fnum2
;
4242 printf("starting xcopy test\n");
4244 if (!torture_open_connection(&cli1
, 0)) {
4248 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4249 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
4250 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
4251 0x4044, 0, &fnum1
))) {
4252 printf("First open failed - %s\n", cli_errstr(cli1
));
4256 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
4257 SECOND_DESIRED_ACCESS
, 0,
4258 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
4259 0x200000, 0, &fnum2
))) {
4260 printf("second open failed - %s\n", cli_errstr(cli1
));
4264 if (!torture_close_connection(cli1
)) {
4272 Test rename on files open with share delete and no share delete.
4274 static bool run_rename(int dummy
)
4276 static struct cli_state
*cli1
;
4277 const char *fname
= "\\test.txt";
4278 const char *fname1
= "\\test1.txt";
4279 bool correct
= True
;
4284 printf("starting rename test\n");
4286 if (!torture_open_connection(&cli1
, 0)) {
4290 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4291 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4293 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4294 printf("First open failed - %s\n", cli_errstr(cli1
));
4298 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4299 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
4301 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4305 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4306 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
4310 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4311 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4312 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4314 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4316 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4318 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4319 if (!NT_STATUS_IS_OK(status
)) {
4320 printf("Second open failed - %s\n", cli_errstr(cli1
));
4324 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4325 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
4328 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4331 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4332 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
4336 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4337 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4339 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4340 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4341 printf("Third open failed - %s\n", cli_errstr(cli1
));
4350 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4351 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4352 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4355 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4356 printf("[8] setting delete_on_close on file failed !\n");
4360 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4361 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4367 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4368 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
4371 printf("Third rename succeeded (SHARE_NONE)\n");
4374 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4375 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
4379 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4380 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4384 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4385 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4386 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4390 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4391 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
4393 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4397 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4398 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4402 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4403 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4407 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4408 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4409 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
4413 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
4414 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4418 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
4422 * Now check if the first name still exists ...
4425 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4426 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4427 printf("Opening original file after rename of open file fails: %s\n",
4431 printf("Opening original file after rename of open file works ...\n");
4432 (void)cli_close(cli1, fnum2);
4436 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4437 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
4441 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4442 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
))) {
4443 printf("getatr on file %s failed - %s ! \n",
4448 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4449 printf("Renamed file %s has wrong attr 0x%x "
4450 "(should be 0x%x)\n",
4453 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4456 printf("Renamed file %s has archive bit set\n", fname1
);
4460 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4461 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
4463 if (!torture_close_connection(cli1
)) {
4470 static bool run_pipe_number(int dummy
)
4472 struct cli_state
*cli1
;
4473 const char *pipe_name
= "\\SPOOLSS";
4477 printf("starting pipenumber test\n");
4478 if (!torture_open_connection(&cli1
, 0)) {
4482 cli_sockopt(cli1
, sockops
);
4484 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4485 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
4486 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
4490 printf("\r%6d", num_pipes
);
4493 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4494 torture_close_connection(cli1
);
4499 Test open mode returns on read-only files.
4501 static bool run_opentest(int dummy
)
4503 static struct cli_state
*cli1
;
4504 static struct cli_state
*cli2
;
4505 const char *fname
= "\\readonly.file";
4506 uint16_t fnum1
, fnum2
;
4509 bool correct
= True
;
4513 printf("starting open test\n");
4515 if (!torture_open_connection(&cli1
, 0)) {
4519 cli_setatr(cli1
, fname
, 0, 0);
4520 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4522 cli_sockopt(cli1
, sockops
);
4524 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4525 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4529 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4530 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4534 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4535 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
4539 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4540 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4544 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4545 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4547 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4548 NT_STATUS_ACCESS_DENIED
)) {
4549 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4552 printf("finished open test 1\n");
4554 cli_close(cli1
, fnum1
);
4556 /* Now try not readonly and ensure ERRbadshare is returned. */
4558 cli_setatr(cli1
, fname
, 0, 0);
4560 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4561 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4565 /* This will fail - but the error should be ERRshare. */
4566 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4568 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4569 NT_STATUS_SHARING_VIOLATION
)) {
4570 printf("correct error code ERRDOS/ERRbadshare returned\n");
4573 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4574 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4578 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4580 printf("finished open test 2\n");
4582 /* Test truncate open disposition on file opened for read. */
4584 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4585 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4589 /* write 20 bytes. */
4591 memset(buf
, '\0', 20);
4593 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4594 if (!NT_STATUS_IS_OK(status
)) {
4595 printf("write failed (%s)\n", nt_errstr(status
));
4599 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4600 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4604 /* Ensure size == 20. */
4605 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4606 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4611 printf("(3) file size != 20\n");
4615 /* Now test if we can truncate a file opened for readonly. */
4617 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4618 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4622 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4623 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4627 /* Ensure size == 0. */
4628 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4629 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4634 printf("(3) file size != 0\n");
4637 printf("finished open test 3\n");
4639 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4641 printf("Do ctemp tests\n");
4642 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4643 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4646 printf("ctemp gave path %s\n", tmp_path
);
4647 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4648 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4650 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4651 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4654 /* Test the non-io opens... */
4656 if (!torture_open_connection(&cli2
, 1)) {
4660 cli_setatr(cli2
, fname
, 0, 0);
4661 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4663 cli_sockopt(cli2
, sockops
);
4665 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4667 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4668 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4669 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4673 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4674 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4675 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4679 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4680 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4683 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4684 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4688 printf("non-io open test #1 passed.\n");
4690 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4692 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4694 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4695 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4696 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4701 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4702 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4706 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4707 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4710 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4711 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4715 printf("non-io open test #2 passed.\n");
4717 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4719 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4721 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4722 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4723 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4727 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4728 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4729 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4733 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4734 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4737 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4738 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4742 printf("non-io open test #3 passed.\n");
4744 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4746 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4748 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4749 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4750 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4754 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4755 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4756 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4760 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4762 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4763 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4767 printf("non-io open test #4 passed.\n");
4769 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4771 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4773 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4774 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4775 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4779 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4780 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4781 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4785 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4786 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4790 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4791 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4795 printf("non-io open test #5 passed.\n");
4797 printf("TEST #6 testing 1 non-io open, one io open\n");
4799 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4801 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4802 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4803 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4807 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4808 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4809 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4813 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4814 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4818 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4819 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4823 printf("non-io open test #6 passed.\n");
4825 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4827 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4829 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4830 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4831 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4835 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4836 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4837 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4841 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4843 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4844 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4848 printf("non-io open test #7 passed.\n");
4850 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4852 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4853 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
4854 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4855 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4856 if (!NT_STATUS_IS_OK(status
)) {
4857 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
4862 /* Write to ensure we have to update the file time. */
4863 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)"TEST DATA\n", 0, 10,
4865 if (!NT_STATUS_IS_OK(status
)) {
4866 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
4871 status
= cli_close(cli1
, fnum1
);
4872 if (!NT_STATUS_IS_OK(status
)) {
4873 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
4879 if (!torture_close_connection(cli1
)) {
4882 if (!torture_close_connection(cli2
)) {
4889 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4891 uint16 major
, minor
;
4892 uint32 caplow
, caphigh
;
4895 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4896 printf("Server doesn't support UNIX CIFS extensions.\n");
4897 return NT_STATUS_NOT_SUPPORTED
;
4900 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4902 if (!NT_STATUS_IS_OK(status
)) {
4903 printf("Server didn't return UNIX CIFS extensions: %s\n",
4908 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4910 if (!NT_STATUS_IS_OK(status
)) {
4911 printf("Server doesn't support setting UNIX CIFS extensions: "
4912 "%s.\n", nt_errstr(status
));
4916 return NT_STATUS_OK
;
4920 Test POSIX open /mkdir calls.
4922 static bool run_simple_posix_open_test(int dummy
)
4924 static struct cli_state
*cli1
;
4925 const char *fname
= "posix:file";
4926 const char *hname
= "posix:hlink";
4927 const char *sname
= "posix:symlink";
4928 const char *dname
= "posix:dir";
4931 uint16_t fnum1
= (uint16_t)-1;
4932 SMB_STRUCT_STAT sbuf
;
4933 bool correct
= false;
4936 printf("Starting simple POSIX open test\n");
4938 if (!torture_open_connection(&cli1
, 0)) {
4942 cli_sockopt(cli1
, sockops
);
4944 status
= torture_setup_unix_extensions(cli1
);
4945 if (!NT_STATUS_IS_OK(status
)) {
4949 cli_setatr(cli1
, fname
, 0, 0);
4950 cli_posix_unlink(cli1
, fname
);
4951 cli_setatr(cli1
, dname
, 0, 0);
4952 cli_posix_rmdir(cli1
, dname
);
4953 cli_setatr(cli1
, hname
, 0, 0);
4954 cli_posix_unlink(cli1
, hname
);
4955 cli_setatr(cli1
, sname
, 0, 0);
4956 cli_posix_unlink(cli1
, sname
);
4958 /* Create a directory. */
4959 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4960 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4964 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4965 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4969 /* Test ftruncate - set file size. */
4970 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4971 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4975 /* Ensure st_size == 1000 */
4976 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4977 printf("stat failed (%s)\n", cli_errstr(cli1
));
4981 if (sbuf
.st_ex_size
!= 1000) {
4982 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4986 /* Test ftruncate - set file size back to zero. */
4987 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4988 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4992 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4993 printf("close failed (%s)\n", cli_errstr(cli1
));
4997 /* Now open the file again for read only. */
4998 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4999 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
5003 /* Now unlink while open. */
5004 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
5005 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
5009 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5010 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
5014 /* Ensure the file has gone. */
5015 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
5016 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5020 /* What happens when we try and POSIX open a directory ? */
5021 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
5022 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5025 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
5026 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5031 /* Create the file. */
5032 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
5033 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
5037 /* Write some data into it. */
5038 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5040 if (!NT_STATUS_IS_OK(status
)) {
5041 printf("cli_write failed: %s\n", nt_errstr(status
));
5045 cli_close(cli1
, fnum1
);
5047 /* Now create a hardlink. */
5048 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
5049 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5053 /* Now create a symlink. */
5054 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
5055 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
5059 /* Open the hardlink for read. */
5060 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
5061 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5065 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
5066 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5070 if (memcmp(buf
, "TEST DATA\n", 10)) {
5071 printf("invalid data read from hardlink\n");
5075 /* Do a POSIX lock/unlock. */
5076 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
5077 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
5081 /* Punch a hole in the locked area. */
5082 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
5083 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
5087 cli_close(cli1
, fnum1
);
5089 /* Open the symlink for read - this should fail. A POSIX
5090 client should not be doing opens on a symlink. */
5091 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
5092 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5095 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
5096 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5097 printf("POSIX open of %s should have failed "
5098 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5099 "failed with %s instead.\n",
5100 sname
, cli_errstr(cli1
));
5105 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
5106 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
5110 if (strcmp(namebuf
, fname
) != 0) {
5111 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5112 sname
, fname
, namebuf
);
5116 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
5117 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
5121 printf("Simple POSIX open test passed\n");
5126 if (fnum1
!= (uint16_t)-1) {
5127 cli_close(cli1
, fnum1
);
5128 fnum1
= (uint16_t)-1;
5131 cli_setatr(cli1
, sname
, 0, 0);
5132 cli_posix_unlink(cli1
, sname
);
5133 cli_setatr(cli1
, hname
, 0, 0);
5134 cli_posix_unlink(cli1
, hname
);
5135 cli_setatr(cli1
, fname
, 0, 0);
5136 cli_posix_unlink(cli1
, fname
);
5137 cli_setatr(cli1
, dname
, 0, 0);
5138 cli_posix_rmdir(cli1
, dname
);
5140 if (!torture_close_connection(cli1
)) {
5148 static uint32 open_attrs_table
[] = {
5149 FILE_ATTRIBUTE_NORMAL
,
5150 FILE_ATTRIBUTE_ARCHIVE
,
5151 FILE_ATTRIBUTE_READONLY
,
5152 FILE_ATTRIBUTE_HIDDEN
,
5153 FILE_ATTRIBUTE_SYSTEM
,
5155 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5156 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5157 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5158 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5159 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5160 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5162 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5163 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5164 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5165 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5168 struct trunc_open_results
{
5175 static struct trunc_open_results attr_results
[] = {
5176 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5177 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5178 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5179 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5180 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5181 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5182 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5183 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5184 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5185 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5186 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5187 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5188 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5189 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5190 { 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
},
5191 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5192 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5193 { 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
},
5194 { 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
},
5195 { 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
},
5196 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5197 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5198 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5199 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5200 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5201 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5204 static bool run_openattrtest(int dummy
)
5206 static struct cli_state
*cli1
;
5207 const char *fname
= "\\openattr.file";
5209 bool correct
= True
;
5211 unsigned int i
, j
, k
, l
;
5213 printf("starting open attr test\n");
5215 if (!torture_open_connection(&cli1
, 0)) {
5219 cli_sockopt(cli1
, sockops
);
5221 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5222 cli_setatr(cli1
, fname
, 0, 0);
5223 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5224 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
5225 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
5226 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5230 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5231 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
5235 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5236 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
5237 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
5238 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5239 if (attr_results
[l
].num
== k
) {
5240 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5241 k
, open_attrs_table
[i
],
5242 open_attrs_table
[j
],
5243 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
5247 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
5248 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5249 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5254 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5260 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
5261 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
5265 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
5266 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
5271 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5272 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5275 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5276 if (attr_results
[l
].num
== k
) {
5277 if (attr
!= attr_results
[l
].result_attr
||
5278 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5279 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5280 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5281 open_attrs_table
[i
],
5282 open_attrs_table
[j
],
5284 attr_results
[l
].result_attr
);
5294 cli_setatr(cli1
, fname
, 0, 0);
5295 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
5297 printf("open attr test %s.\n", correct
? "passed" : "failed");
5299 if (!torture_close_connection(cli1
)) {
5305 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5306 const char *name
, void *state
)
5308 int *matched
= (int *)state
;
5309 if (matched
!= NULL
) {
5312 return NT_STATUS_OK
;
5316 test directory listing speed
5318 static bool run_dirtest(int dummy
)
5321 static struct cli_state
*cli
;
5323 struct timeval core_start
;
5324 bool correct
= True
;
5327 printf("starting directory test\n");
5329 if (!torture_open_connection(&cli
, 0)) {
5333 cli_sockopt(cli
, sockops
);
5336 for (i
=0;i
<torture_numops
;i
++) {
5338 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5339 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5340 fprintf(stderr
,"Failed to open %s\n", fname
);
5343 cli_close(cli
, fnum
);
5346 core_start
= timeval_current();
5349 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5350 printf("Matched %d\n", matched
);
5353 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5354 printf("Matched %d\n", matched
);
5357 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5358 printf("Matched %d\n", matched
);
5360 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5363 for (i
=0;i
<torture_numops
;i
++) {
5365 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5366 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5369 if (!torture_close_connection(cli
)) {
5373 printf("finished dirtest\n");
5378 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5381 struct cli_state
*pcli
= (struct cli_state
*)state
;
5383 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5385 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5386 return NT_STATUS_OK
;
5388 if (finfo
->mode
& aDIR
) {
5389 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5390 printf("del_fn: failed to rmdir %s\n,", fname
);
5392 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
5393 printf("del_fn: failed to unlink %s\n,", fname
);
5395 return NT_STATUS_OK
;
5400 sees what IOCTLs are supported
5402 bool torture_ioctl_test(int dummy
)
5404 static struct cli_state
*cli
;
5405 uint16_t device
, function
;
5407 const char *fname
= "\\ioctl.dat";
5411 if (!torture_open_connection(&cli
, 0)) {
5415 printf("starting ioctl test\n");
5417 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5419 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5420 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
5424 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5425 printf("ioctl device info: %s\n", nt_errstr(status
));
5427 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5428 printf("ioctl job info: %s\n", nt_errstr(status
));
5430 for (device
=0;device
<0x100;device
++) {
5431 printf("ioctl test with device = 0x%x\n", device
);
5432 for (function
=0;function
<0x100;function
++) {
5433 uint32 code
= (device
<<16) | function
;
5435 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5437 if (NT_STATUS_IS_OK(status
)) {
5438 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5440 data_blob_free(&blob
);
5445 if (!torture_close_connection(cli
)) {
5454 tries varients of chkpath
5456 bool torture_chkpath_test(int dummy
)
5458 static struct cli_state
*cli
;
5462 if (!torture_open_connection(&cli
, 0)) {
5466 printf("starting chkpath test\n");
5468 /* cleanup from an old run */
5469 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5470 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5471 cli_rmdir(cli
, "\\chkpath.dir");
5473 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
5474 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
5478 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
5479 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
5483 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5484 printf("open1 failed (%s)\n", cli_errstr(cli
));
5487 cli_close(cli
, fnum
);
5489 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
5490 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
5494 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
5495 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
5499 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
5500 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5501 NT_STATUS_NOT_A_DIRECTORY
);
5503 printf("* chkpath on a file should fail\n");
5507 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
5508 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
5509 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
5511 printf("* chkpath on a non existant file should fail\n");
5515 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5516 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5517 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
5519 printf("* chkpath on a non existent component should fail\n");
5523 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5524 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
5525 cli_rmdir(cli
, "\\chkpath.dir");
5527 if (!torture_close_connection(cli
)) {
5534 static bool run_eatest(int dummy
)
5536 static struct cli_state
*cli
;
5537 const char *fname
= "\\eatest.txt";
5538 bool correct
= True
;
5542 struct ea_struct
*ea_list
= NULL
;
5543 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5546 printf("starting eatest\n");
5548 if (!torture_open_connection(&cli
, 0)) {
5549 talloc_destroy(mem_ctx
);
5553 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5554 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5555 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5556 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5557 0x4044, 0, &fnum
))) {
5558 printf("open failed - %s\n", cli_errstr(cli
));
5559 talloc_destroy(mem_ctx
);
5563 for (i
= 0; i
< 10; i
++) {
5564 fstring ea_name
, ea_val
;
5566 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5567 memset(ea_val
, (char)i
+1, i
+1);
5568 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
5569 if (!NT_STATUS_IS_OK(status
)) {
5570 printf("ea_set of name %s failed - %s\n", ea_name
,
5572 talloc_destroy(mem_ctx
);
5577 cli_close(cli
, fnum
);
5578 for (i
= 0; i
< 10; i
++) {
5579 fstring ea_name
, ea_val
;
5581 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5582 memset(ea_val
, (char)i
+1, i
+1);
5583 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
5584 if (!NT_STATUS_IS_OK(status
)) {
5585 printf("ea_set of name %s failed - %s\n", ea_name
,
5587 talloc_destroy(mem_ctx
);
5592 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5593 if (!NT_STATUS_IS_OK(status
)) {
5594 printf("ea_get list failed - %s\n", nt_errstr(status
));
5598 printf("num_eas = %d\n", (int)num_eas
);
5600 if (num_eas
!= 20) {
5601 printf("Should be 20 EA's stored... failing.\n");
5605 for (i
= 0; i
< num_eas
; i
++) {
5606 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5607 dump_data(0, ea_list
[i
].value
.data
,
5608 ea_list
[i
].value
.length
);
5611 /* Setting EA's to zero length deletes them. Test this */
5612 printf("Now deleting all EA's - case indepenent....\n");
5615 cli_set_ea_path(cli
, fname
, "", "", 0);
5617 for (i
= 0; i
< 20; i
++) {
5619 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5620 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
5621 if (!NT_STATUS_IS_OK(status
)) {
5622 printf("ea_set of name %s failed - %s\n", ea_name
,
5624 talloc_destroy(mem_ctx
);
5630 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
5631 if (!NT_STATUS_IS_OK(status
)) {
5632 printf("ea_get list failed - %s\n", nt_errstr(status
));
5636 printf("num_eas = %d\n", (int)num_eas
);
5637 for (i
= 0; i
< num_eas
; i
++) {
5638 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5639 dump_data(0, ea_list
[i
].value
.data
,
5640 ea_list
[i
].value
.length
);
5644 printf("deleting EA's failed.\n");
5648 /* Try and delete a non existant EA. */
5649 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
5650 if (!NT_STATUS_IS_OK(status
)) {
5651 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5656 talloc_destroy(mem_ctx
);
5657 if (!torture_close_connection(cli
)) {
5664 static bool run_dirtest1(int dummy
)
5667 static struct cli_state
*cli
;
5670 bool correct
= True
;
5672 printf("starting directory test\n");
5674 if (!torture_open_connection(&cli
, 0)) {
5678 cli_sockopt(cli
, sockops
);
5680 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5681 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5682 cli_rmdir(cli
, "\\LISTDIR");
5683 cli_mkdir(cli
, "\\LISTDIR");
5685 /* Create 1000 files and 1000 directories. */
5686 for (i
=0;i
<1000;i
++) {
5688 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5689 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5690 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5691 fprintf(stderr
,"Failed to open %s\n", fname
);
5694 cli_close(cli
, fnum
);
5696 for (i
=0;i
<1000;i
++) {
5698 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5699 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5700 fprintf(stderr
,"Failed to open %s\n", fname
);
5705 /* Now ensure that doing an old list sees both files and directories. */
5707 cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, &num_seen
);
5708 printf("num_seen = %d\n", num_seen
);
5709 /* We should see 100 files + 1000 directories + . and .. */
5710 if (num_seen
!= 2002)
5713 /* Ensure if we have the "must have" bits we only see the
5717 cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, &num_seen
);
5718 printf("num_seen = %d\n", num_seen
);
5719 if (num_seen
!= 1002)
5723 cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, &num_seen
);
5724 printf("num_seen = %d\n", num_seen
);
5725 if (num_seen
!= 1000)
5728 /* Delete everything. */
5729 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5730 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5731 cli_rmdir(cli
, "\\LISTDIR");
5734 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5735 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5736 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5739 if (!torture_close_connection(cli
)) {
5743 printf("finished dirtest1\n");
5748 static bool run_error_map_extract(int dummy
) {
5750 static struct cli_state
*c_dos
;
5751 static struct cli_state
*c_nt
;
5756 uint32 flgs2
, errnum
;
5763 /* NT-Error connection */
5765 if (!(c_nt
= open_nbt_connection())) {
5769 c_nt
->use_spnego
= False
;
5771 status
= cli_negprot(c_nt
);
5773 if (!NT_STATUS_IS_OK(status
)) {
5774 printf("%s rejected the NT-error negprot (%s)\n", host
,
5780 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5782 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5786 /* DOS-Error connection */
5788 if (!(c_dos
= open_nbt_connection())) {
5792 c_dos
->use_spnego
= False
;
5793 c_dos
->force_dos_errors
= True
;
5795 status
= cli_negprot(c_dos
);
5796 if (!NT_STATUS_IS_OK(status
)) {
5797 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5799 cli_shutdown(c_dos
);
5803 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5805 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5809 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5810 fstr_sprintf(user
, "%X", error
);
5812 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5813 password
, strlen(password
),
5814 password
, strlen(password
),
5816 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5819 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5821 /* Case #1: 32-bit NT errors */
5822 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5823 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5825 printf("/** Dos error on NT connection! (%s) */\n",
5827 nt_status
= NT_STATUS(0xc0000000);
5830 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5831 password
, strlen(password
),
5832 password
, strlen(password
),
5834 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5836 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5838 /* Case #1: 32-bit NT errors */
5839 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5840 printf("/** NT error on DOS connection! (%s) */\n",
5842 errnum
= errclass
= 0;
5844 cli_dos_error(c_dos
, &errclass
, &errnum
);
5847 if (NT_STATUS_V(nt_status
) != error
) {
5848 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5849 get_nt_error_c_code(NT_STATUS(error
)),
5850 get_nt_error_c_code(nt_status
));
5853 printf("\t{%s,\t%s,\t%s},\n",
5854 smb_dos_err_class(errclass
),
5855 smb_dos_err_name(errclass
, errnum
),
5856 get_nt_error_c_code(NT_STATUS(error
)));
5861 static bool run_sesssetup_bench(int dummy
)
5863 static struct cli_state
*c
;
5864 const char *fname
= "\\file.dat";
5869 if (!torture_open_connection(&c
, 0)) {
5873 if (!NT_STATUS_IS_OK(cli_ntcreate(
5874 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5875 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5876 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5877 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5881 for (i
=0; i
<torture_numops
; i
++) {
5882 status
= cli_session_setup(
5884 password
, strlen(password
),
5885 password
, strlen(password
),
5887 if (!NT_STATUS_IS_OK(status
)) {
5888 d_printf("(%s) cli_session_setup failed: %s\n",
5889 __location__
, nt_errstr(status
));
5893 d_printf("\r%d ", (int)c
->vuid
);
5895 status
= cli_ulogoff(c
);
5896 if (!NT_STATUS_IS_OK(status
)) {
5897 d_printf("(%s) cli_ulogoff failed: %s\n",
5898 __location__
, nt_errstr(status
));
5907 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5908 uid_t uid
, gid_t gid
, const char *expected
)
5913 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5915 if (strcmp(subst
, expected
) != 0) {
5916 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5917 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5926 static void chain1_open_completion(struct tevent_req
*req
)
5930 status
= cli_open_recv(req
, &fnum
);
5933 d_printf("cli_open_recv returned %s: %d\n",
5935 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5938 static void chain1_write_completion(struct tevent_req
*req
)
5942 status
= cli_write_andx_recv(req
, &written
);
5945 d_printf("cli_write_andx_recv returned %s: %d\n",
5947 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5950 static void chain1_close_completion(struct tevent_req
*req
)
5953 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5955 status
= cli_close_recv(req
);
5960 d_printf("cli_close returned %s\n", nt_errstr(status
));
5963 static bool run_chain1(int dummy
)
5965 struct cli_state
*cli1
;
5966 struct event_context
*evt
= event_context_init(NULL
);
5967 struct tevent_req
*reqs
[3], *smbreqs
[3];
5969 const char *str
= "foobar";
5972 printf("starting chain1 test\n");
5973 if (!torture_open_connection(&cli1
, 0)) {
5977 cli_sockopt(cli1
, sockops
);
5979 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5980 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5981 if (reqs
[0] == NULL
) return false;
5982 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5985 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5986 (uint8_t *)str
, 0, strlen(str
)+1,
5987 smbreqs
, 1, &smbreqs
[1]);
5988 if (reqs
[1] == NULL
) return false;
5989 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5991 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5992 if (reqs
[2] == NULL
) return false;
5993 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5995 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5996 if (!NT_STATUS_IS_OK(status
)) {
6001 event_loop_once(evt
);
6004 torture_close_connection(cli1
);
6008 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6011 status
= cli_session_setup_guest_recv(req
);
6012 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6015 static void chain2_tcon_completion(struct tevent_req
*req
)
6017 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6019 status
= cli_tcon_andx_recv(req
);
6020 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6024 static bool run_chain2(int dummy
)
6026 struct cli_state
*cli1
;
6027 struct event_context
*evt
= event_context_init(NULL
);
6028 struct tevent_req
*reqs
[2], *smbreqs
[2];
6032 printf("starting chain2 test\n");
6033 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
6034 port_to_use
, Undefined
, 0);
6035 if (!NT_STATUS_IS_OK(status
)) {
6039 cli_sockopt(cli1
, sockops
);
6041 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6043 if (reqs
[0] == NULL
) return false;
6044 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6046 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6047 "?????", NULL
, 0, &smbreqs
[1]);
6048 if (reqs
[1] == NULL
) return false;
6049 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6051 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6052 if (!NT_STATUS_IS_OK(status
)) {
6057 event_loop_once(evt
);
6060 torture_close_connection(cli1
);
6065 struct torture_createdel_state
{
6066 struct tevent_context
*ev
;
6067 struct cli_state
*cli
;
6070 static void torture_createdel_created(struct tevent_req
*subreq
);
6071 static void torture_createdel_closed(struct tevent_req
*subreq
);
6073 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6074 struct tevent_context
*ev
,
6075 struct cli_state
*cli
,
6078 struct tevent_req
*req
, *subreq
;
6079 struct torture_createdel_state
*state
;
6081 req
= tevent_req_create(mem_ctx
, &state
,
6082 struct torture_createdel_state
);
6089 subreq
= cli_ntcreate_send(
6090 state
, ev
, cli
, name
, 0,
6091 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6092 FILE_ATTRIBUTE_NORMAL
,
6093 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6094 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6096 if (tevent_req_nomem(subreq
, req
)) {
6097 return tevent_req_post(req
, ev
);
6099 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6103 static void torture_createdel_created(struct tevent_req
*subreq
)
6105 struct tevent_req
*req
= tevent_req_callback_data(
6106 subreq
, struct tevent_req
);
6107 struct torture_createdel_state
*state
= tevent_req_data(
6108 req
, struct torture_createdel_state
);
6112 status
= cli_ntcreate_recv(subreq
, &fnum
);
6113 TALLOC_FREE(subreq
);
6114 if (!NT_STATUS_IS_OK(status
)) {
6115 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6116 nt_errstr(status
)));
6117 tevent_req_nterror(req
, status
);
6121 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6122 if (tevent_req_nomem(subreq
, req
)) {
6125 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6128 static void torture_createdel_closed(struct tevent_req
*subreq
)
6130 struct tevent_req
*req
= tevent_req_callback_data(
6131 subreq
, struct tevent_req
);
6134 status
= cli_close_recv(subreq
);
6135 if (!NT_STATUS_IS_OK(status
)) {
6136 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6137 tevent_req_nterror(req
, status
);
6140 tevent_req_done(req
);
6143 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6145 return tevent_req_simple_recv_ntstatus(req
);
6148 struct torture_createdels_state
{
6149 struct tevent_context
*ev
;
6150 struct cli_state
*cli
;
6151 const char *base_name
;
6155 struct tevent_req
**reqs
;
6158 static void torture_createdels_done(struct tevent_req
*subreq
);
6160 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6161 struct tevent_context
*ev
,
6162 struct cli_state
*cli
,
6163 const char *base_name
,
6167 struct tevent_req
*req
;
6168 struct torture_createdels_state
*state
;
6171 req
= tevent_req_create(mem_ctx
, &state
,
6172 struct torture_createdels_state
);
6178 state
->base_name
= talloc_strdup(state
, base_name
);
6179 if (tevent_req_nomem(state
->base_name
, req
)) {
6180 return tevent_req_post(req
, ev
);
6182 state
->num_files
= MAX(num_parallel
, num_files
);
6184 state
->received
= 0;
6186 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6187 if (tevent_req_nomem(state
->reqs
, req
)) {
6188 return tevent_req_post(req
, ev
);
6191 for (i
=0; i
<num_parallel
; i
++) {
6194 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6196 if (tevent_req_nomem(name
, req
)) {
6197 return tevent_req_post(req
, ev
);
6199 state
->reqs
[i
] = torture_createdel_send(
6200 state
->reqs
, state
->ev
, state
->cli
, name
);
6201 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6202 return tevent_req_post(req
, ev
);
6204 name
= talloc_move(state
->reqs
[i
], &name
);
6205 tevent_req_set_callback(state
->reqs
[i
],
6206 torture_createdels_done
, req
);
6212 static void torture_createdels_done(struct tevent_req
*subreq
)
6214 struct tevent_req
*req
= tevent_req_callback_data(
6215 subreq
, struct tevent_req
);
6216 struct torture_createdels_state
*state
= tevent_req_data(
6217 req
, struct torture_createdels_state
);
6218 size_t num_parallel
= talloc_array_length(state
->reqs
);
6223 status
= torture_createdel_recv(subreq
);
6224 if (!NT_STATUS_IS_OK(status
)){
6225 DEBUG(10, ("torture_createdel_recv returned %s\n",
6226 nt_errstr(status
)));
6227 TALLOC_FREE(subreq
);
6228 tevent_req_nterror(req
, status
);
6232 for (i
=0; i
<num_parallel
; i
++) {
6233 if (subreq
== state
->reqs
[i
]) {
6237 if (i
== num_parallel
) {
6238 DEBUG(10, ("received something we did not send\n"));
6239 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6242 TALLOC_FREE(state
->reqs
[i
]);
6244 if (state
->sent
>= state
->num_files
) {
6245 tevent_req_done(req
);
6249 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6251 if (tevent_req_nomem(name
, req
)) {
6254 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6256 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6259 name
= talloc_move(state
->reqs
[i
], &name
);
6260 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6264 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6266 return tevent_req_simple_recv_ntstatus(req
);
6269 struct swallow_notify_state
{
6270 struct tevent_context
*ev
;
6271 struct cli_state
*cli
;
6273 uint32_t completion_filter
;
6275 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6279 static void swallow_notify_done(struct tevent_req
*subreq
);
6281 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6282 struct tevent_context
*ev
,
6283 struct cli_state
*cli
,
6285 uint32_t completion_filter
,
6287 bool (*fn
)(uint32_t action
,
6292 struct tevent_req
*req
, *subreq
;
6293 struct swallow_notify_state
*state
;
6295 req
= tevent_req_create(mem_ctx
, &state
,
6296 struct swallow_notify_state
);
6303 state
->completion_filter
= completion_filter
;
6304 state
->recursive
= recursive
;
6308 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6309 0xffff, state
->completion_filter
,
6311 if (tevent_req_nomem(subreq
, req
)) {
6312 return tevent_req_post(req
, ev
);
6314 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6318 static void swallow_notify_done(struct tevent_req
*subreq
)
6320 struct tevent_req
*req
= tevent_req_callback_data(
6321 subreq
, struct tevent_req
);
6322 struct swallow_notify_state
*state
= tevent_req_data(
6323 req
, struct swallow_notify_state
);
6325 uint32_t i
, num_changes
;
6326 struct notify_change
*changes
;
6328 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6329 TALLOC_FREE(subreq
);
6330 if (!NT_STATUS_IS_OK(status
)) {
6331 DEBUG(10, ("cli_notify_recv returned %s\n",
6332 nt_errstr(status
)));
6333 tevent_req_nterror(req
, status
);
6337 for (i
=0; i
<num_changes
; i
++) {
6338 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6340 TALLOC_FREE(changes
);
6342 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6343 0xffff, state
->completion_filter
,
6345 if (tevent_req_nomem(subreq
, req
)) {
6348 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6351 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6353 if (DEBUGLEVEL
> 5) {
6354 d_printf("%d %s\n", (int)action
, name
);
6359 static void notify_bench_done(struct tevent_req
*req
)
6361 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6365 static bool run_notify_bench(int dummy
)
6367 const char *dname
= "\\notify-bench";
6368 struct tevent_context
*ev
;
6371 struct tevent_req
*req1
;
6372 struct tevent_req
*req2
= NULL
;
6373 int i
, num_unc_names
;
6374 int num_finished
= 0;
6376 printf("starting notify-bench test\n");
6378 if (use_multishare_conn
) {
6380 unc_list
= file_lines_load(multishare_conn_fname
,
6381 &num_unc_names
, 0, NULL
);
6382 if (!unc_list
|| num_unc_names
<= 0) {
6383 d_printf("Failed to load unc names list from '%s'\n",
6384 multishare_conn_fname
);
6387 TALLOC_FREE(unc_list
);
6392 ev
= tevent_context_init(talloc_tos());
6394 d_printf("tevent_context_init failed\n");
6398 for (i
=0; i
<num_unc_names
; i
++) {
6399 struct cli_state
*cli
;
6402 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6404 if (base_fname
== NULL
) {
6408 if (!torture_open_connection(&cli
, i
)) {
6412 status
= cli_ntcreate(cli
, dname
, 0,
6413 MAXIMUM_ALLOWED_ACCESS
,
6414 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6416 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6419 if (!NT_STATUS_IS_OK(status
)) {
6420 d_printf("Could not create %s: %s\n", dname
,
6425 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6426 FILE_NOTIFY_CHANGE_FILE_NAME
|
6427 FILE_NOTIFY_CHANGE_DIR_NAME
|
6428 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6429 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6430 false, print_notifies
, NULL
);
6432 d_printf("Could not create notify request\n");
6436 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6437 base_fname
, 10, torture_numops
);
6439 d_printf("Could not create createdels request\n");
6442 TALLOC_FREE(base_fname
);
6444 tevent_req_set_callback(req2
, notify_bench_done
,
6448 while (num_finished
< num_unc_names
) {
6450 ret
= tevent_loop_once(ev
);
6452 d_printf("tevent_loop_once failed\n");
6457 if (!tevent_req_poll(req2
, ev
)) {
6458 d_printf("tevent_req_poll failed\n");
6461 status
= torture_createdels_recv(req2
);
6462 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
6467 static bool run_mangle1(int dummy
)
6469 struct cli_state
*cli
;
6470 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
6474 time_t change_time
, access_time
, write_time
;
6478 printf("starting mangle1 test\n");
6479 if (!torture_open_connection(&cli
, 0)) {
6483 cli_sockopt(cli
, sockops
);
6485 if (!NT_STATUS_IS_OK(cli_ntcreate(
6486 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6487 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6488 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
6491 cli_close(cli
, fnum
);
6493 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
6494 if (!NT_STATUS_IS_OK(status
)) {
6495 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6499 d_printf("alt_name: %s\n", alt_name
);
6501 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
6502 d_printf("cli_open(%s) failed: %s\n", alt_name
,
6506 cli_close(cli
, fnum
);
6508 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
6509 &write_time
, &size
, &mode
);
6510 if (!NT_STATUS_IS_OK(status
)) {
6511 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
6519 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
6521 size_t *to_pull
= (size_t *)priv
;
6522 size_t thistime
= *to_pull
;
6524 thistime
= MIN(thistime
, n
);
6525 if (thistime
== 0) {
6529 memset(buf
, 0, thistime
);
6530 *to_pull
-= thistime
;
6534 static bool run_windows_write(int dummy
)
6536 struct cli_state
*cli1
;
6540 const char *fname
= "\\writetest.txt";
6541 struct timeval start_time
;
6545 printf("starting windows_write test\n");
6546 if (!torture_open_connection(&cli1
, 0)) {
6550 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
6551 printf("open failed (%s)\n", cli_errstr(cli1
));
6555 cli_sockopt(cli1
, sockops
);
6557 start_time
= timeval_current();
6559 for (i
=0; i
<torture_numops
; i
++) {
6561 off_t start
= i
* torture_blocksize
;
6563 size_t to_pull
= torture_blocksize
- 1;
6565 status
= cli_writeall(cli1
, fnum
, 0, &c
,
6566 start
+ torture_blocksize
- 1, 1, NULL
);
6567 if (!NT_STATUS_IS_OK(status
)) {
6568 printf("cli_write failed: %s\n", nt_errstr(status
));
6572 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6573 null_source
, &to_pull
);
6574 if (!NT_STATUS_IS_OK(status
)) {
6575 printf("cli_push returned: %s\n", nt_errstr(status
));
6580 seconds
= timeval_elapsed(&start_time
);
6581 kbytes
= (double)torture_blocksize
* torture_numops
;
6584 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6585 (double)seconds
, (int)(kbytes
/seconds
));
6589 cli_close(cli1
, fnum
);
6590 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6591 torture_close_connection(cli1
);
6595 static bool run_cli_echo(int dummy
)
6597 struct cli_state
*cli
;
6600 printf("starting cli_echo test\n");
6601 if (!torture_open_connection(&cli
, 0)) {
6604 cli_sockopt(cli
, sockops
);
6606 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6608 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6610 torture_close_connection(cli
);
6611 return NT_STATUS_IS_OK(status
);
6614 static bool run_uid_regression_test(int dummy
)
6616 static struct cli_state
*cli
;
6619 bool correct
= True
;
6622 printf("starting uid regression test\n");
6624 if (!torture_open_connection(&cli
, 0)) {
6628 cli_sockopt(cli
, sockops
);
6630 /* Ok - now save then logoff our current user. */
6631 old_vuid
= cli
->vuid
;
6633 status
= cli_ulogoff(cli
);
6634 if (!NT_STATUS_IS_OK(status
)) {
6635 d_printf("(%s) cli_ulogoff failed: %s\n",
6636 __location__
, nt_errstr(status
));
6641 cli
->vuid
= old_vuid
;
6643 /* Try an operation. */
6644 status
= cli_mkdir(cli
, "\\uid_reg_test");
6645 if (NT_STATUS_IS_OK(status
)) {
6646 d_printf("(%s) cli_mkdir succeeded\n",
6651 /* Should be bad uid. */
6652 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6653 NT_STATUS_USER_SESSION_DELETED
)) {
6659 old_cnum
= cli
->cnum
;
6661 /* Now try a SMBtdis with the invald vuid set to zero. */
6664 /* This should succeed. */
6665 status
= cli_tdis(cli
);
6667 if (NT_STATUS_IS_OK(status
)) {
6668 d_printf("First tdis with invalid vuid should succeed.\n");
6670 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
6675 cli
->vuid
= old_vuid
;
6676 cli
->cnum
= old_cnum
;
6678 /* This should fail. */
6679 status
= cli_tdis(cli
);
6680 if (NT_STATUS_IS_OK(status
)) {
6681 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6685 /* Should be bad tid. */
6686 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6687 NT_STATUS_NETWORK_NAME_DELETED
)) {
6693 cli_rmdir(cli
, "\\uid_reg_test");
6702 static const char *illegal_chars
= "*\\/?<>|\":";
6703 static char force_shortname_chars
[] = " +,.[];=\177";
6705 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
6706 const char *mask
, void *state
)
6708 struct cli_state
*pcli
= (struct cli_state
*)state
;
6710 NTSTATUS status
= NT_STATUS_OK
;
6712 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6714 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6715 return NT_STATUS_OK
;
6717 if (finfo
->mode
& aDIR
) {
6718 status
= cli_rmdir(pcli
, fname
);
6719 if (!NT_STATUS_IS_OK(status
)) {
6720 printf("del_fn: failed to rmdir %s\n,", fname
);
6723 status
= cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
);
6724 if (!NT_STATUS_IS_OK(status
)) {
6725 printf("del_fn: failed to unlink %s\n,", fname
);
6737 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
6738 const char *name
, void *state
)
6740 struct sn_state
*s
= (struct sn_state
*)state
;
6744 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6745 i
, finfo
->name
, finfo
->short_name
);
6748 if (strchr(force_shortname_chars
, i
)) {
6749 if (!finfo
->short_name
[0]) {
6750 /* Shortname not created when it should be. */
6751 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6752 __location__
, finfo
->name
, i
);
6755 } else if (finfo
->short_name
[0]){
6756 /* Shortname created when it should not be. */
6757 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6758 __location__
, finfo
->short_name
, finfo
->name
);
6762 return NT_STATUS_OK
;
6765 static bool run_shortname_test(int dummy
)
6767 static struct cli_state
*cli
;
6768 bool correct
= True
;
6773 printf("starting shortname test\n");
6775 if (!torture_open_connection(&cli
, 0)) {
6779 cli_sockopt(cli
, sockops
);
6781 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6782 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6783 cli_rmdir(cli
, "\\shortname");
6785 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6786 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6787 __location__
, cli_errstr(cli
));
6792 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6793 strlcat(fname
, "test .txt", sizeof(fname
));
6797 for (i
= 32; i
< 128; i
++) {
6799 uint16_t fnum
= (uint16_t)-1;
6803 if (strchr(illegal_chars
, i
)) {
6808 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6809 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6810 if (!NT_STATUS_IS_OK(status
)) {
6811 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6812 __location__
, fname
, cli_errstr(cli
));
6816 cli_close(cli
, fnum
);
6819 cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
,
6821 if (s
.matched
!= 1) {
6822 d_printf("(%s) failed to list %s: %s\n",
6823 __location__
, fname
, cli_errstr(cli
));
6827 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6828 d_printf("(%s) failed to delete %s: %s\n",
6829 __location__
, fname
, cli_errstr(cli
));
6842 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6843 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6844 cli_rmdir(cli
, "\\shortname");
6845 torture_close_connection(cli
);
6849 static void pagedsearch_cb(struct tevent_req
*req
)
6852 struct tldap_message
*msg
;
6855 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6856 if (rc
!= TLDAP_SUCCESS
) {
6857 d_printf("tldap_search_paged_recv failed: %s\n",
6858 tldap_err2string(rc
));
6861 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6865 if (!tldap_entry_dn(msg
, &dn
)) {
6866 d_printf("tldap_entry_dn failed\n");
6869 d_printf("%s\n", dn
);
6873 static bool run_tldap(int dummy
)
6875 struct tldap_context
*ld
;
6878 struct sockaddr_storage addr
;
6879 struct tevent_context
*ev
;
6880 struct tevent_req
*req
;
6884 if (!resolve_name(host
, &addr
, 0, false)) {
6885 d_printf("could not find host %s\n", host
);
6888 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6889 if (!NT_STATUS_IS_OK(status
)) {
6890 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6894 ld
= tldap_context_create(talloc_tos(), fd
);
6897 d_printf("tldap_context_create failed\n");
6901 rc
= tldap_fetch_rootdse(ld
);
6902 if (rc
!= TLDAP_SUCCESS
) {
6903 d_printf("tldap_fetch_rootdse failed: %s\n",
6904 tldap_errstr(talloc_tos(), ld
, rc
));
6908 basedn
= tldap_talloc_single_attribute(
6909 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6910 if (basedn
== NULL
) {
6911 d_printf("no defaultNamingContext\n");
6914 d_printf("defaultNamingContext: %s\n", basedn
);
6916 ev
= tevent_context_init(talloc_tos());
6918 d_printf("tevent_context_init failed\n");
6922 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6923 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6925 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6927 d_printf("tldap_search_paged_send failed\n");
6930 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6932 tevent_req_poll(req
, ev
);
6936 /* test search filters against rootDSE */
6937 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6938 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6940 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
6941 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
6942 talloc_tos(), NULL
, NULL
);
6943 if (rc
!= TLDAP_SUCCESS
) {
6944 d_printf("tldap_search with complex filter failed: %s\n",
6945 tldap_errstr(talloc_tos(), ld
, rc
));
6953 /* Torture test to ensure no regression of :
6954 https://bugzilla.samba.org/show_bug.cgi?id=7084
6957 static bool run_dir_createtime(int dummy
)
6959 struct cli_state
*cli
;
6960 const char *dname
= "\\testdir";
6961 const char *fname
= "\\testdir\\testfile";
6963 struct timespec create_time
;
6964 struct timespec create_time1
;
6968 if (!torture_open_connection(&cli
, 0)) {
6972 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6973 cli_rmdir(cli
, dname
);
6975 status
= cli_mkdir(cli
, dname
);
6976 if (!NT_STATUS_IS_OK(status
)) {
6977 printf("mkdir failed: %s\n", nt_errstr(status
));
6981 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
6983 if (!NT_STATUS_IS_OK(status
)) {
6984 printf("cli_qpathinfo2 returned %s\n",
6989 /* Sleep 3 seconds, then create a file. */
6992 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
6994 if (!NT_STATUS_IS_OK(status
)) {
6995 printf("cli_open failed: %s\n", nt_errstr(status
));
6999 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7001 if (!NT_STATUS_IS_OK(status
)) {
7002 printf("cli_qpathinfo2 (2) returned %s\n",
7007 if (timespec_compare(&create_time1
, &create_time
)) {
7008 printf("run_dir_createtime: create time was updated (error)\n");
7010 printf("run_dir_createtime: create time was not updated (correct)\n");
7016 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
7017 cli_rmdir(cli
, dname
);
7018 if (!torture_close_connection(cli
)) {
7025 static bool run_streamerror(int dummy
)
7027 struct cli_state
*cli
;
7028 const char *dname
= "\\testdir";
7029 const char *streamname
=
7030 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7032 time_t change_time
, access_time
, write_time
;
7034 uint16_t mode
, fnum
;
7037 if (!torture_open_connection(&cli
, 0)) {
7041 cli_unlink(cli
, "\\testdir\\*", aSYSTEM
| aHIDDEN
);
7042 cli_rmdir(cli
, dname
);
7044 status
= cli_mkdir(cli
, dname
);
7045 if (!NT_STATUS_IS_OK(status
)) {
7046 printf("mkdir failed: %s\n", nt_errstr(status
));
7050 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
7052 status
= cli_nt_error(cli
);
7054 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7055 printf("pathinfo returned %s, expected "
7056 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7061 status
= cli_ntcreate(cli
, streamname
, 0x16,
7062 FILE_READ_DATA
|FILE_READ_EA
|
7063 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7064 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7065 FILE_OPEN
, 0, 0, &fnum
);
7067 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7068 printf("ntcreate returned %s, expected "
7069 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7075 cli_rmdir(cli
, dname
);
7079 static bool run_local_substitute(int dummy
)
7083 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7084 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7085 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7086 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7087 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7088 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7089 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7090 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7092 /* Different captialization rules in sub_basic... */
7094 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7100 static bool run_local_base64(int dummy
)
7105 for (i
=1; i
<2000; i
++) {
7106 DATA_BLOB blob1
, blob2
;
7109 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7111 generate_random_buffer(blob1
.data
, blob1
.length
);
7113 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7115 d_fprintf(stderr
, "base64_encode_data_blob failed "
7116 "for %d bytes\n", i
);
7119 blob2
= base64_decode_data_blob(b64
);
7122 if (data_blob_cmp(&blob1
, &blob2
)) {
7123 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7127 TALLOC_FREE(blob1
.data
);
7128 data_blob_free(&blob2
);
7133 static bool run_local_gencache(int dummy
)
7139 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7140 d_printf("%s: gencache_set() failed\n", __location__
);
7144 if (!gencache_get("foo", NULL
, NULL
)) {
7145 d_printf("%s: gencache_get() failed\n", __location__
);
7149 if (!gencache_get("foo", &val
, &tm
)) {
7150 d_printf("%s: gencache_get() failed\n", __location__
);
7154 if (strcmp(val
, "bar") != 0) {
7155 d_printf("%s: gencache_get() returned %s, expected %s\n",
7156 __location__
, val
, "bar");
7163 if (!gencache_del("foo")) {
7164 d_printf("%s: gencache_del() failed\n", __location__
);
7167 if (gencache_del("foo")) {
7168 d_printf("%s: second gencache_del() succeeded\n",
7173 if (gencache_get("foo", &val
, &tm
)) {
7174 d_printf("%s: gencache_get() on deleted entry "
7175 "succeeded\n", __location__
);
7179 blob
= data_blob_string_const_null("bar");
7180 tm
= time(NULL
) + 60;
7182 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7183 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7187 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7188 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7192 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7193 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7194 __location__
, (const char *)blob
.data
, "bar");
7195 data_blob_free(&blob
);
7199 data_blob_free(&blob
);
7201 if (!gencache_del("foo")) {
7202 d_printf("%s: gencache_del() failed\n", __location__
);
7205 if (gencache_del("foo")) {
7206 d_printf("%s: second gencache_del() succeeded\n",
7211 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7212 d_printf("%s: gencache_get_data_blob() on deleted entry "
7213 "succeeded\n", __location__
);
7220 static bool rbt_testval(struct db_context
*db
, const char *key
,
7223 struct db_record
*rec
;
7224 TDB_DATA data
= string_tdb_data(value
);
7228 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7230 d_fprintf(stderr
, "fetch_locked failed\n");
7233 status
= rec
->store(rec
, data
, 0);
7234 if (!NT_STATUS_IS_OK(status
)) {
7235 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7240 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7242 d_fprintf(stderr
, "second fetch_locked failed\n");
7245 if ((rec
->value
.dsize
!= data
.dsize
)
7246 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7247 d_fprintf(stderr
, "Got wrong data back\n");
7257 static bool run_local_rbtree(int dummy
)
7259 struct db_context
*db
;
7263 db
= db_open_rbt(NULL
);
7266 d_fprintf(stderr
, "db_open_rbt failed\n");
7270 for (i
=0; i
<1000; i
++) {
7273 if (asprintf(&key
, "key%ld", random()) == -1) {
7276 if (asprintf(&value
, "value%ld", random()) == -1) {
7281 if (!rbt_testval(db
, key
, value
)) {
7288 if (asprintf(&value
, "value%ld", random()) == -1) {
7293 if (!rbt_testval(db
, key
, value
)) {
7310 struct talloc_dict_test
{
7314 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7316 int *count
= (int *)priv
;
7321 static bool run_local_talloc_dict(int dummy
)
7323 struct talloc_dict
*dict
;
7324 struct talloc_dict_test
*t
;
7327 dict
= talloc_dict_init(talloc_tos());
7332 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7339 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7344 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
7357 static bool run_local_string_to_sid(int dummy
) {
7360 if (string_to_sid(&sid
, "S--1-5-32-545")) {
7361 printf("allowing S--1-5-32-545\n");
7364 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
7365 printf("allowing S-1-5-32-+545\n");
7368 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")) {
7369 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7372 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
7373 printf("allowing S-1-5-32-545-abc\n");
7376 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
7377 printf("could not parse S-1-5-32-545\n");
7380 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
7381 printf("mis-parsed S-1-5-32-545 as %s\n",
7382 sid_string_tos(&sid
));
7388 static bool run_local_binary_to_sid(int dummy
) {
7389 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
7390 static const char good_binary_sid
[] = {
7391 0x1, /* revision number */
7393 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7394 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7411 static const char long_binary_sid
[] = {
7412 0x1, /* revision number */
7414 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7415 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7422 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7423 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7424 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7425 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7426 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7427 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7428 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7429 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7430 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7431 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7432 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7435 static const char long_binary_sid2
[] = {
7436 0x1, /* revision number */
7438 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7439 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7440 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7441 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7442 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7443 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7444 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7445 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7446 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7447 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7448 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7449 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7450 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7451 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7452 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7453 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7454 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7455 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7456 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7457 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7458 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7459 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7460 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7461 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7462 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7463 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7464 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7465 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7466 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7467 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7468 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7469 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7470 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7473 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
7476 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
7479 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
7485 /* Split a path name into filename and stream name components. Canonicalise
7486 * such that an implicit $DATA token is always explicit.
7488 * The "specification" of this function can be found in the
7489 * run_local_stream_name() function in torture.c, I've tried those
7490 * combinations against a W2k3 server.
7493 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
7494 char **pbase
, char **pstream
)
7497 char *stream
= NULL
;
7498 char *sname
; /* stream name */
7499 const char *stype
; /* stream type */
7501 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
7503 sname
= strchr_m(fname
, ':');
7505 if (lp_posix_pathnames() || (sname
== NULL
)) {
7506 if (pbase
!= NULL
) {
7507 base
= talloc_strdup(mem_ctx
, fname
);
7508 NT_STATUS_HAVE_NO_MEMORY(base
);
7513 if (pbase
!= NULL
) {
7514 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
7515 NT_STATUS_HAVE_NO_MEMORY(base
);
7520 stype
= strchr_m(sname
, ':');
7522 if (stype
== NULL
) {
7523 sname
= talloc_strdup(mem_ctx
, sname
);
7527 if (StrCaseCmp(stype
, ":$DATA") != 0) {
7529 * If there is an explicit stream type, so far we only
7530 * allow $DATA. Is there anything else allowed? -- vl
7532 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
7534 return NT_STATUS_OBJECT_NAME_INVALID
;
7536 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
7540 if (sname
== NULL
) {
7542 return NT_STATUS_NO_MEMORY
;
7545 if (sname
[0] == '\0') {
7547 * no stream name, so no stream
7552 if (pstream
!= NULL
) {
7553 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
7554 if (stream
== NULL
) {
7557 return NT_STATUS_NO_MEMORY
;
7560 * upper-case the type field
7562 strupper_m(strchr_m(stream
, ':')+1);
7566 if (pbase
!= NULL
) {
7569 if (pstream
!= NULL
) {
7572 return NT_STATUS_OK
;
7575 static bool test_stream_name(const char *fname
, const char *expected_base
,
7576 const char *expected_stream
,
7577 NTSTATUS expected_status
)
7581 char *stream
= NULL
;
7583 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
7584 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
7588 if (!NT_STATUS_IS_OK(status
)) {
7592 if (base
== NULL
) goto error
;
7594 if (strcmp(expected_base
, base
) != 0) goto error
;
7596 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
7597 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
7599 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
7603 TALLOC_FREE(stream
);
7607 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
7608 fname
, expected_base
? expected_base
: "<NULL>",
7609 expected_stream
? expected_stream
: "<NULL>",
7610 nt_errstr(expected_status
));
7611 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
7612 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
7615 TALLOC_FREE(stream
);
7619 static bool run_local_stream_name(int dummy
)
7623 ret
&= test_stream_name(
7624 "bla", "bla", NULL
, NT_STATUS_OK
);
7625 ret
&= test_stream_name(
7626 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
7627 ret
&= test_stream_name(
7628 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7629 ret
&= test_stream_name(
7630 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7631 ret
&= test_stream_name(
7632 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
7633 ret
&= test_stream_name(
7634 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
7635 ret
&= test_stream_name(
7636 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
7637 ret
&= test_stream_name(
7638 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
7643 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
7645 if (a
.length
!= b
.length
) {
7646 printf("a.length=%d != b.length=%d\n",
7647 (int)a
.length
, (int)b
.length
);
7650 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
7651 printf("a.data and b.data differ\n");
7657 static bool run_local_memcache(int dummy
)
7659 struct memcache
*cache
;
7661 DATA_BLOB d1
, d2
, d3
;
7662 DATA_BLOB v1
, v2
, v3
;
7664 TALLOC_CTX
*mem_ctx
;
7666 size_t size1
, size2
;
7669 cache
= memcache_init(NULL
, 100);
7671 if (cache
== NULL
) {
7672 printf("memcache_init failed\n");
7676 d1
= data_blob_const("d1", 2);
7677 d2
= data_blob_const("d2", 2);
7678 d3
= data_blob_const("d3", 2);
7680 k1
= data_blob_const("d1", 2);
7681 k2
= data_blob_const("d2", 2);
7683 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
7684 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
7686 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
7687 printf("could not find k1\n");
7690 if (!data_blob_equal(d1
, v1
)) {
7694 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7695 printf("could not find k2\n");
7698 if (!data_blob_equal(d2
, v2
)) {
7702 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
7704 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
7705 printf("could not find replaced k1\n");
7708 if (!data_blob_equal(d3
, v3
)) {
7712 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
7714 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7715 printf("Did find k2, should have been purged\n");
7721 cache
= memcache_init(NULL
, 0);
7723 mem_ctx
= talloc_init("foo");
7725 str1
= talloc_strdup(mem_ctx
, "string1");
7726 str2
= talloc_strdup(mem_ctx
, "string2");
7728 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7729 data_blob_string_const("torture"), &str1
);
7730 size1
= talloc_total_size(cache
);
7732 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7733 data_blob_string_const("torture"), &str2
);
7734 size2
= talloc_total_size(cache
);
7736 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
7738 if (size2
> size1
) {
7739 printf("memcache leaks memory!\n");
7749 static void wbclient_done(struct tevent_req
*req
)
7752 struct winbindd_response
*wb_resp
;
7753 int *i
= (int *)tevent_req_callback_data_void(req
);
7755 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
7758 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
7761 static bool run_local_wbclient(int dummy
)
7763 struct event_context
*ev
;
7764 struct wb_context
**wb_ctx
;
7765 struct winbindd_request wb_req
;
7766 bool result
= false;
7769 BlockSignals(True
, SIGPIPE
);
7771 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
7776 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
7777 if (wb_ctx
== NULL
) {
7781 ZERO_STRUCT(wb_req
);
7782 wb_req
.cmd
= WINBINDD_PING
;
7784 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
7786 for (i
=0; i
<nprocs
; i
++) {
7787 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
7788 if (wb_ctx
[i
] == NULL
) {
7791 for (j
=0; j
<torture_numops
; j
++) {
7792 struct tevent_req
*req
;
7793 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
7794 (j
% 2) == 0, &wb_req
);
7798 tevent_req_set_callback(req
, wbclient_done
, &i
);
7804 while (i
< nprocs
* torture_numops
) {
7805 event_loop_once(ev
);
7814 static void getaddrinfo_finished(struct tevent_req
*req
)
7816 char *name
= (char *)tevent_req_callback_data_void(req
);
7817 struct addrinfo
*ainfo
;
7820 res
= getaddrinfo_recv(req
, &ainfo
);
7822 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7825 d_printf("gai(%s) succeeded\n", name
);
7826 freeaddrinfo(ainfo
);
7829 static bool run_getaddrinfo_send(int dummy
)
7831 TALLOC_CTX
*frame
= talloc_stackframe();
7832 struct fncall_context
*ctx
;
7833 struct tevent_context
*ev
;
7834 bool result
= false;
7835 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7836 "www.slashdot.org", "heise.de" };
7837 struct tevent_req
*reqs
[4];
7840 ev
= event_context_init(frame
);
7845 ctx
= fncall_context_init(frame
, 4);
7847 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7848 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7850 if (reqs
[i
] == NULL
) {
7853 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7857 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7858 tevent_loop_once(ev
);
7867 static bool dbtrans_inc(struct db_context
*db
)
7869 struct db_record
*rec
;
7874 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7876 printf(__location__
"fetch_lock failed\n");
7880 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
7881 printf(__location__
"value.dsize = %d\n",
7882 (int)rec
->value
.dsize
);
7886 val
= (uint32_t *)rec
->value
.dptr
;
7889 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
7892 if (!NT_STATUS_IS_OK(status
)) {
7893 printf(__location__
"store failed: %s\n",
7904 static bool run_local_dbtrans(int dummy
)
7906 struct db_context
*db
;
7907 struct db_record
*rec
;
7912 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
7913 O_RDWR
|O_CREAT
, 0600);
7915 printf("Could not open transtest.db\n");
7919 res
= db
->transaction_start(db
);
7921 printf(__location__
"transaction_start failed\n");
7925 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7927 printf(__location__
"fetch_lock failed\n");
7931 if (rec
->value
.dptr
== NULL
) {
7933 status
= rec
->store(
7934 rec
, make_tdb_data((uint8_t *)&initial
,
7937 if (!NT_STATUS_IS_OK(status
)) {
7938 printf(__location__
"store returned %s\n",
7946 res
= db
->transaction_commit(db
);
7948 printf(__location__
"transaction_commit failed\n");
7956 res
= db
->transaction_start(db
);
7958 printf(__location__
"transaction_start failed\n");
7962 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
7963 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7967 for (i
=0; i
<10; i
++) {
7968 if (!dbtrans_inc(db
)) {
7973 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
7974 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7978 if (val2
!= val
+ 10) {
7979 printf(__location__
"val=%d, val2=%d\n",
7980 (int)val
, (int)val2
);
7984 printf("val2=%d\r", val2
);
7986 res
= db
->transaction_commit(db
);
7988 printf(__location__
"transaction_commit failed\n");
7998 * Just a dummy test to be run under a debugger. There's no real way
7999 * to inspect the tevent_select specific function from outside of
8003 static bool run_local_tevent_select(int dummy
)
8005 struct tevent_context
*ev
;
8006 struct tevent_fd
*fd1
, *fd2
;
8007 bool result
= false;
8009 ev
= tevent_context_init_byname(NULL
, "select");
8011 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8015 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8017 d_fprintf(stderr
, "tevent_add_fd failed\n");
8020 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8022 d_fprintf(stderr
, "tevent_add_fd failed\n");
8027 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8029 d_fprintf(stderr
, "tevent_add_fd failed\n");
8039 static double create_procs(bool (*fn
)(int), bool *result
)
8042 volatile pid_t
*child_status
;
8043 volatile bool *child_status_out
;
8046 struct timeval start
;
8050 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
8051 if (!child_status
) {
8052 printf("Failed to setup shared memory\n");
8056 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
8057 if (!child_status_out
) {
8058 printf("Failed to setup result status shared memory\n");
8062 for (i
= 0; i
< nprocs
; i
++) {
8063 child_status
[i
] = 0;
8064 child_status_out
[i
] = True
;
8067 start
= timeval_current();
8069 for (i
=0;i
<nprocs
;i
++) {
8072 pid_t mypid
= getpid();
8073 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8075 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8078 if (torture_open_connection(¤t_cli
, i
)) break;
8080 printf("pid %d failed to start\n", (int)getpid());
8086 child_status
[i
] = getpid();
8088 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8090 child_status_out
[i
] = fn(i
);
8097 for (i
=0;i
<nprocs
;i
++) {
8098 if (child_status
[i
]) synccount
++;
8100 if (synccount
== nprocs
) break;
8102 } while (timeval_elapsed(&start
) < 30);
8104 if (synccount
!= nprocs
) {
8105 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8107 return timeval_elapsed(&start
);
8110 /* start the client load */
8111 start
= timeval_current();
8113 for (i
=0;i
<nprocs
;i
++) {
8114 child_status
[i
] = 0;
8117 printf("%d clients started\n", nprocs
);
8119 for (i
=0;i
<nprocs
;i
++) {
8120 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8125 for (i
=0;i
<nprocs
;i
++) {
8126 if (!child_status_out
[i
]) {
8130 return timeval_elapsed(&start
);
8133 #define FLAG_MULTIPROC 1
8140 {"FDPASS", run_fdpasstest
, 0},
8141 {"LOCK1", run_locktest1
, 0},
8142 {"LOCK2", run_locktest2
, 0},
8143 {"LOCK3", run_locktest3
, 0},
8144 {"LOCK4", run_locktest4
, 0},
8145 {"LOCK5", run_locktest5
, 0},
8146 {"LOCK6", run_locktest6
, 0},
8147 {"LOCK7", run_locktest7
, 0},
8148 {"LOCK8", run_locktest8
, 0},
8149 {"LOCK9", run_locktest9
, 0},
8150 {"UNLINK", run_unlinktest
, 0},
8151 {"BROWSE", run_browsetest
, 0},
8152 {"ATTR", run_attrtest
, 0},
8153 {"TRANS2", run_trans2test
, 0},
8154 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8155 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8156 {"RANDOMIPC", run_randomipc
, 0},
8157 {"NEGNOWAIT", run_negprot_nowait
, 0},
8158 {"NBENCH", run_nbench
, 0},
8159 {"NBENCH2", run_nbench2
, 0},
8160 {"OPLOCK1", run_oplock1
, 0},
8161 {"OPLOCK2", run_oplock2
, 0},
8162 {"OPLOCK3", run_oplock3
, 0},
8163 {"OPLOCK4", run_oplock4
, 0},
8164 {"DIR", run_dirtest
, 0},
8165 {"DIR1", run_dirtest1
, 0},
8166 {"DIR-CREATETIME", run_dir_createtime
, 0},
8167 {"DENY1", torture_denytest1
, 0},
8168 {"DENY2", torture_denytest2
, 0},
8169 {"TCON", run_tcon_test
, 0},
8170 {"TCONDEV", run_tcon_devtype_test
, 0},
8171 {"RW1", run_readwritetest
, 0},
8172 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8173 {"RW3", run_readwritelarge
, 0},
8174 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8175 {"OPEN", run_opentest
, 0},
8176 {"POSIX", run_simple_posix_open_test
, 0},
8177 {"POSIX-APPEND", run_posix_append
, 0},
8178 {"ASYNC-ECHO", run_async_echo
, 0},
8179 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8180 { "SHORTNAME-TEST", run_shortname_test
, 0},
8181 { "ADDRCHANGE", run_addrchange
, 0},
8183 {"OPENATTR", run_openattrtest
, 0},
8185 {"XCOPY", run_xcopy
, 0},
8186 {"RENAME", run_rename
, 0},
8187 {"DELETE", run_deletetest
, 0},
8188 {"DELETE-LN", run_deletetest_ln
, 0},
8189 {"PROPERTIES", run_properties
, 0},
8190 {"MANGLE", torture_mangle
, 0},
8191 {"MANGLE1", run_mangle1
, 0},
8192 {"W2K", run_w2ktest
, 0},
8193 {"TRANS2SCAN", torture_trans2_scan
, 0},
8194 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8195 {"UTABLE", torture_utable
, 0},
8196 {"CASETABLE", torture_casetable
, 0},
8197 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8198 {"PIPE_NUMBER", run_pipe_number
, 0},
8199 {"TCON2", run_tcon2_test
, 0},
8200 {"IOCTL", torture_ioctl_test
, 0},
8201 {"CHKPATH", torture_chkpath_test
, 0},
8202 {"FDSESS", run_fdsesstest
, 0},
8203 { "EATEST", run_eatest
, 0},
8204 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8205 { "CHAIN1", run_chain1
, 0},
8206 { "CHAIN2", run_chain2
, 0},
8207 { "WINDOWS-WRITE", run_windows_write
, 0},
8208 { "CLI_ECHO", run_cli_echo
, 0},
8209 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8210 { "TLDAP", run_tldap
},
8211 { "STREAMERROR", run_streamerror
},
8212 { "NOTIFY-BENCH", run_notify_bench
},
8213 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8214 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8215 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8216 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8217 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8218 { "LOCAL-BASE64", run_local_base64
, 0},
8219 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8220 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8221 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8222 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8223 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8224 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8225 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8226 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8231 /****************************************************************************
8232 run a specified test or "ALL"
8233 ****************************************************************************/
8234 static bool run_test(const char *name
)
8241 if (strequal(name
,"ALL")) {
8242 for (i
=0;torture_ops
[i
].name
;i
++) {
8243 run_test(torture_ops
[i
].name
);
8248 for (i
=0;torture_ops
[i
].name
;i
++) {
8249 fstr_sprintf(randomfname
, "\\XX%x",
8250 (unsigned)random());
8252 if (strequal(name
, torture_ops
[i
].name
)) {
8254 printf("Running %s\n", name
);
8255 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8256 t
= create_procs(torture_ops
[i
].fn
, &result
);
8259 printf("TEST %s FAILED!\n", name
);
8262 struct timeval start
;
8263 start
= timeval_current();
8264 if (!torture_ops
[i
].fn(0)) {
8266 printf("TEST %s FAILED!\n", name
);
8268 t
= timeval_elapsed(&start
);
8270 printf("%s took %g secs\n\n", name
, t
);
8275 printf("Did not find a test named %s\n", name
);
8283 static void usage(void)
8287 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8288 printf("Please use samba4 torture.\n\n");
8290 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8292 printf("\t-d debuglevel\n");
8293 printf("\t-U user%%pass\n");
8294 printf("\t-k use kerberos\n");
8295 printf("\t-N numprocs\n");
8296 printf("\t-n my_netbios_name\n");
8297 printf("\t-W workgroup\n");
8298 printf("\t-o num_operations\n");
8299 printf("\t-O socket_options\n");
8300 printf("\t-m maximum protocol\n");
8301 printf("\t-L use oplocks\n");
8302 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8303 printf("\t-A showall\n");
8304 printf("\t-p port\n");
8305 printf("\t-s seed\n");
8306 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8309 printf("tests are:");
8310 for (i
=0;torture_ops
[i
].name
;i
++) {
8311 printf(" %s", torture_ops
[i
].name
);
8315 printf("default test is ALL\n");
8320 /****************************************************************************
8322 ****************************************************************************/
8323 int main(int argc
,char *argv
[])
8329 bool correct
= True
;
8330 TALLOC_CTX
*frame
= talloc_stackframe();
8331 int seed
= time(NULL
);
8333 #ifdef HAVE_SETBUFFER
8334 setbuffer(stdout
, NULL
, 0);
8337 setup_logging("smbtorture", DEBUG_STDOUT
);
8341 if (is_default_dyn_CONFIGFILE()) {
8342 if(getenv("SMB_CONF_PATH")) {
8343 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8346 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
8353 for(p
= argv
[1]; *p
; p
++)
8357 if (strncmp(argv
[1], "//", 2)) {
8361 fstrcpy(host
, &argv
[1][2]);
8362 p
= strchr_m(&host
[2],'/');
8367 fstrcpy(share
, p
+1);
8369 fstrcpy(myname
, get_myname(talloc_tos()));
8371 fprintf(stderr
, "Failed to get my hostname.\n");
8375 if (*username
== 0 && getenv("LOGNAME")) {
8376 fstrcpy(username
,getenv("LOGNAME"));
8382 fstrcpy(workgroup
, lp_workgroup());
8384 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
8387 port_to_use
= atoi(optarg
);
8390 seed
= atoi(optarg
);
8393 fstrcpy(workgroup
,optarg
);
8396 max_protocol
= interpret_protocol(optarg
, max_protocol
);
8399 nprocs
= atoi(optarg
);
8402 torture_numops
= atoi(optarg
);
8405 lp_set_cmdline("log level", optarg
);
8414 local_path
= optarg
;
8417 torture_showall
= True
;
8420 fstrcpy(myname
, optarg
);
8423 client_txt
= optarg
;
8430 use_kerberos
= True
;
8432 d_printf("No kerberos support compiled in\n");
8438 fstrcpy(username
,optarg
);
8439 p
= strchr_m(username
,'%');
8442 fstrcpy(password
, p
+1);
8447 fstrcpy(multishare_conn_fname
, optarg
);
8448 use_multishare_conn
= True
;
8451 torture_blocksize
= atoi(optarg
);
8454 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
8459 d_printf("using seed %d\n", seed
);
8463 if(use_kerberos
&& !gotuser
) gotpass
= True
;
8466 p
= getpass("Password:");
8468 fstrcpy(password
, p
);
8473 printf("host=%s share=%s user=%s myname=%s\n",
8474 host
, share
, username
, myname
);
8476 if (argc
== optind
) {
8477 correct
= run_test("ALL");
8479 for (i
=optind
;i
<argc
;i
++) {
8480 if (!run_test(argv
[i
])) {