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/libsmb.h"
35 #include "libsmb/clirap.h"
37 #include "libsmb/nmblib.h"
38 #include "../lib/util/tevent_ntstatus.h"
40 #include "libsmb/read_smb.h"
45 fstring host
, workgroup
, share
, password
, username
, myname
;
46 static int max_protocol
= PROTOCOL_NT1
;
47 static const char *sockops
="TCP_NODELAY";
49 static int port_to_use
=0;
50 int torture_numops
=100;
51 int torture_blocksize
=1024*1024;
52 static int procnum
; /* records process count number when forking */
53 static struct cli_state
*current_cli
;
54 static fstring randomfname
;
55 static bool use_oplocks
;
56 static bool use_level_II_oplocks
;
57 static const char *client_txt
= "client_oplocks.txt";
58 static bool use_kerberos
;
59 static fstring multishare_conn_fname
;
60 static bool use_multishare_conn
= False
;
61 static bool do_encrypt
;
62 static const char *local_path
= NULL
;
63 static int signing_state
= Undefined
;
66 bool torture_showall
= False
;
68 static double create_procs(bool (*fn
)(int), bool *result
);
71 /* return a pointer to a anonymous shared memory segment of size "size"
72 which will persist across fork() but will disappear when all processes
75 The memory is not zeroed
77 This function uses system5 shared memory. It takes advantage of a property
78 that the memory is not destroyed if it is attached when the id is removed
80 void *shm_setup(int size
)
86 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
88 printf("can't get shared memory\n");
91 shm_unlink("private");
92 if (ftruncate(shmid
, size
) == -1) {
93 printf("can't set shared memory size\n");
96 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
97 if (ret
== MAP_FAILED
) {
98 printf("can't map shared memory\n");
102 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
104 printf("can't get shared memory\n");
107 ret
= (void *)shmat(shmid
, 0, 0);
108 if (!ret
|| ret
== (void *)-1) {
109 printf("can't attach to shared memory\n");
112 /* the following releases the ipc, but note that this process
113 and all its children will still have access to the memory, its
114 just that the shmid is no longer valid for other shm calls. This
115 means we don't leave behind lots of shm segments after we exit
117 See Stevens "advanced programming in unix env" for details
119 shmctl(shmid
, IPC_RMID
, 0);
125 /********************************************************************
126 Ensure a connection is encrypted.
127 ********************************************************************/
129 static bool force_cli_encryption(struct cli_state
*c
,
130 const char *sharename
)
133 uint32 caplow
, caphigh
;
136 if (!SERVER_HAS_UNIX_CIFS(c
)) {
137 d_printf("Encryption required and "
138 "server that doesn't support "
139 "UNIX extensions - failing connect\n");
143 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
145 if (!NT_STATUS_IS_OK(status
)) {
146 d_printf("Encryption required and "
147 "can't get UNIX CIFS extensions "
148 "version from server: %s\n", nt_errstr(status
));
152 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
153 d_printf("Encryption required and "
154 "share %s doesn't support "
155 "encryption.\n", sharename
);
159 if (c
->use_kerberos
) {
160 status
= cli_gss_smb_encryption_start(c
);
162 status
= cli_raw_ntlm_smb_encryption_start(c
,
168 if (!NT_STATUS_IS_OK(status
)) {
169 d_printf("Encryption required and "
170 "setup failed with error %s.\n",
179 static struct cli_state
*open_nbt_connection(void)
184 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
186 if (!NT_STATUS_IS_OK(status
)) {
187 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
191 c
->use_kerberos
= use_kerberos
;
193 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
194 if (use_oplocks
) c
->use_oplocks
= True
;
195 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
200 /****************************************************************************
201 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
202 ****************************************************************************/
204 static bool cli_bad_session_request(int fd
,
205 struct nmb_name
*calling
, struct nmb_name
*called
)
214 uint8_t message_type
;
217 frame
= talloc_stackframe();
219 iov
[0].iov_base
= len_buf
;
220 iov
[0].iov_len
= sizeof(len_buf
);
222 /* put in the destination name */
224 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
226 if (iov
[1].iov_base
== NULL
) {
229 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
230 talloc_get_size(iov
[1].iov_base
));
234 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
236 if (iov
[2].iov_base
== NULL
) {
239 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
240 talloc_get_size(iov
[2].iov_base
));
242 /* Deliberately corrupt the name len (first byte) */
243 *((uint8_t *)iov
[2].iov_base
) = 100;
245 /* send a session request (RFC 1002) */
246 /* setup the packet length
247 * Remove four bytes from the length count, since the length
248 * field in the NBT Session Service header counts the number
249 * of bytes which follow. The cli_send_smb() function knows
250 * about this and accounts for those four bytes.
254 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
255 SCVAL(len_buf
,0,0x81);
257 len
= write_data_iov(fd
, iov
, 3);
261 len
= read_smb(fd
, talloc_tos(), &inbuf
, &err
);
267 message_type
= CVAL(inbuf
, 0);
268 if (message_type
!= 0x83) {
269 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
274 if (smb_len(inbuf
) != 1) {
275 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
276 (int)smb_len(inbuf
));
280 error
= CVAL(inbuf
, 4);
282 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
293 /* Insert a NULL at the first separator of the given path and return a pointer
294 * to the remainder of the string.
297 terminate_path_at_separator(char * path
)
305 if ((p
= strchr_m(path
, '/'))) {
310 if ((p
= strchr_m(path
, '\\'))) {
320 parse a //server/share type UNC name
322 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
323 char **hostname
, char **sharename
)
327 *hostname
= *sharename
= NULL
;
329 if (strncmp(unc_name
, "\\\\", 2) &&
330 strncmp(unc_name
, "//", 2)) {
334 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
335 p
= terminate_path_at_separator(*hostname
);
338 *sharename
= talloc_strdup(mem_ctx
, p
);
339 terminate_path_at_separator(*sharename
);
342 if (*hostname
&& *sharename
) {
346 TALLOC_FREE(*hostname
);
347 TALLOC_FREE(*sharename
);
351 static bool torture_open_connection_share(struct cli_state
**c
,
352 const char *hostname
,
353 const char *sharename
)
359 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
361 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
362 if (use_level_II_oplocks
)
363 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
365 status
= cli_full_connection(c
, myname
,
366 hostname
, NULL
, port_to_use
,
369 password
, flags
, signing_state
);
370 if (!NT_STATUS_IS_OK(status
)) {
371 printf("failed to open share connection: //%s/%s port:%d - %s\n",
372 hostname
, sharename
, port_to_use
, nt_errstr(status
));
376 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
379 return force_cli_encryption(*c
,
385 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
387 char **unc_list
= NULL
;
388 int num_unc_names
= 0;
391 if (use_multishare_conn
==True
) {
393 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
394 if (!unc_list
|| num_unc_names
<= 0) {
395 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
399 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
401 printf("Failed to parse UNC name %s\n",
402 unc_list
[conn_index
% num_unc_names
]);
403 TALLOC_FREE(unc_list
);
407 result
= torture_open_connection_share(c
, h
, s
);
409 /* h, s were copied earlier */
410 TALLOC_FREE(unc_list
);
414 return torture_open_connection_share(c
, host
, share
);
417 bool torture_init_connection(struct cli_state
**pcli
)
419 struct cli_state
*cli
;
421 cli
= open_nbt_connection();
430 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
432 uint16 old_vuid
= cli
->vuid
;
433 fstring old_user_name
;
434 size_t passlen
= strlen(password
);
438 fstrcpy(old_user_name
, cli
->user_name
);
440 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
444 *new_vuid
= cli
->vuid
;
445 cli
->vuid
= old_vuid
;
446 status
= cli_set_username(cli
, old_user_name
);
447 if (!NT_STATUS_IS_OK(status
)) {
454 bool torture_close_connection(struct cli_state
*c
)
459 status
= cli_tdis(c
);
460 if (!NT_STATUS_IS_OK(status
)) {
461 printf("tdis failed (%s)\n", nt_errstr(status
));
471 /* check if the server produced the expected dos or nt error code */
472 static bool check_both_error(int line
, NTSTATUS status
,
473 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
475 if (NT_STATUS_IS_DOS(status
)) {
479 /* Check DOS error */
480 cclass
= NT_STATUS_DOS_CLASS(status
);
481 num
= NT_STATUS_DOS_CODE(status
);
483 if (eclass
!= cclass
|| ecode
!= num
) {
484 printf("unexpected error code class=%d code=%d\n",
485 (int)cclass
, (int)num
);
486 printf(" expected %d/%d %s (line=%d)\n",
487 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
492 if (!NT_STATUS_EQUAL(nterr
, status
)) {
493 printf("unexpected error code %s\n",
495 printf(" expected %s (line=%d)\n",
496 nt_errstr(nterr
), line
);
505 /* check if the server produced the expected error code */
506 static bool check_error(int line
, struct cli_state
*c
,
507 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
509 if (cli_is_dos_error(c
)) {
513 /* Check DOS error */
515 cli_dos_error(c
, &cclass
, &num
);
517 if (eclass
!= cclass
|| ecode
!= num
) {
518 printf("unexpected error code class=%d code=%d\n",
519 (int)cclass
, (int)num
);
520 printf(" expected %d/%d %s (line=%d)\n",
521 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
530 status
= cli_nt_error(c
);
532 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
533 printf("unexpected error code %s\n", nt_errstr(status
));
534 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
543 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
547 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
549 while (!NT_STATUS_IS_OK(status
)) {
550 if (!check_both_error(__LINE__
, status
, ERRDOS
,
551 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
555 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
562 static bool rw_torture(struct cli_state
*c
)
564 const char *lockfname
= "\\torture.lck";
568 pid_t pid2
, pid
= getpid();
574 memset(buf
, '\0', sizeof(buf
));
576 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
578 if (!NT_STATUS_IS_OK(status
)) {
579 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
581 if (!NT_STATUS_IS_OK(status
)) {
582 printf("open of %s failed (%s)\n",
583 lockfname
, nt_errstr(status
));
587 for (i
=0;i
<torture_numops
;i
++) {
588 unsigned n
= (unsigned)sys_random()%10;
591 printf("%d\r", i
); fflush(stdout
);
593 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
595 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
599 status
= cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
601 if (!NT_STATUS_IS_OK(status
)) {
602 printf("open failed (%s)\n", nt_errstr(status
));
607 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
609 if (!NT_STATUS_IS_OK(status
)) {
610 printf("write failed (%s)\n", nt_errstr(status
));
615 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
616 sizeof(pid
)+(j
*sizeof(buf
)),
618 if (!NT_STATUS_IS_OK(status
)) {
619 printf("write failed (%s)\n",
627 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
628 printf("read failed (%s)\n", cli_errstr(c
));
633 printf("data corruption!\n");
637 status
= cli_close(c
, fnum
);
638 if (!NT_STATUS_IS_OK(status
)) {
639 printf("close failed (%s)\n", nt_errstr(status
));
643 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
644 if (!NT_STATUS_IS_OK(status
)) {
645 printf("unlink failed (%s)\n", nt_errstr(status
));
649 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
650 if (!NT_STATUS_IS_OK(status
)) {
651 printf("unlock failed (%s)\n", nt_errstr(status
));
657 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
664 static bool run_torture(int dummy
)
666 struct cli_state
*cli
;
671 cli_sockopt(cli
, sockops
);
673 ret
= rw_torture(cli
);
675 if (!torture_close_connection(cli
)) {
682 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
684 uint16_t fnum
= (uint16_t)-1;
689 unsigned countprev
= 0;
692 NTSTATUS status
= NT_STATUS_OK
;
695 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
697 SIVAL(buf
, i
, sys_random());
704 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
705 if (!NT_STATUS_IS_OK(status
)) {
706 printf("unlink failed (%s) (normal, this file should "
707 "not exist)\n", nt_errstr(status
));
710 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
712 if (!NT_STATUS_IS_OK(status
)) {
713 printf("first open read/write of %s failed (%s)\n",
714 lockfname
, nt_errstr(status
));
720 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
722 status
= cli_open(c
, lockfname
, O_RDONLY
,
724 if (!NT_STATUS_IS_OK(status
)) {
729 if (!NT_STATUS_IS_OK(status
)) {
730 printf("second open read-only of %s failed (%s)\n",
731 lockfname
, nt_errstr(status
));
737 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
739 if (count
>= countprev
) {
740 printf("%d %8d\r", i
, count
);
743 countprev
+= (sizeof(buf
) / 20);
748 sent
= ((unsigned)sys_random()%(20))+ 1;
749 if (sent
> sizeof(buf
) - count
)
751 sent
= sizeof(buf
) - count
;
754 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
755 count
, (size_t)sent
, NULL
);
756 if (!NT_STATUS_IS_OK(status
)) {
757 printf("write failed (%s)\n",
764 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
768 printf("read failed offset:%d size:%ld (%s)\n",
769 count
, (unsigned long)sizeof(buf
)-count
,
776 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
778 printf("read/write compare failed\n");
779 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
788 status
= cli_close(c
, fnum
);
789 if (!NT_STATUS_IS_OK(status
)) {
790 printf("close failed (%s)\n", nt_errstr(status
));
797 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
799 const char *lockfname
= "\\torture2.lck";
809 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
810 if (!NT_STATUS_IS_OK(status
)) {
811 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
814 status
= cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
816 if (!NT_STATUS_IS_OK(status
)) {
817 printf("first open read/write of %s failed (%s)\n",
818 lockfname
, nt_errstr(status
));
822 status
= cli_open(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
823 if (!NT_STATUS_IS_OK(status
)) {
824 printf("second open read-only of %s failed (%s)\n",
825 lockfname
, nt_errstr(status
));
826 cli_close(c1
, fnum1
);
830 for (i
= 0; i
< torture_numops
; i
++)
832 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
834 printf("%d\r", i
); fflush(stdout
);
837 generate_random_buffer((unsigned char *)buf
, buf_size
);
839 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
841 if (!NT_STATUS_IS_OK(status
)) {
842 printf("write failed (%s)\n", nt_errstr(status
));
847 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
848 printf("read failed (%s)\n", cli_errstr(c2
));
849 printf("read %d, expected %ld\n", (int)bytes_read
,
850 (unsigned long)buf_size
);
855 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
857 printf("read/write compare failed\n");
863 status
= cli_close(c2
, fnum2
);
864 if (!NT_STATUS_IS_OK(status
)) {
865 printf("close failed (%s)\n", nt_errstr(status
));
869 status
= cli_close(c1
, fnum1
);
870 if (!NT_STATUS_IS_OK(status
)) {
871 printf("close failed (%s)\n", nt_errstr(status
));
875 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
876 if (!NT_STATUS_IS_OK(status
)) {
877 printf("unlink failed (%s)\n", nt_errstr(status
));
884 static bool run_readwritetest(int dummy
)
886 struct cli_state
*cli1
, *cli2
;
887 bool test1
, test2
= False
;
889 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
892 cli_sockopt(cli1
, sockops
);
893 cli_sockopt(cli2
, sockops
);
895 printf("starting readwritetest\n");
897 test1
= rw_torture2(cli1
, cli2
);
898 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
901 test2
= rw_torture2(cli1
, cli1
);
902 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
905 if (!torture_close_connection(cli1
)) {
909 if (!torture_close_connection(cli2
)) {
913 return (test1
&& test2
);
916 static bool run_readwritemulti(int dummy
)
918 struct cli_state
*cli
;
923 cli_sockopt(cli
, sockops
);
925 printf("run_readwritemulti: fname %s\n", randomfname
);
926 test
= rw_torture3(cli
, randomfname
);
928 if (!torture_close_connection(cli
)) {
935 static bool run_readwritelarge_internal(int max_xmit_k
)
937 static struct cli_state
*cli1
;
939 const char *lockfname
= "\\large.dat";
945 if (!torture_open_connection(&cli1
, 0)) {
948 cli_sockopt(cli1
, sockops
);
949 memset(buf
,'\0',sizeof(buf
));
951 cli1
->max_xmit
= max_xmit_k
*1024;
953 if (signing_state
== Required
) {
954 /* Horrible cheat to force
955 multiple signed outstanding
956 packets against a Samba server.
958 cli1
->is_samba
= false;
961 printf("starting readwritelarge_internal\n");
963 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
965 status
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
967 if (!NT_STATUS_IS_OK(status
)) {
968 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
972 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
974 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
976 if (!NT_STATUS_IS_OK(status
)) {
977 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
981 if (fsize
== sizeof(buf
))
982 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
983 (unsigned long)fsize
);
985 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
986 (unsigned long)fsize
);
990 status
= cli_close(cli1
, fnum1
);
991 if (!NT_STATUS_IS_OK(status
)) {
992 printf("close failed (%s)\n", nt_errstr(status
));
996 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
997 if (!NT_STATUS_IS_OK(status
)) {
998 printf("unlink failed (%s)\n", nt_errstr(status
));
1002 status
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1004 if (!NT_STATUS_IS_OK(status
)) {
1005 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1009 cli1
->max_xmit
= 4*1024;
1011 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
1013 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1015 if (!NT_STATUS_IS_OK(status
)) {
1016 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1020 if (fsize
== sizeof(buf
))
1021 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1022 (unsigned long)fsize
);
1024 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1025 (unsigned long)fsize
);
1030 /* ToDo - set allocation. JRA */
1031 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1032 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1035 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1037 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1041 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1044 status
= cli_close(cli1
, fnum1
);
1045 if (!NT_STATUS_IS_OK(status
)) {
1046 printf("close failed (%s)\n", nt_errstr(status
));
1050 if (!torture_close_connection(cli1
)) {
1056 static bool run_readwritelarge(int dummy
)
1058 return run_readwritelarge_internal(128);
1061 static bool run_readwritelarge_signtest(int dummy
)
1064 signing_state
= Required
;
1065 ret
= run_readwritelarge_internal(2);
1066 signing_state
= Undefined
;
1073 #define ival(s) strtol(s, NULL, 0)
1075 /* run a test that simulates an approximate netbench client load */
1076 static bool run_netbench(int client
)
1078 struct cli_state
*cli
;
1083 const char *params
[20];
1084 bool correct
= True
;
1090 cli_sockopt(cli
, sockops
);
1094 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1096 f
= fopen(client_txt
, "r");
1103 while (fgets(line
, sizeof(line
)-1, f
)) {
1107 line
[strlen(line
)-1] = 0;
1109 /* printf("[%d] %s\n", line_count, line); */
1111 all_string_sub(line
,"client1", cname
, sizeof(line
));
1113 /* parse the command parameters */
1114 params
[0] = strtok_r(line
, " ", &saveptr
);
1116 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1120 if (i
< 2) continue;
1122 if (!strncmp(params
[0],"SMB", 3)) {
1123 printf("ERROR: You are using a dbench 1 load file\n");
1127 if (!strcmp(params
[0],"NTCreateX")) {
1128 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1130 } else if (!strcmp(params
[0],"Close")) {
1131 nb_close(ival(params
[1]));
1132 } else if (!strcmp(params
[0],"Rename")) {
1133 nb_rename(params
[1], params
[2]);
1134 } else if (!strcmp(params
[0],"Unlink")) {
1135 nb_unlink(params
[1]);
1136 } else if (!strcmp(params
[0],"Deltree")) {
1137 nb_deltree(params
[1]);
1138 } else if (!strcmp(params
[0],"Rmdir")) {
1139 nb_rmdir(params
[1]);
1140 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1141 nb_qpathinfo(params
[1]);
1142 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1143 nb_qfileinfo(ival(params
[1]));
1144 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1145 nb_qfsinfo(ival(params
[1]));
1146 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1147 nb_findfirst(params
[1]);
1148 } else if (!strcmp(params
[0],"WriteX")) {
1149 nb_writex(ival(params
[1]),
1150 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1151 } else if (!strcmp(params
[0],"ReadX")) {
1152 nb_readx(ival(params
[1]),
1153 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1154 } else if (!strcmp(params
[0],"Flush")) {
1155 nb_flush(ival(params
[1]));
1157 printf("Unknown operation %s\n", params
[0]);
1165 if (!torture_close_connection(cli
)) {
1173 /* run a test that simulates an approximate netbench client load */
1174 static bool run_nbench(int dummy
)
1177 bool correct
= True
;
1183 signal(SIGALRM
, nb_alarm
);
1185 t
= create_procs(run_netbench
, &correct
);
1188 printf("\nThroughput %g MB/sec\n",
1189 1.0e-6 * nbio_total() / t
);
1195 This test checks for two things:
1197 1) correct support for retaining locks over a close (ie. the server
1198 must not use posix semantics)
1199 2) support for lock timeouts
1201 static bool run_locktest1(int dummy
)
1203 struct cli_state
*cli1
, *cli2
;
1204 const char *fname
= "\\lockt1.lck";
1205 uint16_t fnum1
, fnum2
, fnum3
;
1207 unsigned lock_timeout
;
1210 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1213 cli_sockopt(cli1
, sockops
);
1214 cli_sockopt(cli2
, sockops
);
1216 printf("starting locktest1\n");
1218 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1220 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1222 if (!NT_STATUS_IS_OK(status
)) {
1223 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1227 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1228 if (!NT_STATUS_IS_OK(status
)) {
1229 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1233 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1234 if (!NT_STATUS_IS_OK(status
)) {
1235 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1239 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1240 if (!NT_STATUS_IS_OK(status
)) {
1241 printf("lock1 failed (%s)\n", nt_errstr(status
));
1245 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1246 if (NT_STATUS_IS_OK(status
)) {
1247 printf("lock2 succeeded! This is a locking bug\n");
1250 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1251 NT_STATUS_LOCK_NOT_GRANTED
)) {
1256 lock_timeout
= (1 + (random() % 20));
1257 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1259 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1260 if (NT_STATUS_IS_OK(status
)) {
1261 printf("lock3 succeeded! This is a locking bug\n");
1264 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1265 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1271 if (ABS(t2
- t1
) < lock_timeout
-1) {
1272 printf("error: This server appears not to support timed lock requests\n");
1275 printf("server slept for %u seconds for a %u second timeout\n",
1276 (unsigned int)(t2
-t1
), lock_timeout
);
1278 status
= cli_close(cli1
, fnum2
);
1279 if (!NT_STATUS_IS_OK(status
)) {
1280 printf("close1 failed (%s)\n", nt_errstr(status
));
1284 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1285 if (NT_STATUS_IS_OK(status
)) {
1286 printf("lock4 succeeded! This is a locking bug\n");
1289 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1290 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1295 status
= cli_close(cli1
, fnum1
);
1296 if (!NT_STATUS_IS_OK(status
)) {
1297 printf("close2 failed (%s)\n", nt_errstr(status
));
1301 status
= cli_close(cli2
, fnum3
);
1302 if (!NT_STATUS_IS_OK(status
)) {
1303 printf("close3 failed (%s)\n", nt_errstr(status
));
1307 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1308 if (!NT_STATUS_IS_OK(status
)) {
1309 printf("unlink failed (%s)\n", nt_errstr(status
));
1314 if (!torture_close_connection(cli1
)) {
1318 if (!torture_close_connection(cli2
)) {
1322 printf("Passed locktest1\n");
1327 this checks to see if a secondary tconx can use open files from an
1330 static bool run_tcon_test(int dummy
)
1332 static struct cli_state
*cli
;
1333 const char *fname
= "\\tcontest.tmp";
1335 uint16 cnum1
, cnum2
, cnum3
;
1336 uint16 vuid1
, vuid2
;
1341 memset(buf
, '\0', sizeof(buf
));
1343 if (!torture_open_connection(&cli
, 0)) {
1346 cli_sockopt(cli
, sockops
);
1348 printf("starting tcontest\n");
1350 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1352 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1353 if (!NT_STATUS_IS_OK(status
)) {
1354 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1361 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1362 if (!NT_STATUS_IS_OK(status
)) {
1363 printf("initial write failed (%s)", nt_errstr(status
));
1367 status
= cli_tcon_andx(cli
, share
, "?????",
1368 password
, strlen(password
)+1);
1369 if (!NT_STATUS_IS_OK(status
)) {
1370 printf("%s refused 2nd tree connect (%s)\n", host
,
1377 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1378 vuid2
= cli
->vuid
+ 1;
1380 /* try a write with the wrong tid */
1383 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1384 if (NT_STATUS_IS_OK(status
)) {
1385 printf("* server allows write with wrong TID\n");
1388 printf("server fails write with wrong TID : %s\n",
1393 /* try a write with an invalid tid */
1396 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1397 if (NT_STATUS_IS_OK(status
)) {
1398 printf("* server allows write with invalid TID\n");
1401 printf("server fails write with invalid TID : %s\n",
1405 /* try a write with an invalid vuid */
1409 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1410 if (NT_STATUS_IS_OK(status
)) {
1411 printf("* server allows write with invalid VUID\n");
1414 printf("server fails write with invalid VUID : %s\n",
1421 status
= cli_close(cli
, fnum1
);
1422 if (!NT_STATUS_IS_OK(status
)) {
1423 printf("close failed (%s)\n", nt_errstr(status
));
1429 status
= cli_tdis(cli
);
1430 if (!NT_STATUS_IS_OK(status
)) {
1431 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1437 if (!torture_close_connection(cli
)) {
1446 checks for old style tcon support
1448 static bool run_tcon2_test(int dummy
)
1450 static struct cli_state
*cli
;
1451 uint16 cnum
, max_xmit
;
1455 if (!torture_open_connection(&cli
, 0)) {
1458 cli_sockopt(cli
, sockops
);
1460 printf("starting tcon2 test\n");
1462 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1466 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1470 if (!NT_STATUS_IS_OK(status
)) {
1471 printf("tcon2 failed : %s\n", nt_errstr(status
));
1473 printf("tcon OK : max_xmit=%d cnum=%d\n",
1474 (int)max_xmit
, (int)cnum
);
1477 if (!torture_close_connection(cli
)) {
1481 printf("Passed tcon2 test\n");
1485 static bool tcon_devtest(struct cli_state
*cli
,
1486 const char *myshare
, const char *devtype
,
1487 const char *return_devtype
,
1488 NTSTATUS expected_error
)
1493 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1494 password
, strlen(password
)+1);
1496 if (NT_STATUS_IS_OK(expected_error
)) {
1497 if (NT_STATUS_IS_OK(status
)) {
1498 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1501 printf("tconX to share %s with type %s "
1502 "succeeded but returned the wrong "
1503 "device type (got [%s] but should have got [%s])\n",
1504 myshare
, devtype
, cli
->dev
, return_devtype
);
1508 printf("tconX to share %s with type %s "
1509 "should have succeeded but failed\n",
1515 if (NT_STATUS_IS_OK(status
)) {
1516 printf("tconx to share %s with type %s "
1517 "should have failed but succeeded\n",
1521 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1525 printf("Returned unexpected error\n");
1534 checks for correct tconX support
1536 static bool run_tcon_devtype_test(int dummy
)
1538 static struct cli_state
*cli1
= NULL
;
1543 status
= cli_full_connection(&cli1
, myname
,
1544 host
, NULL
, port_to_use
,
1546 username
, workgroup
,
1547 password
, flags
, signing_state
);
1549 if (!NT_STATUS_IS_OK(status
)) {
1550 printf("could not open connection\n");
1554 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1557 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1560 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1563 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1566 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1569 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1572 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1575 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1578 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1581 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1587 printf("Passed tcondevtest\n");
1594 This test checks that
1596 1) the server supports multiple locking contexts on the one SMB
1597 connection, distinguished by PID.
1599 2) the server correctly fails overlapping locks made by the same PID (this
1600 goes against POSIX behaviour, which is why it is tricky to implement)
1602 3) the server denies unlock requests by an incorrect client PID
1604 static bool run_locktest2(int dummy
)
1606 static struct cli_state
*cli
;
1607 const char *fname
= "\\lockt2.lck";
1608 uint16_t fnum1
, fnum2
, fnum3
;
1609 bool correct
= True
;
1612 if (!torture_open_connection(&cli
, 0)) {
1616 cli_sockopt(cli
, sockops
);
1618 printf("starting locktest2\n");
1620 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1624 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1625 if (!NT_STATUS_IS_OK(status
)) {
1626 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1630 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1631 if (!NT_STATUS_IS_OK(status
)) {
1632 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1638 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1639 if (!NT_STATUS_IS_OK(status
)) {
1640 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1646 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1647 if (!NT_STATUS_IS_OK(status
)) {
1648 printf("lock1 failed (%s)\n", nt_errstr(status
));
1652 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1653 if (NT_STATUS_IS_OK(status
)) {
1654 printf("WRITE lock1 succeeded! This is a locking bug\n");
1657 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1658 NT_STATUS_LOCK_NOT_GRANTED
)) {
1663 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1664 if (NT_STATUS_IS_OK(status
)) {
1665 printf("WRITE lock2 succeeded! This is a locking bug\n");
1668 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1669 NT_STATUS_LOCK_NOT_GRANTED
)) {
1674 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1675 if (NT_STATUS_IS_OK(status
)) {
1676 printf("READ lock2 succeeded! This is a locking bug\n");
1679 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1680 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1685 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1686 if (!NT_STATUS_IS_OK(status
)) {
1687 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1690 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1691 printf("unlock at 100 succeeded! This is a locking bug\n");
1695 status
= cli_unlock(cli
, fnum1
, 0, 4);
1696 if (NT_STATUS_IS_OK(status
)) {
1697 printf("unlock1 succeeded! This is a locking bug\n");
1700 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1701 NT_STATUS_RANGE_NOT_LOCKED
)) {
1706 status
= cli_unlock(cli
, fnum1
, 0, 8);
1707 if (NT_STATUS_IS_OK(status
)) {
1708 printf("unlock2 succeeded! This is a locking bug\n");
1711 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1712 NT_STATUS_RANGE_NOT_LOCKED
)) {
1717 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1718 if (NT_STATUS_IS_OK(status
)) {
1719 printf("lock3 succeeded! This is a locking bug\n");
1722 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1723 NT_STATUS_LOCK_NOT_GRANTED
)) {
1730 status
= cli_close(cli
, fnum1
);
1731 if (!NT_STATUS_IS_OK(status
)) {
1732 printf("close1 failed (%s)\n", nt_errstr(status
));
1736 status
= cli_close(cli
, fnum2
);
1737 if (!NT_STATUS_IS_OK(status
)) {
1738 printf("close2 failed (%s)\n", nt_errstr(status
));
1742 status
= cli_close(cli
, fnum3
);
1743 if (!NT_STATUS_IS_OK(status
)) {
1744 printf("close3 failed (%s)\n", nt_errstr(status
));
1748 if (!torture_close_connection(cli
)) {
1752 printf("locktest2 finished\n");
1759 This test checks that
1761 1) the server supports the full offset range in lock requests
1763 static bool run_locktest3(int dummy
)
1765 static struct cli_state
*cli1
, *cli2
;
1766 const char *fname
= "\\lockt3.lck";
1767 uint16_t fnum1
, fnum2
;
1770 bool correct
= True
;
1773 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1775 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1778 cli_sockopt(cli1
, sockops
);
1779 cli_sockopt(cli2
, sockops
);
1781 printf("starting locktest3\n");
1783 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1785 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1787 if (!NT_STATUS_IS_OK(status
)) {
1788 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1792 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1793 if (!NT_STATUS_IS_OK(status
)) {
1794 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1798 for (offset
=i
=0;i
<torture_numops
;i
++) {
1800 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1801 printf("lock1 %d failed (%s)\n",
1807 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1808 printf("lock2 %d failed (%s)\n",
1815 for (offset
=i
=0;i
<torture_numops
;i
++) {
1818 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1819 printf("error: lock1 %d succeeded!\n", i
);
1823 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1824 printf("error: lock2 %d succeeded!\n", i
);
1828 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1829 printf("error: lock3 %d succeeded!\n", i
);
1833 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1834 printf("error: lock4 %d succeeded!\n", i
);
1839 for (offset
=i
=0;i
<torture_numops
;i
++) {
1842 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1843 if (!NT_STATUS_IS_OK(status
)) {
1844 printf("unlock1 %d failed (%s)\n",
1850 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1851 if (!NT_STATUS_IS_OK(status
)) {
1852 printf("unlock2 %d failed (%s)\n",
1859 status
= cli_close(cli1
, fnum1
);
1860 if (!NT_STATUS_IS_OK(status
)) {
1861 printf("close1 failed (%s)\n", nt_errstr(status
));
1865 status
= cli_close(cli2
, fnum2
);
1866 if (!NT_STATUS_IS_OK(status
)) {
1867 printf("close2 failed (%s)\n", nt_errstr(status
));
1871 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1872 if (!NT_STATUS_IS_OK(status
)) {
1873 printf("unlink failed (%s)\n", nt_errstr(status
));
1877 if (!torture_close_connection(cli1
)) {
1881 if (!torture_close_connection(cli2
)) {
1885 printf("finished locktest3\n");
1890 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1891 printf("** "); correct = False; \
1895 looks at overlapping locks
1897 static bool run_locktest4(int dummy
)
1899 static struct cli_state
*cli1
, *cli2
;
1900 const char *fname
= "\\lockt4.lck";
1901 uint16_t fnum1
, fnum2
, f
;
1904 bool correct
= True
;
1907 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1911 cli_sockopt(cli1
, sockops
);
1912 cli_sockopt(cli2
, sockops
);
1914 printf("starting locktest4\n");
1916 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1918 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1919 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1921 memset(buf
, 0, sizeof(buf
));
1923 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1925 if (!NT_STATUS_IS_OK(status
)) {
1926 printf("Failed to create file: %s\n", nt_errstr(status
));
1931 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1932 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1933 EXPECTED(ret
, False
);
1934 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1936 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1937 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1938 EXPECTED(ret
, True
);
1939 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1941 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1942 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1943 EXPECTED(ret
, False
);
1944 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1946 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1947 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1948 EXPECTED(ret
, True
);
1949 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1951 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1952 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1953 EXPECTED(ret
, False
);
1954 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1956 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1957 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1958 EXPECTED(ret
, True
);
1959 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1961 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1962 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1963 EXPECTED(ret
, True
);
1964 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1966 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1967 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1968 EXPECTED(ret
, False
);
1969 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1971 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1972 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1973 EXPECTED(ret
, False
);
1974 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1976 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1977 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1978 EXPECTED(ret
, True
);
1979 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1981 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1982 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1983 EXPECTED(ret
, False
);
1984 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1986 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1987 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1988 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1989 EXPECTED(ret
, False
);
1990 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1993 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1994 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1995 EXPECTED(ret
, False
);
1996 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1998 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2000 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2002 ret
= NT_STATUS_IS_OK(status
);
2004 EXPECTED(ret
, False
);
2005 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2008 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
2009 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
2010 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2011 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2012 EXPECTED(ret
, True
);
2013 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2016 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
2017 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
2018 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2019 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
2020 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2022 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2023 EXPECTED(ret
, True
);
2024 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2026 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
2027 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2028 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2030 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
2031 EXPECTED(ret
, True
);
2032 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2034 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
2035 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2036 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2038 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
2039 EXPECTED(ret
, True
);
2040 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2042 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
2043 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
2044 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2045 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2047 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
2048 EXPECTED(ret
, True
);
2049 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2051 cli_close(cli1
, fnum1
);
2052 cli_close(cli2
, fnum2
);
2053 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2054 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2055 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
2056 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
2057 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2058 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2059 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2061 cli_close(cli1
, fnum1
);
2062 EXPECTED(ret
, True
);
2063 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2066 cli_close(cli1
, fnum1
);
2067 cli_close(cli2
, fnum2
);
2068 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2069 torture_close_connection(cli1
);
2070 torture_close_connection(cli2
);
2072 printf("finished locktest4\n");
2077 looks at lock upgrade/downgrade.
2079 static bool run_locktest5(int dummy
)
2081 static struct cli_state
*cli1
, *cli2
;
2082 const char *fname
= "\\lockt5.lck";
2083 uint16_t fnum1
, fnum2
, fnum3
;
2086 bool correct
= True
;
2089 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2093 cli_sockopt(cli1
, sockops
);
2094 cli_sockopt(cli2
, sockops
);
2096 printf("starting locktest5\n");
2098 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2100 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2101 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2102 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2104 memset(buf
, 0, sizeof(buf
));
2106 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2108 if (!NT_STATUS_IS_OK(status
)) {
2109 printf("Failed to create file: %s\n", nt_errstr(status
));
2114 /* Check for NT bug... */
2115 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
2116 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
2117 cli_close(cli1
, fnum1
);
2118 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2119 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2120 EXPECTED(ret
, True
);
2121 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2122 cli_close(cli1
, fnum1
);
2123 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2124 cli_unlock(cli1
, fnum3
, 0, 1);
2126 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
2127 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
2128 EXPECTED(ret
, True
);
2129 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2131 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2132 EXPECTED(ret
, False
);
2134 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2136 /* Unlock the process 2 lock. */
2137 cli_unlock(cli2
, fnum2
, 0, 4);
2139 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2140 EXPECTED(ret
, False
);
2142 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2144 /* Unlock the process 1 fnum3 lock. */
2145 cli_unlock(cli1
, fnum3
, 0, 4);
2147 /* Stack 2 more locks here. */
2148 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
2149 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
2151 EXPECTED(ret
, True
);
2152 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2154 /* Unlock the first process lock, then check this was the WRITE lock that was
2157 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2158 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2160 EXPECTED(ret
, True
);
2161 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2163 /* Unlock the process 2 lock. */
2164 cli_unlock(cli2
, fnum2
, 0, 4);
2166 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2168 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2169 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2170 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2172 EXPECTED(ret
, True
);
2173 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2175 /* Ensure the next unlock fails. */
2176 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2177 EXPECTED(ret
, False
);
2178 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2180 /* Ensure connection 2 can get a write lock. */
2181 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2182 EXPECTED(ret
, True
);
2184 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2188 cli_close(cli1
, fnum1
);
2189 cli_close(cli2
, fnum2
);
2190 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2191 if (!torture_close_connection(cli1
)) {
2194 if (!torture_close_connection(cli2
)) {
2198 printf("finished locktest5\n");
2204 tries the unusual lockingX locktype bits
2206 static bool run_locktest6(int dummy
)
2208 static struct cli_state
*cli
;
2209 const char *fname
[1] = { "\\lock6.txt" };
2214 if (!torture_open_connection(&cli
, 0)) {
2218 cli_sockopt(cli
, sockops
);
2220 printf("starting locktest6\n");
2223 printf("Testing %s\n", fname
[i
]);
2225 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2227 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2228 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2229 cli_close(cli
, fnum
);
2230 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2232 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2233 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2234 cli_close(cli
, fnum
);
2235 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2237 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2240 torture_close_connection(cli
);
2242 printf("finished locktest6\n");
2246 static bool run_locktest7(int dummy
)
2248 struct cli_state
*cli1
;
2249 const char *fname
= "\\lockt7.lck";
2252 bool correct
= False
;
2255 if (!torture_open_connection(&cli1
, 0)) {
2259 cli_sockopt(cli1
, sockops
);
2261 printf("starting locktest7\n");
2263 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2265 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2267 memset(buf
, 0, sizeof(buf
));
2269 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2271 if (!NT_STATUS_IS_OK(status
)) {
2272 printf("Failed to create file: %s\n", nt_errstr(status
));
2276 cli_setpid(cli1
, 1);
2278 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
2279 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2282 printf("pid1 successfully locked range 130:4 for READ\n");
2285 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2286 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2289 printf("pid1 successfully read the range 130:4\n");
2292 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2293 if (!NT_STATUS_IS_OK(status
)) {
2294 printf("pid1 unable to write to the range 130:4, error was "
2295 "%s\n", nt_errstr(status
));
2296 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2297 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2301 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2305 cli_setpid(cli1
, 2);
2307 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2308 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2310 printf("pid2 successfully read the range 130:4\n");
2313 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2314 if (!NT_STATUS_IS_OK(status
)) {
2315 printf("pid2 unable to write to the range 130:4, error was "
2316 "%s\n", nt_errstr(status
));
2317 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2318 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2322 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2326 cli_setpid(cli1
, 1);
2327 cli_unlock(cli1
, fnum1
, 130, 4);
2329 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2330 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2333 printf("pid1 successfully locked range 130:4 for WRITE\n");
2336 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2337 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2340 printf("pid1 successfully read the range 130:4\n");
2343 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2344 if (!NT_STATUS_IS_OK(status
)) {
2345 printf("pid1 unable to write to the range 130:4, error was "
2346 "%s\n", nt_errstr(status
));
2349 printf("pid1 successfully wrote to the range 130:4\n");
2352 cli_setpid(cli1
, 2);
2354 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2355 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2356 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2357 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2361 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2365 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2366 if (!NT_STATUS_IS_OK(status
)) {
2367 printf("pid2 unable to write to the range 130:4, error was "
2368 "%s\n", nt_errstr(status
));
2369 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2370 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2374 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2378 cli_unlock(cli1
, fnum1
, 130, 0);
2382 cli_close(cli1
, fnum1
);
2383 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2384 torture_close_connection(cli1
);
2386 printf("finished locktest7\n");
2391 * This demonstrates a problem with our use of GPFS share modes: A file
2392 * descriptor sitting in the pending close queue holding a GPFS share mode
2393 * blocks opening a file another time. Happens with Word 2007 temp files.
2394 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2395 * open is denied with NT_STATUS_SHARING_VIOLATION.
2398 static bool run_locktest8(int dummy
)
2400 struct cli_state
*cli1
;
2401 const char *fname
= "\\lockt8.lck";
2402 uint16_t fnum1
, fnum2
;
2404 bool correct
= False
;
2407 if (!torture_open_connection(&cli1
, 0)) {
2411 cli_sockopt(cli1
, sockops
);
2413 printf("starting locktest8\n");
2415 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2417 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2419 if (!NT_STATUS_IS_OK(status
)) {
2420 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2424 memset(buf
, 0, sizeof(buf
));
2426 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2427 if (!NT_STATUS_IS_OK(status
)) {
2428 d_fprintf(stderr
, "cli_open second time returned %s\n",
2433 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2434 printf("Unable to apply read lock on range 1:1, error was "
2435 "%s\n", cli_errstr(cli1
));
2439 status
= cli_close(cli1
, fnum1
);
2440 if (!NT_STATUS_IS_OK(status
)) {
2441 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2445 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2446 if (!NT_STATUS_IS_OK(status
)) {
2447 d_fprintf(stderr
, "cli_open third time returned %s\n",
2455 cli_close(cli1
, fnum1
);
2456 cli_close(cli1
, fnum2
);
2457 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2458 torture_close_connection(cli1
);
2460 printf("finished locktest8\n");
2465 * This test is designed to be run in conjunction with
2466 * external NFS or POSIX locks taken in the filesystem.
2467 * It checks that the smbd server will block until the
2468 * lock is released and then acquire it. JRA.
2471 static bool got_alarm
;
2472 static int alarm_fd
;
2474 static void alarm_handler(int dummy
)
2479 static void alarm_handler_parent(int dummy
)
2484 static void do_local_lock(int read_fd
, int write_fd
)
2489 const char *local_pathname
= NULL
;
2492 local_pathname
= talloc_asprintf(talloc_tos(),
2493 "%s/lockt9.lck", local_path
);
2494 if (!local_pathname
) {
2495 printf("child: alloc fail\n");
2499 unlink(local_pathname
);
2500 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2502 printf("child: open of %s failed %s.\n",
2503 local_pathname
, strerror(errno
));
2507 /* Now take a fcntl lock. */
2508 lock
.l_type
= F_WRLCK
;
2509 lock
.l_whence
= SEEK_SET
;
2512 lock
.l_pid
= getpid();
2514 ret
= fcntl(fd
,F_SETLK
,&lock
);
2516 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2517 local_pathname
, strerror(errno
));
2520 printf("child: got lock 0:4 on file %s.\n",
2525 CatchSignal(SIGALRM
, alarm_handler
);
2527 /* Signal the parent. */
2528 if (write(write_fd
, &c
, 1) != 1) {
2529 printf("child: start signal fail %s.\n",
2536 /* Wait for the parent to be ready. */
2537 if (read(read_fd
, &c
, 1) != 1) {
2538 printf("child: reply signal fail %s.\n",
2546 printf("child: released lock 0:4 on file %s.\n",
2552 static bool run_locktest9(int dummy
)
2554 struct cli_state
*cli1
;
2555 const char *fname
= "\\lockt9.lck";
2557 bool correct
= False
;
2558 int pipe_in
[2], pipe_out
[2];
2562 struct timeval start
;
2566 printf("starting locktest9\n");
2568 if (local_path
== NULL
) {
2569 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2573 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2578 if (child_pid
== -1) {
2582 if (child_pid
== 0) {
2584 do_local_lock(pipe_out
[0], pipe_in
[1]);
2594 ret
= read(pipe_in
[0], &c
, 1);
2596 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2601 if (!torture_open_connection(&cli1
, 0)) {
2605 cli_sockopt(cli1
, sockops
);
2607 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2609 if (!NT_STATUS_IS_OK(status
)) {
2610 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2614 /* Ensure the child has the lock. */
2615 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2616 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2619 d_printf("Child has the lock.\n");
2622 /* Tell the child to wait 5 seconds then exit. */
2623 ret
= write(pipe_out
[1], &c
, 1);
2625 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2630 /* Wait 20 seconds for the lock. */
2631 alarm_fd
= cli1
->fd
;
2632 CatchSignal(SIGALRM
, alarm_handler_parent
);
2635 start
= timeval_current();
2637 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2638 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2639 "%s\n", cli_errstr(cli1
));
2644 seconds
= timeval_elapsed(&start
);
2646 printf("Parent got the lock after %.2f seconds.\n",
2649 status
= cli_close(cli1
, fnum
);
2650 if (!NT_STATUS_IS_OK(status
)) {
2651 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2658 cli_close(cli1
, fnum
);
2659 torture_close_connection(cli1
);
2663 printf("finished locktest9\n");
2668 test whether fnums and tids open on one VC are available on another (a major
2671 static bool run_fdpasstest(int dummy
)
2673 struct cli_state
*cli1
, *cli2
;
2674 const char *fname
= "\\fdpass.tst";
2679 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2682 cli_sockopt(cli1
, sockops
);
2683 cli_sockopt(cli2
, sockops
);
2685 printf("starting fdpasstest\n");
2687 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2689 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2691 if (!NT_STATUS_IS_OK(status
)) {
2692 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2696 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2698 if (!NT_STATUS_IS_OK(status
)) {
2699 printf("write failed (%s)\n", nt_errstr(status
));
2703 cli2
->vuid
= cli1
->vuid
;
2704 cli2
->cnum
= cli1
->cnum
;
2705 cli2
->pid
= cli1
->pid
;
2707 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2708 printf("read succeeded! nasty security hole [%s]\n",
2713 cli_close(cli1
, fnum1
);
2714 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2716 torture_close_connection(cli1
);
2717 torture_close_connection(cli2
);
2719 printf("finished fdpasstest\n");
2723 static bool run_fdsesstest(int dummy
)
2725 struct cli_state
*cli
;
2730 const char *fname
= "\\fdsess.tst";
2731 const char *fname1
= "\\fdsess1.tst";
2738 if (!torture_open_connection(&cli
, 0))
2740 cli_sockopt(cli
, sockops
);
2742 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2745 saved_cnum
= cli
->cnum
;
2746 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2748 new_cnum
= cli
->cnum
;
2749 cli
->cnum
= saved_cnum
;
2751 printf("starting fdsesstest\n");
2753 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2754 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2756 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2757 if (!NT_STATUS_IS_OK(status
)) {
2758 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2762 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2764 if (!NT_STATUS_IS_OK(status
)) {
2765 printf("write failed (%s)\n", nt_errstr(status
));
2769 saved_vuid
= cli
->vuid
;
2770 cli
->vuid
= new_vuid
;
2772 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2773 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2777 /* Try to open a file with different vuid, samba cnum. */
2778 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2779 printf("create with different vuid, same cnum succeeded.\n");
2780 cli_close(cli
, fnum2
);
2781 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2783 printf("create with different vuid, same cnum failed.\n");
2784 printf("This will cause problems with service clients.\n");
2788 cli
->vuid
= saved_vuid
;
2790 /* Try with same vuid, different cnum. */
2791 cli
->cnum
= new_cnum
;
2793 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2794 printf("read succeeded with different cnum![%s]\n",
2799 cli
->cnum
= saved_cnum
;
2800 cli_close(cli
, fnum1
);
2801 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2803 torture_close_connection(cli
);
2805 printf("finished fdsesstest\n");
2810 This test checks that
2812 1) the server does not allow an unlink on a file that is open
2814 static bool run_unlinktest(int dummy
)
2816 struct cli_state
*cli
;
2817 const char *fname
= "\\unlink.tst";
2819 bool correct
= True
;
2822 if (!torture_open_connection(&cli
, 0)) {
2826 cli_sockopt(cli
, sockops
);
2828 printf("starting unlink test\n");
2830 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2834 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2835 if (!NT_STATUS_IS_OK(status
)) {
2836 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2840 status
= cli_unlink(cli
, fname
,
2841 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2842 if (NT_STATUS_IS_OK(status
)) {
2843 printf("error: server allowed unlink on an open file\n");
2846 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2847 NT_STATUS_SHARING_VIOLATION
);
2850 cli_close(cli
, fnum
);
2851 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2853 if (!torture_close_connection(cli
)) {
2857 printf("unlink test finished\n");
2864 test how many open files this server supports on the one socket
2866 static bool run_maxfidtest(int dummy
)
2868 struct cli_state
*cli
;
2870 uint16_t fnums
[0x11000];
2873 bool correct
= True
;
2879 printf("failed to connect\n");
2883 cli_sockopt(cli
, sockops
);
2885 for (i
=0; i
<0x11000; i
++) {
2886 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2887 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2889 if (!NT_STATUS_IS_OK(status
)) {
2890 printf("open of %s failed (%s)\n",
2891 fname
, nt_errstr(status
));
2892 printf("maximum fnum is %d\n", i
);
2900 printf("cleaning up\n");
2902 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2903 cli_close(cli
, fnums
[i
]);
2905 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2906 if (!NT_STATUS_IS_OK(status
)) {
2907 printf("unlink of %s failed (%s)\n",
2908 fname
, nt_errstr(status
));
2915 printf("maxfid test finished\n");
2916 if (!torture_close_connection(cli
)) {
2922 /* generate a random buffer */
2923 static void rand_buf(char *buf
, int len
)
2926 *buf
= (char)sys_random();
2931 /* send smb negprot commands, not reading the response */
2932 static bool run_negprot_nowait(int dummy
)
2934 struct tevent_context
*ev
;
2936 struct cli_state
*cli
;
2937 bool correct
= True
;
2939 printf("starting negprot nowait test\n");
2941 ev
= tevent_context_init(talloc_tos());
2946 if (!(cli
= open_nbt_connection())) {
2951 for (i
=0;i
<50000;i
++) {
2952 struct tevent_req
*req
;
2954 req
= cli_negprot_send(ev
, ev
, cli
);
2959 if (!tevent_req_poll(req
, ev
)) {
2960 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
2968 if (torture_close_connection(cli
)) {
2972 printf("finished negprot nowait test\n");
2977 /* send smb negprot commands, not reading the response */
2978 static bool run_bad_nbt_session(int dummy
)
2980 struct nmb_name called
, calling
;
2981 struct sockaddr_storage ss
;
2986 printf("starting bad nbt session test\n");
2988 make_nmb_name(&calling
, myname
, 0x0);
2989 make_nmb_name(&called
, host
, 0x20);
2991 if (!resolve_name(host
, &ss
, 0x20, true)) {
2992 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
2996 status
= open_socket_out(&ss
, 139, 10000, &fd
);
2997 if (!NT_STATUS_IS_OK(status
)) {
2998 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3003 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3006 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3011 printf("finished bad nbt session test\n");
3015 /* send random IPC commands */
3016 static bool run_randomipc(int dummy
)
3018 char *rparam
= NULL
;
3020 unsigned int rdrcnt
,rprcnt
;
3022 int api
, param_len
, i
;
3023 struct cli_state
*cli
;
3024 bool correct
= True
;
3027 printf("starting random ipc test\n");
3029 if (!torture_open_connection(&cli
, 0)) {
3033 for (i
=0;i
<count
;i
++) {
3034 api
= sys_random() % 500;
3035 param_len
= (sys_random() % 64);
3037 rand_buf(param
, param_len
);
3042 param
, param_len
, 8,
3043 NULL
, 0, BUFFER_SIZE
,
3047 printf("%d/%d\r", i
,count
);
3050 printf("%d/%d\n", i
, count
);
3052 if (!torture_close_connection(cli
)) {
3056 printf("finished random ipc test\n");
3063 static void browse_callback(const char *sname
, uint32 stype
,
3064 const char *comment
, void *state
)
3066 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3072 This test checks the browse list code
3075 static bool run_browsetest(int dummy
)
3077 static struct cli_state
*cli
;
3078 bool correct
= True
;
3080 printf("starting browse test\n");
3082 if (!torture_open_connection(&cli
, 0)) {
3086 printf("domain list:\n");
3087 cli_NetServerEnum(cli
, cli
->server_domain
,
3088 SV_TYPE_DOMAIN_ENUM
,
3089 browse_callback
, NULL
);
3091 printf("machine list:\n");
3092 cli_NetServerEnum(cli
, cli
->server_domain
,
3094 browse_callback
, NULL
);
3096 if (!torture_close_connection(cli
)) {
3100 printf("browse test finished\n");
3108 This checks how the getatr calls works
3110 static bool run_attrtest(int dummy
)
3112 struct cli_state
*cli
;
3115 const char *fname
= "\\attrib123456789.tst";
3116 bool correct
= True
;
3119 printf("starting attrib test\n");
3121 if (!torture_open_connection(&cli
, 0)) {
3125 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3126 cli_open(cli
, fname
,
3127 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3128 cli_close(cli
, fnum
);
3130 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3131 if (!NT_STATUS_IS_OK(status
)) {
3132 printf("getatr failed (%s)\n", nt_errstr(status
));
3136 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3137 printf("ERROR: SMBgetatr bug. time is %s",
3143 t2
= t
-60*60*24; /* 1 day ago */
3145 status
= cli_setatr(cli
, fname
, 0, t2
);
3146 if (!NT_STATUS_IS_OK(status
)) {
3147 printf("setatr failed (%s)\n", nt_errstr(status
));
3151 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3152 if (!NT_STATUS_IS_OK(status
)) {
3153 printf("getatr failed (%s)\n", nt_errstr(status
));
3158 printf("ERROR: getatr/setatr bug. times are\n%s",
3160 printf("%s", ctime(&t2
));
3164 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3166 if (!torture_close_connection(cli
)) {
3170 printf("attrib test finished\n");
3177 This checks a couple of trans2 calls
3179 static bool run_trans2test(int dummy
)
3181 struct cli_state
*cli
;
3184 time_t c_time
, a_time
, m_time
;
3185 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3186 const char *fname
= "\\trans2.tst";
3187 const char *dname
= "\\trans2";
3188 const char *fname2
= "\\trans2\\trans2.tst";
3190 bool correct
= True
;
3194 printf("starting trans2 test\n");
3196 if (!torture_open_connection(&cli
, 0)) {
3200 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3201 if (!NT_STATUS_IS_OK(status
)) {
3202 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3207 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3208 cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3209 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3210 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3211 if (!NT_STATUS_IS_OK(status
)) {
3212 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3216 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3217 if (!NT_STATUS_IS_OK(status
)) {
3218 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3222 if (strcmp(pname
, fname
)) {
3223 printf("qfilename gave different name? [%s] [%s]\n",
3228 cli_close(cli
, fnum
);
3232 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3233 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3235 if (!NT_STATUS_IS_OK(status
)) {
3236 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3239 cli_close(cli
, fnum
);
3241 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3243 if (!NT_STATUS_IS_OK(status
)) {
3244 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3247 if (c_time
!= m_time
) {
3248 printf("create time=%s", ctime(&c_time
));
3249 printf("modify time=%s", ctime(&m_time
));
3250 printf("This system appears to have sticky create times\n");
3252 if (a_time
% (60*60) == 0) {
3253 printf("access time=%s", ctime(&a_time
));
3254 printf("This system appears to set a midnight access time\n");
3258 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3259 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3265 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3266 cli_open(cli
, fname
,
3267 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3268 cli_close(cli
, fnum
);
3269 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3270 &m_time_ts
, &size
, NULL
, NULL
);
3271 if (!NT_STATUS_IS_OK(status
)) {
3272 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3275 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3276 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3277 printf("This system appears to set a initial 0 write time\n");
3282 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3285 /* check if the server updates the directory modification time
3286 when creating a new file */
3287 status
= cli_mkdir(cli
, dname
);
3288 if (!NT_STATUS_IS_OK(status
)) {
3289 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3293 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3294 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3295 if (!NT_STATUS_IS_OK(status
)) {
3296 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3300 cli_open(cli
, fname2
,
3301 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3302 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3303 cli_close(cli
, fnum
);
3304 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3305 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3306 if (!NT_STATUS_IS_OK(status
)) {
3307 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3310 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3312 printf("This system does not update directory modification times\n");
3316 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3317 cli_rmdir(cli
, dname
);
3319 if (!torture_close_connection(cli
)) {
3323 printf("trans2 test finished\n");
3329 This checks new W2K calls.
3332 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3334 uint8_t *buf
= NULL
;
3338 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3339 pcli
->max_xmit
, NULL
, &buf
, &len
);
3340 if (!NT_STATUS_IS_OK(status
)) {
3341 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3344 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3345 dump_data(0, (uint8
*)buf
, len
);
3352 static bool run_w2ktest(int dummy
)
3354 struct cli_state
*cli
;
3356 const char *fname
= "\\w2ktest\\w2k.tst";
3358 bool correct
= True
;
3360 printf("starting w2k test\n");
3362 if (!torture_open_connection(&cli
, 0)) {
3366 cli_open(cli
, fname
,
3367 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3369 for (level
= 1004; level
< 1040; level
++) {
3370 new_trans(cli
, fnum
, level
);
3373 cli_close(cli
, fnum
);
3375 if (!torture_close_connection(cli
)) {
3379 printf("w2k test finished\n");
3386 this is a harness for some oplock tests
3388 static bool run_oplock1(int dummy
)
3390 struct cli_state
*cli1
;
3391 const char *fname
= "\\lockt1.lck";
3393 bool correct
= True
;
3396 printf("starting oplock test 1\n");
3398 if (!torture_open_connection(&cli1
, 0)) {
3402 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3404 cli_sockopt(cli1
, sockops
);
3406 cli1
->use_oplocks
= True
;
3408 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3410 if (!NT_STATUS_IS_OK(status
)) {
3411 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3415 cli1
->use_oplocks
= False
;
3417 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3418 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3420 status
= cli_close(cli1
, fnum1
);
3421 if (!NT_STATUS_IS_OK(status
)) {
3422 printf("close2 failed (%s)\n", nt_errstr(status
));
3426 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3427 if (!NT_STATUS_IS_OK(status
)) {
3428 printf("unlink failed (%s)\n", nt_errstr(status
));
3432 if (!torture_close_connection(cli1
)) {
3436 printf("finished oplock test 1\n");
3441 static bool run_oplock2(int dummy
)
3443 struct cli_state
*cli1
, *cli2
;
3444 const char *fname
= "\\lockt2.lck";
3445 uint16_t fnum1
, fnum2
;
3446 int saved_use_oplocks
= use_oplocks
;
3448 bool correct
= True
;
3449 volatile bool *shared_correct
;
3452 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3453 *shared_correct
= True
;
3455 use_level_II_oplocks
= True
;
3458 printf("starting oplock test 2\n");
3460 if (!torture_open_connection(&cli1
, 0)) {
3461 use_level_II_oplocks
= False
;
3462 use_oplocks
= saved_use_oplocks
;
3466 cli1
->use_oplocks
= True
;
3467 cli1
->use_level_II_oplocks
= True
;
3469 if (!torture_open_connection(&cli2
, 1)) {
3470 use_level_II_oplocks
= False
;
3471 use_oplocks
= saved_use_oplocks
;
3475 cli2
->use_oplocks
= True
;
3476 cli2
->use_level_II_oplocks
= True
;
3478 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3480 cli_sockopt(cli1
, sockops
);
3481 cli_sockopt(cli2
, sockops
);
3483 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3485 if (!NT_STATUS_IS_OK(status
)) {
3486 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3490 /* Don't need the globals any more. */
3491 use_level_II_oplocks
= False
;
3492 use_oplocks
= saved_use_oplocks
;
3496 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3497 if (!NT_STATUS_IS_OK(status
)) {
3498 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3499 *shared_correct
= False
;
3505 status
= cli_close(cli2
, fnum2
);
3506 if (!NT_STATUS_IS_OK(status
)) {
3507 printf("close2 failed (%s)\n", nt_errstr(status
));
3508 *shared_correct
= False
;
3516 /* Ensure cli1 processes the break. Empty file should always return 0
3519 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3520 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3524 /* Should now be at level II. */
3525 /* Test if sending a write locks causes a break to none. */
3527 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3528 printf("lock failed (%s)\n", cli_errstr(cli1
));
3532 cli_unlock(cli1
, fnum1
, 0, 4);
3536 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3537 printf("lock failed (%s)\n", cli_errstr(cli1
));
3541 cli_unlock(cli1
, fnum1
, 0, 4);
3545 cli_read(cli1
, fnum1
, buf
, 0, 4);
3547 status
= cli_close(cli1
, fnum1
);
3548 if (!NT_STATUS_IS_OK(status
)) {
3549 printf("close1 failed (%s)\n", nt_errstr(status
));
3555 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3556 if (!NT_STATUS_IS_OK(status
)) {
3557 printf("unlink failed (%s)\n", nt_errstr(status
));
3561 if (!torture_close_connection(cli1
)) {
3565 if (!*shared_correct
) {
3569 printf("finished oplock test 2\n");
3574 struct oplock4_state
{
3575 struct tevent_context
*ev
;
3576 struct cli_state
*cli
;
3581 static void oplock4_got_break(struct tevent_req
*req
);
3582 static void oplock4_got_open(struct tevent_req
*req
);
3584 static bool run_oplock4(int dummy
)
3586 struct tevent_context
*ev
;
3587 struct cli_state
*cli1
, *cli2
;
3588 struct tevent_req
*oplock_req
, *open_req
;
3589 const char *fname
= "\\lockt4.lck";
3590 const char *fname_ln
= "\\lockt4_ln.lck";
3591 uint16_t fnum1
, fnum2
;
3592 int saved_use_oplocks
= use_oplocks
;
3594 bool correct
= true;
3598 struct oplock4_state
*state
;
3600 printf("starting oplock test 4\n");
3602 if (!torture_open_connection(&cli1
, 0)) {
3603 use_level_II_oplocks
= false;
3604 use_oplocks
= saved_use_oplocks
;
3608 if (!torture_open_connection(&cli2
, 1)) {
3609 use_level_II_oplocks
= false;
3610 use_oplocks
= saved_use_oplocks
;
3614 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3615 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3617 cli_sockopt(cli1
, sockops
);
3618 cli_sockopt(cli2
, sockops
);
3620 /* Create the file. */
3621 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3623 if (!NT_STATUS_IS_OK(status
)) {
3624 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3628 status
= cli_close(cli1
, fnum1
);
3629 if (!NT_STATUS_IS_OK(status
)) {
3630 printf("close1 failed (%s)\n", nt_errstr(status
));
3634 /* Now create a hardlink. */
3635 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3636 if (!NT_STATUS_IS_OK(status
)) {
3637 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3641 /* Prove that opening hardlinks cause deny modes to conflict. */
3642 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3643 if (!NT_STATUS_IS_OK(status
)) {
3644 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3648 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3649 if (NT_STATUS_IS_OK(status
)) {
3650 printf("open of %s succeeded - should fail with sharing violation.\n",
3655 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3656 printf("open of %s should fail with sharing violation. Got %s\n",
3657 fname_ln
, nt_errstr(status
));
3661 status
= cli_close(cli1
, fnum1
);
3662 if (!NT_STATUS_IS_OK(status
)) {
3663 printf("close1 failed (%s)\n", nt_errstr(status
));
3667 cli1
->use_oplocks
= true;
3668 cli1
->use_level_II_oplocks
= true;
3670 cli2
->use_oplocks
= true;
3671 cli2
->use_level_II_oplocks
= true;
3673 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3674 if (!NT_STATUS_IS_OK(status
)) {
3675 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3679 ev
= tevent_context_init(talloc_tos());
3681 printf("tevent_req_create failed\n");
3685 state
= talloc(ev
, struct oplock4_state
);
3686 if (state
== NULL
) {
3687 printf("talloc failed\n");
3692 state
->got_break
= &got_break
;
3693 state
->fnum2
= &fnum2
;
3695 oplock_req
= cli_smb_oplock_break_waiter_send(
3696 talloc_tos(), ev
, cli1
);
3697 if (oplock_req
== NULL
) {
3698 printf("cli_smb_oplock_break_waiter_send failed\n");
3701 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3703 open_req
= cli_open_send(
3704 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3705 if (oplock_req
== NULL
) {
3706 printf("cli_open_send failed\n");
3709 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3714 while (!got_break
|| fnum2
== 0xffff) {
3716 ret
= tevent_loop_once(ev
);
3718 printf("tevent_loop_once failed: %s\n",
3724 status
= cli_close(cli2
, fnum2
);
3725 if (!NT_STATUS_IS_OK(status
)) {
3726 printf("close2 failed (%s)\n", nt_errstr(status
));
3730 status
= cli_close(cli1
, fnum1
);
3731 if (!NT_STATUS_IS_OK(status
)) {
3732 printf("close1 failed (%s)\n", nt_errstr(status
));
3736 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3737 if (!NT_STATUS_IS_OK(status
)) {
3738 printf("unlink failed (%s)\n", nt_errstr(status
));
3742 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3743 if (!NT_STATUS_IS_OK(status
)) {
3744 printf("unlink failed (%s)\n", nt_errstr(status
));
3748 if (!torture_close_connection(cli1
)) {
3756 printf("finished oplock test 4\n");
3761 static void oplock4_got_break(struct tevent_req
*req
)
3763 struct oplock4_state
*state
= tevent_req_callback_data(
3764 req
, struct oplock4_state
);
3769 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3771 if (!NT_STATUS_IS_OK(status
)) {
3772 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3776 *state
->got_break
= true;
3778 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3781 printf("cli_oplock_ack_send failed\n");
3786 static void oplock4_got_open(struct tevent_req
*req
)
3788 struct oplock4_state
*state
= tevent_req_callback_data(
3789 req
, struct oplock4_state
);
3792 status
= cli_open_recv(req
, state
->fnum2
);
3793 if (!NT_STATUS_IS_OK(status
)) {
3794 printf("cli_open_recv returned %s\n", nt_errstr(status
));
3795 *state
->fnum2
= 0xffff;
3800 Test delete on close semantics.
3802 static bool run_deletetest(int dummy
)
3804 struct cli_state
*cli1
= NULL
;
3805 struct cli_state
*cli2
= NULL
;
3806 const char *fname
= "\\delete.file";
3807 uint16_t fnum1
= (uint16_t)-1;
3808 uint16_t fnum2
= (uint16_t)-1;
3809 bool correct
= True
;
3812 printf("starting delete test\n");
3814 if (!torture_open_connection(&cli1
, 0)) {
3818 cli_sockopt(cli1
, sockops
);
3820 /* Test 1 - this should delete the file on close. */
3822 cli_setatr(cli1
, fname
, 0, 0);
3823 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3825 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3826 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3827 FILE_DELETE_ON_CLOSE
, 0, &fnum1
);
3828 if (!NT_STATUS_IS_OK(status
)) {
3829 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3834 status
= cli_close(cli1
, fnum1
);
3835 if (!NT_STATUS_IS_OK(status
)) {
3836 printf("[1] close failed (%s)\n", nt_errstr(status
));
3841 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3842 printf("[1] open of %s succeeded (should fail)\n", fname
);
3847 printf("first delete on close test succeeded.\n");
3849 /* Test 2 - this should delete the file on close. */
3851 cli_setatr(cli1
, fname
, 0, 0);
3852 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3854 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3855 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3856 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3857 if (!NT_STATUS_IS_OK(status
)) {
3858 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3863 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3864 if (!NT_STATUS_IS_OK(status
)) {
3865 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3870 status
= cli_close(cli1
, fnum1
);
3871 if (!NT_STATUS_IS_OK(status
)) {
3872 printf("[2] close failed (%s)\n", nt_errstr(status
));
3877 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3878 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3879 status
= cli_close(cli1
, fnum1
);
3880 if (!NT_STATUS_IS_OK(status
)) {
3881 printf("[2] close failed (%s)\n", nt_errstr(status
));
3885 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3887 printf("second delete on close test succeeded.\n");
3890 cli_setatr(cli1
, fname
, 0, 0);
3891 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3893 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3894 FILE_ATTRIBUTE_NORMAL
,
3895 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3896 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3897 if (!NT_STATUS_IS_OK(status
)) {
3898 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
3903 /* This should fail with a sharing violation - open for delete is only compatible
3904 with SHARE_DELETE. */
3906 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3907 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3908 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3913 /* This should succeed. */
3914 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3915 FILE_ATTRIBUTE_NORMAL
,
3916 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3917 FILE_OPEN
, 0, 0, &fnum2
);
3918 if (!NT_STATUS_IS_OK(status
)) {
3919 printf("[3] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
3924 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3925 if (!NT_STATUS_IS_OK(status
)) {
3926 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3931 status
= cli_close(cli1
, fnum1
);
3932 if (!NT_STATUS_IS_OK(status
)) {
3933 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
3938 status
= cli_close(cli1
, fnum2
);
3939 if (!NT_STATUS_IS_OK(status
)) {
3940 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
3945 /* This should fail - file should no longer be there. */
3947 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3948 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3949 status
= cli_close(cli1
, fnum1
);
3950 if (!NT_STATUS_IS_OK(status
)) {
3951 printf("[3] close failed (%s)\n", nt_errstr(status
));
3953 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3957 printf("third delete on close test succeeded.\n");
3960 cli_setatr(cli1
, fname
, 0, 0);
3961 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3963 status
= cli_ntcreate(cli1
, fname
, 0,
3964 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3965 FILE_ATTRIBUTE_NORMAL
,
3966 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3967 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3968 if (!NT_STATUS_IS_OK(status
)) {
3969 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3974 /* This should succeed. */
3975 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3976 FILE_ATTRIBUTE_NORMAL
,
3977 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3978 FILE_OPEN
, 0, 0, &fnum2
);
3979 if (!NT_STATUS_IS_OK(status
)) {
3980 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
3985 status
= cli_close(cli1
, fnum2
);
3986 if (!NT_STATUS_IS_OK(status
)) {
3987 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
3992 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3993 if (!NT_STATUS_IS_OK(status
)) {
3994 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3999 /* This should fail - no more opens once delete on close set. */
4000 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4001 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4002 FILE_OPEN
, 0, 0, &fnum2
))) {
4003 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4007 printf("fourth delete on close test succeeded.\n");
4009 status
= cli_close(cli1
, fnum1
);
4010 if (!NT_STATUS_IS_OK(status
)) {
4011 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4017 cli_setatr(cli1
, fname
, 0, 0);
4018 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4020 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4021 if (!NT_STATUS_IS_OK(status
)) {
4022 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4027 /* This should fail - only allowed on NT opens with DELETE access. */
4029 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4030 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4035 status
= cli_close(cli1
, fnum1
);
4036 if (!NT_STATUS_IS_OK(status
)) {
4037 printf("[5] close - 2 failed (%s)\n", nt_errstr(status
));
4042 printf("fifth delete on close test succeeded.\n");
4045 cli_setatr(cli1
, fname
, 0, 0);
4046 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4048 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4049 FILE_ATTRIBUTE_NORMAL
,
4050 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4051 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4052 if (!NT_STATUS_IS_OK(status
)) {
4053 printf("[6] open of %s failed (%s)\n", fname
,
4059 /* This should fail - only allowed on NT opens with DELETE access. */
4061 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4062 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4067 status
= cli_close(cli1
, fnum1
);
4068 if (!NT_STATUS_IS_OK(status
)) {
4069 printf("[6] close - 2 failed (%s)\n", nt_errstr(status
));
4074 printf("sixth delete on close test succeeded.\n");
4077 cli_setatr(cli1
, fname
, 0, 0);
4078 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4080 status
= cli_ntcreate(cli1
, fname
, 0,
4081 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4082 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4084 if (!NT_STATUS_IS_OK(status
)) {
4085 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4090 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4091 printf("[7] setting delete_on_close on file failed !\n");
4096 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
4097 printf("[7] unsetting delete_on_close on file failed !\n");
4102 status
= cli_close(cli1
, fnum1
);
4103 if (!NT_STATUS_IS_OK(status
)) {
4104 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4109 /* This next open should succeed - we reset the flag. */
4110 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4111 if (!NT_STATUS_IS_OK(status
)) {
4112 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4117 status
= cli_close(cli1
, fnum1
);
4118 if (!NT_STATUS_IS_OK(status
)) {
4119 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4124 printf("seventh delete on close test succeeded.\n");
4127 cli_setatr(cli1
, fname
, 0, 0);
4128 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4130 if (!torture_open_connection(&cli2
, 1)) {
4131 printf("[8] failed to open second connection.\n");
4136 cli_sockopt(cli1
, sockops
);
4138 status
= cli_ntcreate(cli1
, fname
, 0,
4139 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4140 FILE_ATTRIBUTE_NORMAL
,
4141 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4142 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4143 if (!NT_STATUS_IS_OK(status
)) {
4144 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4149 status
= cli_ntcreate(cli2
, fname
, 0,
4150 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4151 FILE_ATTRIBUTE_NORMAL
,
4152 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4153 FILE_OPEN
, 0, 0, &fnum2
);
4154 if (!NT_STATUS_IS_OK(status
)) {
4155 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4160 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4161 printf("[8] setting delete_on_close on file failed !\n");
4166 status
= cli_close(cli1
, fnum1
);
4167 if (!NT_STATUS_IS_OK(status
)) {
4168 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4173 status
= cli_close(cli2
, fnum2
);
4174 if (!NT_STATUS_IS_OK(status
)) {
4175 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4180 /* This should fail.. */
4181 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4182 if (NT_STATUS_IS_OK(status
)) {
4183 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4187 printf("eighth delete on close test succeeded.\n");
4189 /* This should fail - we need to set DELETE_ACCESS. */
4190 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
4191 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
4192 printf("[9] open of %s succeeded should have failed!\n", fname
);
4197 printf("ninth delete on close test succeeded.\n");
4199 status
= cli_ntcreate(cli1
, fname
, 0,
4200 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4201 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4202 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4204 if (!NT_STATUS_IS_OK(status
)) {
4205 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4210 /* This should delete the file. */
4211 status
= cli_close(cli1
, fnum1
);
4212 if (!NT_STATUS_IS_OK(status
)) {
4213 printf("[10] close failed (%s)\n", nt_errstr(status
));
4218 /* This should fail.. */
4219 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4220 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4224 printf("tenth delete on close test succeeded.\n");
4226 cli_setatr(cli1
, fname
, 0, 0);
4227 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4229 /* What error do we get when attempting to open a read-only file with
4232 /* Create a readonly file. */
4233 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4234 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4235 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4236 if (!NT_STATUS_IS_OK(status
)) {
4237 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4242 status
= cli_close(cli1
, fnum1
);
4243 if (!NT_STATUS_IS_OK(status
)) {
4244 printf("[11] close failed (%s)\n", nt_errstr(status
));
4249 /* Now try open for delete access. */
4250 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4251 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4252 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4253 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
4254 cli_close(cli1
, fnum1
);
4258 NTSTATUS nterr
= cli_nt_error(cli1
);
4259 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
4260 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
4264 printf("eleventh delete on close test succeeded.\n");
4268 printf("finished delete test\n");
4271 /* FIXME: This will crash if we aborted before cli2 got
4272 * intialized, because these functions don't handle
4273 * uninitialized connections. */
4275 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4276 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4277 cli_setatr(cli1
, fname
, 0, 0);
4278 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4280 if (cli1
&& !torture_close_connection(cli1
)) {
4283 if (cli2
&& !torture_close_connection(cli2
)) {
4289 static bool run_deletetest_ln(int dummy
)
4291 struct cli_state
*cli
;
4292 const char *fname
= "\\delete1";
4293 const char *fname_ln
= "\\delete1_ln";
4297 bool correct
= true;
4300 printf("starting deletetest-ln\n");
4302 if (!torture_open_connection(&cli
, 0)) {
4306 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4307 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4309 cli_sockopt(cli
, sockops
);
4311 /* Create the file. */
4312 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4313 if (!NT_STATUS_IS_OK(status
)) {
4314 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4318 status
= cli_close(cli
, fnum
);
4319 if (!NT_STATUS_IS_OK(status
)) {
4320 printf("close1 failed (%s)\n", nt_errstr(status
));
4324 /* Now create a hardlink. */
4325 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4326 if (!NT_STATUS_IS_OK(status
)) {
4327 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4331 /* Open the original file. */
4332 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4333 FILE_ATTRIBUTE_NORMAL
,
4334 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4335 FILE_OPEN_IF
, 0, 0, &fnum
);
4336 if (!NT_STATUS_IS_OK(status
)) {
4337 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4341 /* Unlink the hard link path. */
4342 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4343 FILE_ATTRIBUTE_NORMAL
,
4344 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4345 FILE_OPEN_IF
, 0, 0, &fnum1
);
4346 if (!NT_STATUS_IS_OK(status
)) {
4347 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4350 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4351 if (!NT_STATUS_IS_OK(status
)) {
4352 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4353 __location__
, fname_ln
, nt_errstr(status
));
4357 status
= cli_close(cli
, fnum1
);
4358 if (!NT_STATUS_IS_OK(status
)) {
4359 printf("close %s failed (%s)\n",
4360 fname_ln
, nt_errstr(status
));
4364 status
= cli_close(cli
, fnum
);
4365 if (!NT_STATUS_IS_OK(status
)) {
4366 printf("close %s failed (%s)\n",
4367 fname
, nt_errstr(status
));
4371 /* Ensure the original file is still there. */
4372 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4373 if (!NT_STATUS_IS_OK(status
)) {
4374 printf("%s getatr on file %s failed (%s)\n",
4381 /* Ensure the link path is gone. */
4382 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4383 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4384 printf("%s, getatr for file %s returned wrong error code %s "
4385 "- should have been deleted\n",
4387 fname_ln
, nt_errstr(status
));
4391 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4392 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4394 if (!torture_close_connection(cli
)) {
4398 printf("finished deletetest-ln\n");
4404 print out server properties
4406 static bool run_properties(int dummy
)
4408 struct cli_state
*cli
;
4409 bool correct
= True
;
4411 printf("starting properties test\n");
4415 if (!torture_open_connection(&cli
, 0)) {
4419 cli_sockopt(cli
, sockops
);
4421 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
4423 if (!torture_close_connection(cli
)) {
4432 /* FIRST_DESIRED_ACCESS 0xf019f */
4433 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4434 FILE_READ_EA| /* 0xf */ \
4435 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4436 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4437 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4438 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4439 /* SECOND_DESIRED_ACCESS 0xe0080 */
4440 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4441 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4442 WRITE_OWNER_ACCESS /* 0xe0000 */
4445 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4446 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4448 WRITE_OWNER_ACCESS /* */
4452 Test ntcreate calls made by xcopy
4454 static bool run_xcopy(int dummy
)
4456 static struct cli_state
*cli1
;
4457 const char *fname
= "\\test.txt";
4458 bool correct
= True
;
4459 uint16_t fnum1
, fnum2
;
4462 printf("starting xcopy test\n");
4464 if (!torture_open_connection(&cli1
, 0)) {
4468 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4469 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4470 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
);
4471 if (!NT_STATUS_IS_OK(status
)) {
4472 printf("First open failed - %s\n", nt_errstr(status
));
4476 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4477 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4478 FILE_OPEN
, 0x200000, 0, &fnum2
);
4479 if (!NT_STATUS_IS_OK(status
)) {
4480 printf("second open failed - %s\n", nt_errstr(status
));
4484 if (!torture_close_connection(cli1
)) {
4492 Test rename on files open with share delete and no share delete.
4494 static bool run_rename(int dummy
)
4496 static struct cli_state
*cli1
;
4497 const char *fname
= "\\test.txt";
4498 const char *fname1
= "\\test1.txt";
4499 bool correct
= True
;
4504 printf("starting rename test\n");
4506 if (!torture_open_connection(&cli1
, 0)) {
4510 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4511 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4513 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4514 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4515 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4516 if (!NT_STATUS_IS_OK(status
)) {
4517 printf("First open failed - %s\n", nt_errstr(status
));
4521 status
= cli_rename(cli1
, fname
, fname1
);
4522 if (!NT_STATUS_IS_OK(status
)) {
4523 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4525 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4529 status
= cli_close(cli1
, fnum1
);
4530 if (!NT_STATUS_IS_OK(status
)) {
4531 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4535 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4536 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4537 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4539 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4541 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4543 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4544 if (!NT_STATUS_IS_OK(status
)) {
4545 printf("Second open failed - %s\n", nt_errstr(status
));
4549 status
= cli_rename(cli1
, fname
, fname1
);
4550 if (!NT_STATUS_IS_OK(status
)) {
4551 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4554 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4557 status
= cli_close(cli1
, fnum1
);
4558 if (!NT_STATUS_IS_OK(status
)) {
4559 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4563 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4564 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4566 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4567 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4568 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4569 if (!NT_STATUS_IS_OK(status
)) {
4570 printf("Third open failed - %s\n", nt_errstr(status
));
4579 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4580 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4581 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4584 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4585 printf("[8] setting delete_on_close on file failed !\n");
4589 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4590 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4596 status
= cli_rename(cli1
, fname
, fname1
);
4597 if (!NT_STATUS_IS_OK(status
)) {
4598 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4601 printf("Third rename succeeded (SHARE_NONE)\n");
4604 status
= cli_close(cli1
, fnum1
);
4605 if (!NT_STATUS_IS_OK(status
)) {
4606 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4610 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4611 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4615 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4616 FILE_ATTRIBUTE_NORMAL
,
4617 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4618 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4619 if (!NT_STATUS_IS_OK(status
)) {
4620 printf("Fourth open failed - %s\n", nt_errstr(status
));
4624 status
= cli_rename(cli1
, fname
, fname1
);
4625 if (!NT_STATUS_IS_OK(status
)) {
4626 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4628 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4632 status
= cli_close(cli1
, fnum1
);
4633 if (!NT_STATUS_IS_OK(status
)) {
4634 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4638 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4639 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4643 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4644 FILE_ATTRIBUTE_NORMAL
,
4645 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4646 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4647 if (!NT_STATUS_IS_OK(status
)) {
4648 printf("Fifth open failed - %s\n", nt_errstr(status
));
4652 status
= cli_rename(cli1
, fname
, fname1
);
4653 if (!NT_STATUS_IS_OK(status
)) {
4654 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4657 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4661 * Now check if the first name still exists ...
4664 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4665 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4666 printf("Opening original file after rename of open file fails: %s\n",
4670 printf("Opening original file after rename of open file works ...\n");
4671 (void)cli_close(cli1, fnum2);
4675 status
= cli_close(cli1
, fnum1
);
4676 if (!NT_STATUS_IS_OK(status
)) {
4677 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4681 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4682 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4683 if (!NT_STATUS_IS_OK(status
)) {
4684 printf("getatr on file %s failed - %s ! \n",
4685 fname1
, nt_errstr(status
));
4688 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4689 printf("Renamed file %s has wrong attr 0x%x "
4690 "(should be 0x%x)\n",
4693 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4696 printf("Renamed file %s has archive bit set\n", fname1
);
4700 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4701 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4703 if (!torture_close_connection(cli1
)) {
4710 static bool run_pipe_number(int dummy
)
4712 struct cli_state
*cli1
;
4713 const char *pipe_name
= "\\SPOOLSS";
4718 printf("starting pipenumber test\n");
4719 if (!torture_open_connection(&cli1
, 0)) {
4723 cli_sockopt(cli1
, sockops
);
4725 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4726 FILE_ATTRIBUTE_NORMAL
,
4727 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4728 FILE_OPEN_IF
, 0, 0, &fnum
);
4729 if (!NT_STATUS_IS_OK(status
)) {
4730 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4734 printf("\r%6d", num_pipes
);
4737 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4738 torture_close_connection(cli1
);
4743 Test open mode returns on read-only files.
4745 static bool run_opentest(int dummy
)
4747 static struct cli_state
*cli1
;
4748 static struct cli_state
*cli2
;
4749 const char *fname
= "\\readonly.file";
4750 uint16_t fnum1
, fnum2
;
4753 bool correct
= True
;
4757 printf("starting open test\n");
4759 if (!torture_open_connection(&cli1
, 0)) {
4763 cli_setatr(cli1
, fname
, 0, 0);
4764 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4766 cli_sockopt(cli1
, sockops
);
4768 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4769 if (!NT_STATUS_IS_OK(status
)) {
4770 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4774 status
= cli_close(cli1
, fnum1
);
4775 if (!NT_STATUS_IS_OK(status
)) {
4776 printf("close2 failed (%s)\n", nt_errstr(status
));
4780 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4781 if (!NT_STATUS_IS_OK(status
)) {
4782 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4786 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4787 if (!NT_STATUS_IS_OK(status
)) {
4788 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4792 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4793 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4795 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4796 NT_STATUS_ACCESS_DENIED
)) {
4797 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4800 printf("finished open test 1\n");
4802 cli_close(cli1
, fnum1
);
4804 /* Now try not readonly and ensure ERRbadshare is returned. */
4806 cli_setatr(cli1
, fname
, 0, 0);
4808 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4809 if (!NT_STATUS_IS_OK(status
)) {
4810 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4814 /* This will fail - but the error should be ERRshare. */
4815 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4817 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4818 NT_STATUS_SHARING_VIOLATION
)) {
4819 printf("correct error code ERRDOS/ERRbadshare returned\n");
4822 status
= cli_close(cli1
, fnum1
);
4823 if (!NT_STATUS_IS_OK(status
)) {
4824 printf("close2 failed (%s)\n", nt_errstr(status
));
4828 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4830 printf("finished open test 2\n");
4832 /* Test truncate open disposition on file opened for read. */
4833 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4834 if (!NT_STATUS_IS_OK(status
)) {
4835 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
4839 /* write 20 bytes. */
4841 memset(buf
, '\0', 20);
4843 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4844 if (!NT_STATUS_IS_OK(status
)) {
4845 printf("write failed (%s)\n", nt_errstr(status
));
4849 status
= cli_close(cli1
, fnum1
);
4850 if (!NT_STATUS_IS_OK(status
)) {
4851 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
4855 /* Ensure size == 20. */
4856 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4857 if (!NT_STATUS_IS_OK(status
)) {
4858 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4863 printf("(3) file size != 20\n");
4867 /* Now test if we can truncate a file opened for readonly. */
4868 status
= cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
4869 if (!NT_STATUS_IS_OK(status
)) {
4870 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
4874 status
= cli_close(cli1
, fnum1
);
4875 if (!NT_STATUS_IS_OK(status
)) {
4876 printf("close2 failed (%s)\n", nt_errstr(status
));
4880 /* Ensure size == 0. */
4881 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4882 if (!NT_STATUS_IS_OK(status
)) {
4883 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4888 printf("(3) file size != 0\n");
4891 printf("finished open test 3\n");
4893 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4895 printf("Do ctemp tests\n");
4896 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
4897 if (!NT_STATUS_IS_OK(status
)) {
4898 printf("ctemp failed (%s)\n", nt_errstr(status
));
4902 printf("ctemp gave path %s\n", tmp_path
);
4903 status
= cli_close(cli1
, fnum1
);
4904 if (!NT_STATUS_IS_OK(status
)) {
4905 printf("close of temp failed (%s)\n", nt_errstr(status
));
4908 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4909 if (!NT_STATUS_IS_OK(status
)) {
4910 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
4913 /* Test the non-io opens... */
4915 if (!torture_open_connection(&cli2
, 1)) {
4919 cli_setatr(cli2
, fname
, 0, 0);
4920 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4922 cli_sockopt(cli2
, sockops
);
4924 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4925 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
4926 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4927 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4928 if (!NT_STATUS_IS_OK(status
)) {
4929 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4933 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
4934 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4935 FILE_OPEN_IF
, 0, 0, &fnum2
);
4936 if (!NT_STATUS_IS_OK(status
)) {
4937 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4941 status
= cli_close(cli1
, fnum1
);
4942 if (!NT_STATUS_IS_OK(status
)) {
4943 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4947 status
= cli_close(cli2
, fnum2
);
4948 if (!NT_STATUS_IS_OK(status
)) {
4949 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4953 printf("non-io open test #1 passed.\n");
4955 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4957 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4959 status
= cli_ntcreate(cli1
, fname
, 0,
4960 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
4961 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4962 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4963 if (!NT_STATUS_IS_OK(status
)) {
4964 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4968 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
4969 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4970 FILE_OPEN_IF
, 0, 0, &fnum2
);
4971 if (!NT_STATUS_IS_OK(status
)) {
4972 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4976 status
= cli_close(cli1
, fnum1
);
4977 if (!NT_STATUS_IS_OK(status
)) {
4978 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4982 status
= cli_close(cli2
, fnum2
);
4983 if (!NT_STATUS_IS_OK(status
)) {
4984 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4988 printf("non-io open test #2 passed.\n");
4990 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4992 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4994 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
4995 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4996 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4997 if (!NT_STATUS_IS_OK(status
)) {
4998 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5002 status
= cli_ntcreate(cli2
, fname
, 0,
5003 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5004 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5005 FILE_OPEN_IF
, 0, 0, &fnum2
);
5006 if (!NT_STATUS_IS_OK(status
)) {
5007 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5011 status
= cli_close(cli1
, fnum1
);
5012 if (!NT_STATUS_IS_OK(status
)) {
5013 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5017 status
= cli_close(cli2
, fnum2
);
5018 if (!NT_STATUS_IS_OK(status
)) {
5019 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5023 printf("non-io open test #3 passed.\n");
5025 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5027 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5029 status
= cli_ntcreate(cli1
, fname
, 0,
5030 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5031 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5032 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5033 if (!NT_STATUS_IS_OK(status
)) {
5034 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5038 status
= cli_ntcreate(cli2
, fname
, 0,
5039 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5040 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5041 FILE_OPEN_IF
, 0, 0, &fnum2
);
5042 if (NT_STATUS_IS_OK(status
)) {
5043 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5047 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5049 status
= cli_close(cli1
, fnum1
);
5050 if (!NT_STATUS_IS_OK(status
)) {
5051 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5055 printf("non-io open test #4 passed.\n");
5057 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5059 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5061 status
= cli_ntcreate(cli1
, fname
, 0,
5062 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5063 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5064 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5065 if (!NT_STATUS_IS_OK(status
)) {
5066 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5070 status
= cli_ntcreate(cli2
, fname
, 0,
5071 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5072 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5073 FILE_OPEN_IF
, 0, 0, &fnum2
);
5074 if (!NT_STATUS_IS_OK(status
)) {
5075 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5079 status
= cli_close(cli1
, fnum1
);
5080 if (!NT_STATUS_IS_OK(status
)) {
5081 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5085 status
= cli_close(cli2
, fnum2
);
5086 if (!NT_STATUS_IS_OK(status
)) {
5087 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5091 printf("non-io open test #5 passed.\n");
5093 printf("TEST #6 testing 1 non-io open, one io open\n");
5095 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5097 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5098 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5099 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5100 if (!NT_STATUS_IS_OK(status
)) {
5101 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5105 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5106 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5107 FILE_OPEN_IF
, 0, 0, &fnum2
);
5108 if (!NT_STATUS_IS_OK(status
)) {
5109 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5113 status
= cli_close(cli1
, fnum1
);
5114 if (!NT_STATUS_IS_OK(status
)) {
5115 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5119 status
= cli_close(cli2
, fnum2
);
5120 if (!NT_STATUS_IS_OK(status
)) {
5121 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5125 printf("non-io open test #6 passed.\n");
5127 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5129 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5131 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5132 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5133 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5134 if (!NT_STATUS_IS_OK(status
)) {
5135 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5139 status
= cli_ntcreate(cli2
, fname
, 0,
5140 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5141 FILE_ATTRIBUTE_NORMAL
,
5142 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5143 FILE_OPEN_IF
, 0, 0, &fnum2
);
5144 if (NT_STATUS_IS_OK(status
)) {
5145 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5149 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5151 status
= cli_close(cli1
, fnum1
);
5152 if (!NT_STATUS_IS_OK(status
)) {
5153 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5157 printf("non-io open test #7 passed.\n");
5159 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5161 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5162 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5163 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5164 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5165 if (!NT_STATUS_IS_OK(status
)) {
5166 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5171 /* Write to ensure we have to update the file time. */
5172 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5174 if (!NT_STATUS_IS_OK(status
)) {
5175 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5180 status
= cli_close(cli1
, fnum1
);
5181 if (!NT_STATUS_IS_OK(status
)) {
5182 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5188 if (!torture_close_connection(cli1
)) {
5191 if (!torture_close_connection(cli2
)) {
5198 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5200 uint16 major
, minor
;
5201 uint32 caplow
, caphigh
;
5204 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5205 printf("Server doesn't support UNIX CIFS extensions.\n");
5206 return NT_STATUS_NOT_SUPPORTED
;
5209 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5211 if (!NT_STATUS_IS_OK(status
)) {
5212 printf("Server didn't return UNIX CIFS extensions: %s\n",
5217 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5219 if (!NT_STATUS_IS_OK(status
)) {
5220 printf("Server doesn't support setting UNIX CIFS extensions: "
5221 "%s.\n", nt_errstr(status
));
5225 return NT_STATUS_OK
;
5229 Test POSIX open /mkdir calls.
5231 static bool run_simple_posix_open_test(int dummy
)
5233 static struct cli_state
*cli1
;
5234 const char *fname
= "posix:file";
5235 const char *hname
= "posix:hlink";
5236 const char *sname
= "posix:symlink";
5237 const char *dname
= "posix:dir";
5240 uint16_t fnum1
= (uint16_t)-1;
5241 SMB_STRUCT_STAT sbuf
;
5242 bool correct
= false;
5245 printf("Starting simple POSIX open test\n");
5247 if (!torture_open_connection(&cli1
, 0)) {
5251 cli_sockopt(cli1
, sockops
);
5253 status
= torture_setup_unix_extensions(cli1
);
5254 if (!NT_STATUS_IS_OK(status
)) {
5258 cli_setatr(cli1
, fname
, 0, 0);
5259 cli_posix_unlink(cli1
, fname
);
5260 cli_setatr(cli1
, dname
, 0, 0);
5261 cli_posix_rmdir(cli1
, dname
);
5262 cli_setatr(cli1
, hname
, 0, 0);
5263 cli_posix_unlink(cli1
, hname
);
5264 cli_setatr(cli1
, sname
, 0, 0);
5265 cli_posix_unlink(cli1
, sname
);
5267 /* Create a directory. */
5268 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5269 if (!NT_STATUS_IS_OK(status
)) {
5270 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5274 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5276 if (!NT_STATUS_IS_OK(status
)) {
5277 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5281 /* Test ftruncate - set file size. */
5282 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5283 if (!NT_STATUS_IS_OK(status
)) {
5284 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5288 /* Ensure st_size == 1000 */
5289 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5290 if (!NT_STATUS_IS_OK(status
)) {
5291 printf("stat failed (%s)\n", nt_errstr(status
));
5295 if (sbuf
.st_ex_size
!= 1000) {
5296 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5300 /* Test ftruncate - set file size back to zero. */
5301 status
= cli_ftruncate(cli1
, fnum1
, 0);
5302 if (!NT_STATUS_IS_OK(status
)) {
5303 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5307 status
= cli_close(cli1
, fnum1
);
5308 if (!NT_STATUS_IS_OK(status
)) {
5309 printf("close failed (%s)\n", nt_errstr(status
));
5313 /* Now open the file again for read only. */
5314 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5315 if (!NT_STATUS_IS_OK(status
)) {
5316 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5320 /* Now unlink while open. */
5321 status
= cli_posix_unlink(cli1
, fname
);
5322 if (!NT_STATUS_IS_OK(status
)) {
5323 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5327 status
= cli_close(cli1
, fnum1
);
5328 if (!NT_STATUS_IS_OK(status
)) {
5329 printf("close(2) failed (%s)\n", nt_errstr(status
));
5333 /* Ensure the file has gone. */
5334 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5335 if (NT_STATUS_IS_OK(status
)) {
5336 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5340 /* Create again to test open with O_TRUNC. */
5341 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5342 if (!NT_STATUS_IS_OK(status
)) {
5343 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5347 /* Test ftruncate - set file size. */
5348 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5349 if (!NT_STATUS_IS_OK(status
)) {
5350 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5354 /* Ensure st_size == 1000 */
5355 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5356 if (!NT_STATUS_IS_OK(status
)) {
5357 printf("stat failed (%s)\n", nt_errstr(status
));
5361 if (sbuf
.st_ex_size
!= 1000) {
5362 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5366 status
= cli_close(cli1
, fnum1
);
5367 if (!NT_STATUS_IS_OK(status
)) {
5368 printf("close(2) failed (%s)\n", nt_errstr(status
));
5372 /* Re-open with O_TRUNC. */
5373 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5374 if (!NT_STATUS_IS_OK(status
)) {
5375 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5379 /* Ensure st_size == 0 */
5380 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5381 if (!NT_STATUS_IS_OK(status
)) {
5382 printf("stat failed (%s)\n", nt_errstr(status
));
5386 if (sbuf
.st_ex_size
!= 0) {
5387 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5391 status
= cli_close(cli1
, fnum1
);
5392 if (!NT_STATUS_IS_OK(status
)) {
5393 printf("close failed (%s)\n", nt_errstr(status
));
5397 status
= cli_posix_unlink(cli1
, fname
);
5398 if (!NT_STATUS_IS_OK(status
)) {
5399 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5403 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5404 if (!NT_STATUS_IS_OK(status
)) {
5405 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5406 dname
, nt_errstr(status
));
5410 cli_close(cli1
, fnum1
);
5412 /* What happens when we try and POSIX open a directory for write ? */
5413 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5414 if (NT_STATUS_IS_OK(status
)) {
5415 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5418 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5419 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5424 /* Create the file. */
5425 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5427 if (!NT_STATUS_IS_OK(status
)) {
5428 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5432 /* Write some data into it. */
5433 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5435 if (!NT_STATUS_IS_OK(status
)) {
5436 printf("cli_write failed: %s\n", nt_errstr(status
));
5440 cli_close(cli1
, fnum1
);
5442 /* Now create a hardlink. */
5443 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5444 if (!NT_STATUS_IS_OK(status
)) {
5445 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5449 /* Now create a symlink. */
5450 status
= cli_posix_symlink(cli1
, fname
, sname
);
5451 if (!NT_STATUS_IS_OK(status
)) {
5452 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5456 /* Open the hardlink for read. */
5457 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5458 if (!NT_STATUS_IS_OK(status
)) {
5459 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5463 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
5464 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
5468 if (memcmp(buf
, "TEST DATA\n", 10)) {
5469 printf("invalid data read from hardlink\n");
5473 /* Do a POSIX lock/unlock. */
5474 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5475 if (!NT_STATUS_IS_OK(status
)) {
5476 printf("POSIX lock failed %s\n", nt_errstr(status
));
5480 /* Punch a hole in the locked area. */
5481 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5482 if (!NT_STATUS_IS_OK(status
)) {
5483 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5487 cli_close(cli1
, fnum1
);
5489 /* Open the symlink for read - this should fail. A POSIX
5490 client should not be doing opens on a symlink. */
5491 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5492 if (NT_STATUS_IS_OK(status
)) {
5493 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5496 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5497 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5498 printf("POSIX open of %s should have failed "
5499 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5500 "failed with %s instead.\n",
5501 sname
, nt_errstr(status
));
5506 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5507 if (!NT_STATUS_IS_OK(status
)) {
5508 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5512 if (strcmp(namebuf
, fname
) != 0) {
5513 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5514 sname
, fname
, namebuf
);
5518 status
= cli_posix_rmdir(cli1
, dname
);
5519 if (!NT_STATUS_IS_OK(status
)) {
5520 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5524 printf("Simple POSIX open test passed\n");
5529 if (fnum1
!= (uint16_t)-1) {
5530 cli_close(cli1
, fnum1
);
5531 fnum1
= (uint16_t)-1;
5534 cli_setatr(cli1
, sname
, 0, 0);
5535 cli_posix_unlink(cli1
, sname
);
5536 cli_setatr(cli1
, hname
, 0, 0);
5537 cli_posix_unlink(cli1
, hname
);
5538 cli_setatr(cli1
, fname
, 0, 0);
5539 cli_posix_unlink(cli1
, fname
);
5540 cli_setatr(cli1
, dname
, 0, 0);
5541 cli_posix_rmdir(cli1
, dname
);
5543 if (!torture_close_connection(cli1
)) {
5551 static uint32 open_attrs_table
[] = {
5552 FILE_ATTRIBUTE_NORMAL
,
5553 FILE_ATTRIBUTE_ARCHIVE
,
5554 FILE_ATTRIBUTE_READONLY
,
5555 FILE_ATTRIBUTE_HIDDEN
,
5556 FILE_ATTRIBUTE_SYSTEM
,
5558 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5559 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5560 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5561 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5562 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5563 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5565 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5566 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5567 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5568 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5571 struct trunc_open_results
{
5578 static struct trunc_open_results attr_results
[] = {
5579 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5580 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5581 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5582 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5583 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5584 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5585 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5586 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5587 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5588 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5589 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5590 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5591 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5592 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5593 { 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
},
5594 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5595 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5596 { 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
},
5597 { 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
},
5598 { 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
},
5599 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5600 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5601 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5602 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5603 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5604 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5607 static bool run_openattrtest(int dummy
)
5609 static struct cli_state
*cli1
;
5610 const char *fname
= "\\openattr.file";
5612 bool correct
= True
;
5614 unsigned int i
, j
, k
, l
;
5617 printf("starting open attr test\n");
5619 if (!torture_open_connection(&cli1
, 0)) {
5623 cli_sockopt(cli1
, sockops
);
5625 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5626 cli_setatr(cli1
, fname
, 0, 0);
5627 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5629 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5630 open_attrs_table
[i
], FILE_SHARE_NONE
,
5631 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5632 if (!NT_STATUS_IS_OK(status
)) {
5633 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5637 status
= cli_close(cli1
, fnum1
);
5638 if (!NT_STATUS_IS_OK(status
)) {
5639 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5643 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5644 status
= cli_ntcreate(cli1
, fname
, 0,
5645 FILE_READ_DATA
|FILE_WRITE_DATA
,
5646 open_attrs_table
[j
],
5647 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5649 if (!NT_STATUS_IS_OK(status
)) {
5650 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5651 if (attr_results
[l
].num
== k
) {
5652 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5653 k
, open_attrs_table
[i
],
5654 open_attrs_table
[j
],
5655 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5660 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5661 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5662 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5667 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5673 status
= cli_close(cli1
, fnum1
);
5674 if (!NT_STATUS_IS_OK(status
)) {
5675 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5679 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5680 if (!NT_STATUS_IS_OK(status
)) {
5681 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5686 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5687 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5690 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5691 if (attr_results
[l
].num
== k
) {
5692 if (attr
!= attr_results
[l
].result_attr
||
5693 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5694 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5695 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5696 open_attrs_table
[i
],
5697 open_attrs_table
[j
],
5699 attr_results
[l
].result_attr
);
5709 cli_setatr(cli1
, fname
, 0, 0);
5710 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5712 printf("open attr test %s.\n", correct
? "passed" : "failed");
5714 if (!torture_close_connection(cli1
)) {
5720 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5721 const char *name
, void *state
)
5723 int *matched
= (int *)state
;
5724 if (matched
!= NULL
) {
5727 return NT_STATUS_OK
;
5731 test directory listing speed
5733 static bool run_dirtest(int dummy
)
5736 static struct cli_state
*cli
;
5738 struct timeval core_start
;
5739 bool correct
= True
;
5742 printf("starting directory test\n");
5744 if (!torture_open_connection(&cli
, 0)) {
5748 cli_sockopt(cli
, sockops
);
5751 for (i
=0;i
<torture_numops
;i
++) {
5753 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5754 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5755 fprintf(stderr
,"Failed to open %s\n", fname
);
5758 cli_close(cli
, fnum
);
5761 core_start
= timeval_current();
5764 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5765 printf("Matched %d\n", matched
);
5768 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5769 printf("Matched %d\n", matched
);
5772 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5773 printf("Matched %d\n", matched
);
5775 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5778 for (i
=0;i
<torture_numops
;i
++) {
5780 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5781 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5784 if (!torture_close_connection(cli
)) {
5788 printf("finished dirtest\n");
5793 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5796 struct cli_state
*pcli
= (struct cli_state
*)state
;
5798 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5800 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5801 return NT_STATUS_OK
;
5803 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
5804 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5805 printf("del_fn: failed to rmdir %s\n,", fname
);
5807 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
5808 printf("del_fn: failed to unlink %s\n,", fname
);
5810 return NT_STATUS_OK
;
5815 sees what IOCTLs are supported
5817 bool torture_ioctl_test(int dummy
)
5819 static struct cli_state
*cli
;
5820 uint16_t device
, function
;
5822 const char *fname
= "\\ioctl.dat";
5826 if (!torture_open_connection(&cli
, 0)) {
5830 printf("starting ioctl test\n");
5832 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5834 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5835 if (!NT_STATUS_IS_OK(status
)) {
5836 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5840 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5841 printf("ioctl device info: %s\n", nt_errstr(status
));
5843 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5844 printf("ioctl job info: %s\n", nt_errstr(status
));
5846 for (device
=0;device
<0x100;device
++) {
5847 printf("ioctl test with device = 0x%x\n", device
);
5848 for (function
=0;function
<0x100;function
++) {
5849 uint32 code
= (device
<<16) | function
;
5851 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5853 if (NT_STATUS_IS_OK(status
)) {
5854 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5856 data_blob_free(&blob
);
5861 if (!torture_close_connection(cli
)) {
5870 tries varients of chkpath
5872 bool torture_chkpath_test(int dummy
)
5874 static struct cli_state
*cli
;
5879 if (!torture_open_connection(&cli
, 0)) {
5883 printf("starting chkpath test\n");
5885 /* cleanup from an old run */
5886 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5887 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5888 cli_rmdir(cli
, "\\chkpath.dir");
5890 status
= cli_mkdir(cli
, "\\chkpath.dir");
5891 if (!NT_STATUS_IS_OK(status
)) {
5892 printf("mkdir1 failed : %s\n", nt_errstr(status
));
5896 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
5897 if (!NT_STATUS_IS_OK(status
)) {
5898 printf("mkdir2 failed : %s\n", nt_errstr(status
));
5902 status
= cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
5904 if (!NT_STATUS_IS_OK(status
)) {
5905 printf("open1 failed (%s)\n", nt_errstr(status
));
5908 cli_close(cli
, fnum
);
5910 status
= cli_chkpath(cli
, "\\chkpath.dir");
5911 if (!NT_STATUS_IS_OK(status
)) {
5912 printf("chkpath1 failed: %s\n", nt_errstr(status
));
5916 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
5917 if (!NT_STATUS_IS_OK(status
)) {
5918 printf("chkpath2 failed: %s\n", nt_errstr(status
));
5922 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
5923 if (!NT_STATUS_IS_OK(status
)) {
5924 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5925 NT_STATUS_NOT_A_DIRECTORY
);
5927 printf("* chkpath on a file should fail\n");
5931 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
5932 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
5933 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
5935 printf("* chkpath on a non existant file should fail\n");
5939 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5940 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
5941 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
5943 printf("* chkpath on a non existent component should fail\n");
5947 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5948 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5949 cli_rmdir(cli
, "\\chkpath.dir");
5951 if (!torture_close_connection(cli
)) {
5958 static bool run_eatest(int dummy
)
5960 static struct cli_state
*cli
;
5961 const char *fname
= "\\eatest.txt";
5962 bool correct
= True
;
5966 struct ea_struct
*ea_list
= NULL
;
5967 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5970 printf("starting eatest\n");
5972 if (!torture_open_connection(&cli
, 0)) {
5973 talloc_destroy(mem_ctx
);
5977 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5979 status
= cli_ntcreate(cli
, fname
, 0,
5980 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5981 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5983 if (!NT_STATUS_IS_OK(status
)) {
5984 printf("open failed - %s\n", nt_errstr(status
));
5985 talloc_destroy(mem_ctx
);
5989 for (i
= 0; i
< 10; i
++) {
5990 fstring ea_name
, ea_val
;
5992 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5993 memset(ea_val
, (char)i
+1, i
+1);
5994 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
5995 if (!NT_STATUS_IS_OK(status
)) {
5996 printf("ea_set of name %s failed - %s\n", ea_name
,
5998 talloc_destroy(mem_ctx
);
6003 cli_close(cli
, fnum
);
6004 for (i
= 0; i
< 10; i
++) {
6005 fstring ea_name
, ea_val
;
6007 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6008 memset(ea_val
, (char)i
+1, i
+1);
6009 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6010 if (!NT_STATUS_IS_OK(status
)) {
6011 printf("ea_set of name %s failed - %s\n", ea_name
,
6013 talloc_destroy(mem_ctx
);
6018 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6019 if (!NT_STATUS_IS_OK(status
)) {
6020 printf("ea_get list failed - %s\n", nt_errstr(status
));
6024 printf("num_eas = %d\n", (int)num_eas
);
6026 if (num_eas
!= 20) {
6027 printf("Should be 20 EA's stored... failing.\n");
6031 for (i
= 0; i
< num_eas
; i
++) {
6032 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6033 dump_data(0, ea_list
[i
].value
.data
,
6034 ea_list
[i
].value
.length
);
6037 /* Setting EA's to zero length deletes them. Test this */
6038 printf("Now deleting all EA's - case indepenent....\n");
6041 cli_set_ea_path(cli
, fname
, "", "", 0);
6043 for (i
= 0; i
< 20; i
++) {
6045 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6046 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6047 if (!NT_STATUS_IS_OK(status
)) {
6048 printf("ea_set of name %s failed - %s\n", ea_name
,
6050 talloc_destroy(mem_ctx
);
6056 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6057 if (!NT_STATUS_IS_OK(status
)) {
6058 printf("ea_get list failed - %s\n", nt_errstr(status
));
6062 printf("num_eas = %d\n", (int)num_eas
);
6063 for (i
= 0; i
< num_eas
; i
++) {
6064 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6065 dump_data(0, ea_list
[i
].value
.data
,
6066 ea_list
[i
].value
.length
);
6070 printf("deleting EA's failed.\n");
6074 /* Try and delete a non existant EA. */
6075 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6076 if (!NT_STATUS_IS_OK(status
)) {
6077 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6082 talloc_destroy(mem_ctx
);
6083 if (!torture_close_connection(cli
)) {
6090 static bool run_dirtest1(int dummy
)
6093 static struct cli_state
*cli
;
6096 bool correct
= True
;
6098 printf("starting directory test\n");
6100 if (!torture_open_connection(&cli
, 0)) {
6104 cli_sockopt(cli
, sockops
);
6106 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6107 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6108 cli_rmdir(cli
, "\\LISTDIR");
6109 cli_mkdir(cli
, "\\LISTDIR");
6111 /* Create 1000 files and 1000 directories. */
6112 for (i
=0;i
<1000;i
++) {
6114 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6115 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6116 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6117 fprintf(stderr
,"Failed to open %s\n", fname
);
6120 cli_close(cli
, fnum
);
6122 for (i
=0;i
<1000;i
++) {
6124 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6125 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6126 fprintf(stderr
,"Failed to open %s\n", fname
);
6131 /* Now ensure that doing an old list sees both files and directories. */
6133 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6134 printf("num_seen = %d\n", num_seen
);
6135 /* We should see 100 files + 1000 directories + . and .. */
6136 if (num_seen
!= 2002)
6139 /* Ensure if we have the "must have" bits we only see the
6143 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6144 printf("num_seen = %d\n", num_seen
);
6145 if (num_seen
!= 1002)
6149 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6150 printf("num_seen = %d\n", num_seen
);
6151 if (num_seen
!= 1000)
6154 /* Delete everything. */
6155 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6156 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6157 cli_rmdir(cli
, "\\LISTDIR");
6160 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6161 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6162 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6165 if (!torture_close_connection(cli
)) {
6169 printf("finished dirtest1\n");
6174 static bool run_error_map_extract(int dummy
) {
6176 static struct cli_state
*c_dos
;
6177 static struct cli_state
*c_nt
;
6189 /* NT-Error connection */
6191 if (!(c_nt
= open_nbt_connection())) {
6195 c_nt
->use_spnego
= False
;
6197 status
= cli_negprot(c_nt
);
6199 if (!NT_STATUS_IS_OK(status
)) {
6200 printf("%s rejected the NT-error negprot (%s)\n", host
,
6206 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6207 if (!NT_STATUS_IS_OK(status
)) {
6208 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6212 /* DOS-Error connection */
6214 if (!(c_dos
= open_nbt_connection())) {
6218 c_dos
->use_spnego
= False
;
6219 c_dos
->force_dos_errors
= True
;
6221 status
= cli_negprot(c_dos
);
6222 if (!NT_STATUS_IS_OK(status
)) {
6223 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6225 cli_shutdown(c_dos
);
6229 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6230 if (!NT_STATUS_IS_OK(status
)) {
6231 printf("%s rejected the DOS-error initial session setup (%s)\n",
6232 host
, nt_errstr(status
));
6236 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6237 fstr_sprintf(user
, "%X", error
);
6239 status
= cli_session_setup(c_nt
, user
,
6240 password
, strlen(password
),
6241 password
, strlen(password
),
6243 if (NT_STATUS_IS_OK(status
)) {
6244 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6247 /* Case #1: 32-bit NT errors */
6248 if (cli_is_nt_error(c_nt
)) {
6249 nt_status
= cli_nt_error(c_nt
);
6251 printf("/** Dos error on NT connection! (%s) */\n",
6253 nt_status
= NT_STATUS(0xc0000000);
6256 status
= cli_session_setup(c_dos
, user
,
6257 password
, strlen(password
),
6258 password
, strlen(password
),
6260 if (NT_STATUS_IS_OK(status
)) {
6261 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6264 /* Case #1: 32-bit NT errors */
6265 if (!cli_is_dos_error(c_dos
)) {
6266 printf("/** NT error on DOS connection! (%s) */\n",
6268 errnum
= errclass
= 0;
6270 cli_dos_error(c_dos
, &errclass
, &errnum
);
6273 if (NT_STATUS_V(nt_status
) != error
) {
6274 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6275 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6276 get_nt_error_c_code(talloc_tos(), nt_status
));
6279 printf("\t{%s,\t%s,\t%s},\n",
6280 smb_dos_err_class(errclass
),
6281 smb_dos_err_name(errclass
, errnum
),
6282 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6287 static bool run_sesssetup_bench(int dummy
)
6289 static struct cli_state
*c
;
6290 const char *fname
= "\\file.dat";
6295 if (!torture_open_connection(&c
, 0)) {
6299 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6300 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6301 FILE_DELETE_ON_CLOSE
, 0, &fnum
);
6302 if (!NT_STATUS_IS_OK(status
)) {
6303 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6307 for (i
=0; i
<torture_numops
; i
++) {
6308 status
= cli_session_setup(
6310 password
, strlen(password
),
6311 password
, strlen(password
),
6313 if (!NT_STATUS_IS_OK(status
)) {
6314 d_printf("(%s) cli_session_setup failed: %s\n",
6315 __location__
, nt_errstr(status
));
6319 d_printf("\r%d ", (int)c
->vuid
);
6321 status
= cli_ulogoff(c
);
6322 if (!NT_STATUS_IS_OK(status
)) {
6323 d_printf("(%s) cli_ulogoff failed: %s\n",
6324 __location__
, nt_errstr(status
));
6333 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6334 uid_t uid
, gid_t gid
, const char *expected
)
6339 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
6341 if (strcmp(subst
, expected
) != 0) {
6342 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6343 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6352 static void chain1_open_completion(struct tevent_req
*req
)
6356 status
= cli_open_recv(req
, &fnum
);
6359 d_printf("cli_open_recv returned %s: %d\n",
6361 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6364 static void chain1_write_completion(struct tevent_req
*req
)
6368 status
= cli_write_andx_recv(req
, &written
);
6371 d_printf("cli_write_andx_recv returned %s: %d\n",
6373 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6376 static void chain1_close_completion(struct tevent_req
*req
)
6379 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6381 status
= cli_close_recv(req
);
6386 d_printf("cli_close returned %s\n", nt_errstr(status
));
6389 static bool run_chain1(int dummy
)
6391 struct cli_state
*cli1
;
6392 struct event_context
*evt
= event_context_init(NULL
);
6393 struct tevent_req
*reqs
[3], *smbreqs
[3];
6395 const char *str
= "foobar";
6398 printf("starting chain1 test\n");
6399 if (!torture_open_connection(&cli1
, 0)) {
6403 cli_sockopt(cli1
, sockops
);
6405 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
6406 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6407 if (reqs
[0] == NULL
) return false;
6408 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6411 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6412 (const uint8_t *)str
, 0, strlen(str
)+1,
6413 smbreqs
, 1, &smbreqs
[1]);
6414 if (reqs
[1] == NULL
) return false;
6415 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6417 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6418 if (reqs
[2] == NULL
) return false;
6419 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6421 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6422 if (!NT_STATUS_IS_OK(status
)) {
6427 event_loop_once(evt
);
6430 torture_close_connection(cli1
);
6434 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6437 status
= cli_session_setup_guest_recv(req
);
6438 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6441 static void chain2_tcon_completion(struct tevent_req
*req
)
6443 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6445 status
= cli_tcon_andx_recv(req
);
6446 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6450 static bool run_chain2(int dummy
)
6452 struct cli_state
*cli1
;
6453 struct event_context
*evt
= event_context_init(NULL
);
6454 struct tevent_req
*reqs
[2], *smbreqs
[2];
6458 printf("starting chain2 test\n");
6459 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6460 port_to_use
, Undefined
, 0);
6461 if (!NT_STATUS_IS_OK(status
)) {
6465 cli_sockopt(cli1
, sockops
);
6467 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6469 if (reqs
[0] == NULL
) return false;
6470 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6472 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6473 "?????", NULL
, 0, &smbreqs
[1]);
6474 if (reqs
[1] == NULL
) return false;
6475 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6477 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6478 if (!NT_STATUS_IS_OK(status
)) {
6483 event_loop_once(evt
);
6486 torture_close_connection(cli1
);
6491 struct torture_createdel_state
{
6492 struct tevent_context
*ev
;
6493 struct cli_state
*cli
;
6496 static void torture_createdel_created(struct tevent_req
*subreq
);
6497 static void torture_createdel_closed(struct tevent_req
*subreq
);
6499 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6500 struct tevent_context
*ev
,
6501 struct cli_state
*cli
,
6504 struct tevent_req
*req
, *subreq
;
6505 struct torture_createdel_state
*state
;
6507 req
= tevent_req_create(mem_ctx
, &state
,
6508 struct torture_createdel_state
);
6515 subreq
= cli_ntcreate_send(
6516 state
, ev
, cli
, name
, 0,
6517 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6518 FILE_ATTRIBUTE_NORMAL
,
6519 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6520 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6522 if (tevent_req_nomem(subreq
, req
)) {
6523 return tevent_req_post(req
, ev
);
6525 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6529 static void torture_createdel_created(struct tevent_req
*subreq
)
6531 struct tevent_req
*req
= tevent_req_callback_data(
6532 subreq
, struct tevent_req
);
6533 struct torture_createdel_state
*state
= tevent_req_data(
6534 req
, struct torture_createdel_state
);
6538 status
= cli_ntcreate_recv(subreq
, &fnum
);
6539 TALLOC_FREE(subreq
);
6540 if (!NT_STATUS_IS_OK(status
)) {
6541 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6542 nt_errstr(status
)));
6543 tevent_req_nterror(req
, status
);
6547 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6548 if (tevent_req_nomem(subreq
, req
)) {
6551 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6554 static void torture_createdel_closed(struct tevent_req
*subreq
)
6556 struct tevent_req
*req
= tevent_req_callback_data(
6557 subreq
, struct tevent_req
);
6560 status
= cli_close_recv(subreq
);
6561 if (!NT_STATUS_IS_OK(status
)) {
6562 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6563 tevent_req_nterror(req
, status
);
6566 tevent_req_done(req
);
6569 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6571 return tevent_req_simple_recv_ntstatus(req
);
6574 struct torture_createdels_state
{
6575 struct tevent_context
*ev
;
6576 struct cli_state
*cli
;
6577 const char *base_name
;
6581 struct tevent_req
**reqs
;
6584 static void torture_createdels_done(struct tevent_req
*subreq
);
6586 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6587 struct tevent_context
*ev
,
6588 struct cli_state
*cli
,
6589 const char *base_name
,
6593 struct tevent_req
*req
;
6594 struct torture_createdels_state
*state
;
6597 req
= tevent_req_create(mem_ctx
, &state
,
6598 struct torture_createdels_state
);
6604 state
->base_name
= talloc_strdup(state
, base_name
);
6605 if (tevent_req_nomem(state
->base_name
, req
)) {
6606 return tevent_req_post(req
, ev
);
6608 state
->num_files
= MAX(num_parallel
, num_files
);
6610 state
->received
= 0;
6612 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6613 if (tevent_req_nomem(state
->reqs
, req
)) {
6614 return tevent_req_post(req
, ev
);
6617 for (i
=0; i
<num_parallel
; i
++) {
6620 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6622 if (tevent_req_nomem(name
, req
)) {
6623 return tevent_req_post(req
, ev
);
6625 state
->reqs
[i
] = torture_createdel_send(
6626 state
->reqs
, state
->ev
, state
->cli
, name
);
6627 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6628 return tevent_req_post(req
, ev
);
6630 name
= talloc_move(state
->reqs
[i
], &name
);
6631 tevent_req_set_callback(state
->reqs
[i
],
6632 torture_createdels_done
, req
);
6638 static void torture_createdels_done(struct tevent_req
*subreq
)
6640 struct tevent_req
*req
= tevent_req_callback_data(
6641 subreq
, struct tevent_req
);
6642 struct torture_createdels_state
*state
= tevent_req_data(
6643 req
, struct torture_createdels_state
);
6644 size_t num_parallel
= talloc_array_length(state
->reqs
);
6649 status
= torture_createdel_recv(subreq
);
6650 if (!NT_STATUS_IS_OK(status
)){
6651 DEBUG(10, ("torture_createdel_recv returned %s\n",
6652 nt_errstr(status
)));
6653 TALLOC_FREE(subreq
);
6654 tevent_req_nterror(req
, status
);
6658 for (i
=0; i
<num_parallel
; i
++) {
6659 if (subreq
== state
->reqs
[i
]) {
6663 if (i
== num_parallel
) {
6664 DEBUG(10, ("received something we did not send\n"));
6665 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6668 TALLOC_FREE(state
->reqs
[i
]);
6670 if (state
->sent
>= state
->num_files
) {
6671 tevent_req_done(req
);
6675 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6677 if (tevent_req_nomem(name
, req
)) {
6680 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6682 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6685 name
= talloc_move(state
->reqs
[i
], &name
);
6686 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6690 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6692 return tevent_req_simple_recv_ntstatus(req
);
6695 struct swallow_notify_state
{
6696 struct tevent_context
*ev
;
6697 struct cli_state
*cli
;
6699 uint32_t completion_filter
;
6701 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6705 static void swallow_notify_done(struct tevent_req
*subreq
);
6707 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6708 struct tevent_context
*ev
,
6709 struct cli_state
*cli
,
6711 uint32_t completion_filter
,
6713 bool (*fn
)(uint32_t action
,
6718 struct tevent_req
*req
, *subreq
;
6719 struct swallow_notify_state
*state
;
6721 req
= tevent_req_create(mem_ctx
, &state
,
6722 struct swallow_notify_state
);
6729 state
->completion_filter
= completion_filter
;
6730 state
->recursive
= recursive
;
6734 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6735 0xffff, state
->completion_filter
,
6737 if (tevent_req_nomem(subreq
, req
)) {
6738 return tevent_req_post(req
, ev
);
6740 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6744 static void swallow_notify_done(struct tevent_req
*subreq
)
6746 struct tevent_req
*req
= tevent_req_callback_data(
6747 subreq
, struct tevent_req
);
6748 struct swallow_notify_state
*state
= tevent_req_data(
6749 req
, struct swallow_notify_state
);
6751 uint32_t i
, num_changes
;
6752 struct notify_change
*changes
;
6754 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6755 TALLOC_FREE(subreq
);
6756 if (!NT_STATUS_IS_OK(status
)) {
6757 DEBUG(10, ("cli_notify_recv returned %s\n",
6758 nt_errstr(status
)));
6759 tevent_req_nterror(req
, status
);
6763 for (i
=0; i
<num_changes
; i
++) {
6764 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6766 TALLOC_FREE(changes
);
6768 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6769 0xffff, state
->completion_filter
,
6771 if (tevent_req_nomem(subreq
, req
)) {
6774 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6777 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6779 if (DEBUGLEVEL
> 5) {
6780 d_printf("%d %s\n", (int)action
, name
);
6785 static void notify_bench_done(struct tevent_req
*req
)
6787 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6791 static bool run_notify_bench(int dummy
)
6793 const char *dname
= "\\notify-bench";
6794 struct tevent_context
*ev
;
6797 struct tevent_req
*req1
;
6798 struct tevent_req
*req2
= NULL
;
6799 int i
, num_unc_names
;
6800 int num_finished
= 0;
6802 printf("starting notify-bench test\n");
6804 if (use_multishare_conn
) {
6806 unc_list
= file_lines_load(multishare_conn_fname
,
6807 &num_unc_names
, 0, NULL
);
6808 if (!unc_list
|| num_unc_names
<= 0) {
6809 d_printf("Failed to load unc names list from '%s'\n",
6810 multishare_conn_fname
);
6813 TALLOC_FREE(unc_list
);
6818 ev
= tevent_context_init(talloc_tos());
6820 d_printf("tevent_context_init failed\n");
6824 for (i
=0; i
<num_unc_names
; i
++) {
6825 struct cli_state
*cli
;
6828 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6830 if (base_fname
== NULL
) {
6834 if (!torture_open_connection(&cli
, i
)) {
6838 status
= cli_ntcreate(cli
, dname
, 0,
6839 MAXIMUM_ALLOWED_ACCESS
,
6840 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6842 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6845 if (!NT_STATUS_IS_OK(status
)) {
6846 d_printf("Could not create %s: %s\n", dname
,
6851 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6852 FILE_NOTIFY_CHANGE_FILE_NAME
|
6853 FILE_NOTIFY_CHANGE_DIR_NAME
|
6854 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6855 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6856 false, print_notifies
, NULL
);
6858 d_printf("Could not create notify request\n");
6862 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6863 base_fname
, 10, torture_numops
);
6865 d_printf("Could not create createdels request\n");
6868 TALLOC_FREE(base_fname
);
6870 tevent_req_set_callback(req2
, notify_bench_done
,
6874 while (num_finished
< num_unc_names
) {
6876 ret
= tevent_loop_once(ev
);
6878 d_printf("tevent_loop_once failed\n");
6883 if (!tevent_req_poll(req2
, ev
)) {
6884 d_printf("tevent_req_poll failed\n");
6887 status
= torture_createdels_recv(req2
);
6888 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
6893 static bool run_mangle1(int dummy
)
6895 struct cli_state
*cli
;
6896 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
6900 time_t change_time
, access_time
, write_time
;
6904 printf("starting mangle1 test\n");
6905 if (!torture_open_connection(&cli
, 0)) {
6909 cli_sockopt(cli
, sockops
);
6911 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6912 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6914 if (!NT_STATUS_IS_OK(status
)) {
6915 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6918 cli_close(cli
, fnum
);
6920 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
6921 if (!NT_STATUS_IS_OK(status
)) {
6922 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6926 d_printf("alt_name: %s\n", alt_name
);
6928 status
= cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
6929 if (!NT_STATUS_IS_OK(status
)) {
6930 d_printf("cli_open(%s) failed: %s\n", alt_name
,
6934 cli_close(cli
, fnum
);
6936 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
6937 &write_time
, &size
, &mode
);
6938 if (!NT_STATUS_IS_OK(status
)) {
6939 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
6947 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
6949 size_t *to_pull
= (size_t *)priv
;
6950 size_t thistime
= *to_pull
;
6952 thistime
= MIN(thistime
, n
);
6953 if (thistime
== 0) {
6957 memset(buf
, 0, thistime
);
6958 *to_pull
-= thistime
;
6962 static bool run_windows_write(int dummy
)
6964 struct cli_state
*cli1
;
6968 const char *fname
= "\\writetest.txt";
6969 struct timeval start_time
;
6974 printf("starting windows_write test\n");
6975 if (!torture_open_connection(&cli1
, 0)) {
6979 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6980 if (!NT_STATUS_IS_OK(status
)) {
6981 printf("open failed (%s)\n", nt_errstr(status
));
6985 cli_sockopt(cli1
, sockops
);
6987 start_time
= timeval_current();
6989 for (i
=0; i
<torture_numops
; i
++) {
6991 off_t start
= i
* torture_blocksize
;
6992 size_t to_pull
= torture_blocksize
- 1;
6994 status
= cli_writeall(cli1
, fnum
, 0, &c
,
6995 start
+ torture_blocksize
- 1, 1, NULL
);
6996 if (!NT_STATUS_IS_OK(status
)) {
6997 printf("cli_write failed: %s\n", nt_errstr(status
));
7001 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7002 null_source
, &to_pull
);
7003 if (!NT_STATUS_IS_OK(status
)) {
7004 printf("cli_push returned: %s\n", nt_errstr(status
));
7009 seconds
= timeval_elapsed(&start_time
);
7010 kbytes
= (double)torture_blocksize
* torture_numops
;
7013 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7014 (double)seconds
, (int)(kbytes
/seconds
));
7018 cli_close(cli1
, fnum
);
7019 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7020 torture_close_connection(cli1
);
7024 static bool run_cli_echo(int dummy
)
7026 struct cli_state
*cli
;
7029 printf("starting cli_echo test\n");
7030 if (!torture_open_connection(&cli
, 0)) {
7033 cli_sockopt(cli
, sockops
);
7035 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7037 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7039 torture_close_connection(cli
);
7040 return NT_STATUS_IS_OK(status
);
7043 static bool run_uid_regression_test(int dummy
)
7045 static struct cli_state
*cli
;
7048 bool correct
= True
;
7051 printf("starting uid regression test\n");
7053 if (!torture_open_connection(&cli
, 0)) {
7057 cli_sockopt(cli
, sockops
);
7059 /* Ok - now save then logoff our current user. */
7060 old_vuid
= cli
->vuid
;
7062 status
= cli_ulogoff(cli
);
7063 if (!NT_STATUS_IS_OK(status
)) {
7064 d_printf("(%s) cli_ulogoff failed: %s\n",
7065 __location__
, nt_errstr(status
));
7070 cli
->vuid
= old_vuid
;
7072 /* Try an operation. */
7073 status
= cli_mkdir(cli
, "\\uid_reg_test");
7074 if (NT_STATUS_IS_OK(status
)) {
7075 d_printf("(%s) cli_mkdir succeeded\n",
7080 /* Should be bad uid. */
7081 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
7082 NT_STATUS_USER_SESSION_DELETED
)) {
7088 old_cnum
= cli
->cnum
;
7090 /* Now try a SMBtdis with the invald vuid set to zero. */
7093 /* This should succeed. */
7094 status
= cli_tdis(cli
);
7096 if (NT_STATUS_IS_OK(status
)) {
7097 d_printf("First tdis with invalid vuid should succeed.\n");
7099 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7104 cli
->vuid
= old_vuid
;
7105 cli
->cnum
= old_cnum
;
7107 /* This should fail. */
7108 status
= cli_tdis(cli
);
7109 if (NT_STATUS_IS_OK(status
)) {
7110 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7114 /* Should be bad tid. */
7115 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
7116 NT_STATUS_NETWORK_NAME_DELETED
)) {
7122 cli_rmdir(cli
, "\\uid_reg_test");
7131 static const char *illegal_chars
= "*\\/?<>|\":";
7132 static char force_shortname_chars
[] = " +,.[];=\177";
7134 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7135 const char *mask
, void *state
)
7137 struct cli_state
*pcli
= (struct cli_state
*)state
;
7139 NTSTATUS status
= NT_STATUS_OK
;
7141 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7143 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7144 return NT_STATUS_OK
;
7146 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7147 status
= cli_rmdir(pcli
, fname
);
7148 if (!NT_STATUS_IS_OK(status
)) {
7149 printf("del_fn: failed to rmdir %s\n,", fname
);
7152 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7153 if (!NT_STATUS_IS_OK(status
)) {
7154 printf("del_fn: failed to unlink %s\n,", fname
);
7166 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7167 const char *name
, void *state
)
7169 struct sn_state
*s
= (struct sn_state
*)state
;
7173 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7174 i
, finfo
->name
, finfo
->short_name
);
7177 if (strchr(force_shortname_chars
, i
)) {
7178 if (!finfo
->short_name
) {
7179 /* Shortname not created when it should be. */
7180 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7181 __location__
, finfo
->name
, i
);
7184 } else if (finfo
->short_name
){
7185 /* Shortname created when it should not be. */
7186 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7187 __location__
, finfo
->short_name
, finfo
->name
);
7191 return NT_STATUS_OK
;
7194 static bool run_shortname_test(int dummy
)
7196 static struct cli_state
*cli
;
7197 bool correct
= True
;
7203 printf("starting shortname test\n");
7205 if (!torture_open_connection(&cli
, 0)) {
7209 cli_sockopt(cli
, sockops
);
7211 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7212 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7213 cli_rmdir(cli
, "\\shortname");
7215 status
= cli_mkdir(cli
, "\\shortname");
7216 if (!NT_STATUS_IS_OK(status
)) {
7217 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7218 __location__
, nt_errstr(status
));
7223 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
7224 strlcat(fname
, "test .txt", sizeof(fname
));
7228 for (i
= 32; i
< 128; i
++) {
7229 uint16_t fnum
= (uint16_t)-1;
7233 if (strchr(illegal_chars
, i
)) {
7238 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7239 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
7240 if (!NT_STATUS_IS_OK(status
)) {
7241 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7242 __location__
, fname
, nt_errstr(status
));
7246 cli_close(cli
, fnum
);
7249 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7250 shortname_list_fn
, &s
);
7251 if (s
.matched
!= 1) {
7252 d_printf("(%s) failed to list %s: %s\n",
7253 __location__
, fname
, nt_errstr(status
));
7258 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7259 if (!NT_STATUS_IS_OK(status
)) {
7260 d_printf("(%s) failed to delete %s: %s\n",
7261 __location__
, fname
, nt_errstr(status
));
7274 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7275 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7276 cli_rmdir(cli
, "\\shortname");
7277 torture_close_connection(cli
);
7281 static void pagedsearch_cb(struct tevent_req
*req
)
7284 struct tldap_message
*msg
;
7287 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7288 if (rc
!= TLDAP_SUCCESS
) {
7289 d_printf("tldap_search_paged_recv failed: %s\n",
7290 tldap_err2string(rc
));
7293 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7297 if (!tldap_entry_dn(msg
, &dn
)) {
7298 d_printf("tldap_entry_dn failed\n");
7301 d_printf("%s\n", dn
);
7305 static bool run_tldap(int dummy
)
7307 struct tldap_context
*ld
;
7310 struct sockaddr_storage addr
;
7311 struct tevent_context
*ev
;
7312 struct tevent_req
*req
;
7316 if (!resolve_name(host
, &addr
, 0, false)) {
7317 d_printf("could not find host %s\n", host
);
7320 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7321 if (!NT_STATUS_IS_OK(status
)) {
7322 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7326 ld
= tldap_context_create(talloc_tos(), fd
);
7329 d_printf("tldap_context_create failed\n");
7333 rc
= tldap_fetch_rootdse(ld
);
7334 if (rc
!= TLDAP_SUCCESS
) {
7335 d_printf("tldap_fetch_rootdse failed: %s\n",
7336 tldap_errstr(talloc_tos(), ld
, rc
));
7340 basedn
= tldap_talloc_single_attribute(
7341 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7342 if (basedn
== NULL
) {
7343 d_printf("no defaultNamingContext\n");
7346 d_printf("defaultNamingContext: %s\n", basedn
);
7348 ev
= tevent_context_init(talloc_tos());
7350 d_printf("tevent_context_init failed\n");
7354 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7355 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7357 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7359 d_printf("tldap_search_paged_send failed\n");
7362 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7364 tevent_req_poll(req
, ev
);
7368 /* test search filters against rootDSE */
7369 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7370 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7372 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7373 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7374 talloc_tos(), NULL
, NULL
);
7375 if (rc
!= TLDAP_SUCCESS
) {
7376 d_printf("tldap_search with complex filter failed: %s\n",
7377 tldap_errstr(talloc_tos(), ld
, rc
));
7385 /* Torture test to ensure no regression of :
7386 https://bugzilla.samba.org/show_bug.cgi?id=7084
7389 static bool run_dir_createtime(int dummy
)
7391 struct cli_state
*cli
;
7392 const char *dname
= "\\testdir";
7393 const char *fname
= "\\testdir\\testfile";
7395 struct timespec create_time
;
7396 struct timespec create_time1
;
7400 if (!torture_open_connection(&cli
, 0)) {
7404 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7405 cli_rmdir(cli
, dname
);
7407 status
= cli_mkdir(cli
, dname
);
7408 if (!NT_STATUS_IS_OK(status
)) {
7409 printf("mkdir failed: %s\n", nt_errstr(status
));
7413 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7415 if (!NT_STATUS_IS_OK(status
)) {
7416 printf("cli_qpathinfo2 returned %s\n",
7421 /* Sleep 3 seconds, then create a file. */
7424 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7426 if (!NT_STATUS_IS_OK(status
)) {
7427 printf("cli_open failed: %s\n", nt_errstr(status
));
7431 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7433 if (!NT_STATUS_IS_OK(status
)) {
7434 printf("cli_qpathinfo2 (2) returned %s\n",
7439 if (timespec_compare(&create_time1
, &create_time
)) {
7440 printf("run_dir_createtime: create time was updated (error)\n");
7442 printf("run_dir_createtime: create time was not updated (correct)\n");
7448 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7449 cli_rmdir(cli
, dname
);
7450 if (!torture_close_connection(cli
)) {
7457 static bool run_streamerror(int dummy
)
7459 struct cli_state
*cli
;
7460 const char *dname
= "\\testdir";
7461 const char *streamname
=
7462 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7464 time_t change_time
, access_time
, write_time
;
7466 uint16_t mode
, fnum
;
7469 if (!torture_open_connection(&cli
, 0)) {
7473 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7474 cli_rmdir(cli
, dname
);
7476 status
= cli_mkdir(cli
, dname
);
7477 if (!NT_STATUS_IS_OK(status
)) {
7478 printf("mkdir failed: %s\n", nt_errstr(status
));
7482 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
7484 status
= cli_nt_error(cli
);
7486 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7487 printf("pathinfo returned %s, expected "
7488 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7493 status
= cli_ntcreate(cli
, streamname
, 0x16,
7494 FILE_READ_DATA
|FILE_READ_EA
|
7495 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7496 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7497 FILE_OPEN
, 0, 0, &fnum
);
7499 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7500 printf("ntcreate returned %s, expected "
7501 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7507 cli_rmdir(cli
, dname
);
7511 static bool run_local_substitute(int dummy
)
7515 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7516 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7517 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7518 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7519 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7520 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7521 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7522 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7524 /* Different captialization rules in sub_basic... */
7526 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7532 static bool run_local_base64(int dummy
)
7537 for (i
=1; i
<2000; i
++) {
7538 DATA_BLOB blob1
, blob2
;
7541 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7543 generate_random_buffer(blob1
.data
, blob1
.length
);
7545 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7547 d_fprintf(stderr
, "base64_encode_data_blob failed "
7548 "for %d bytes\n", i
);
7551 blob2
= base64_decode_data_blob(b64
);
7554 if (data_blob_cmp(&blob1
, &blob2
)) {
7555 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7559 TALLOC_FREE(blob1
.data
);
7560 data_blob_free(&blob2
);
7565 static bool run_local_gencache(int dummy
)
7571 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7572 d_printf("%s: gencache_set() failed\n", __location__
);
7576 if (!gencache_get("foo", NULL
, NULL
)) {
7577 d_printf("%s: gencache_get() failed\n", __location__
);
7581 if (!gencache_get("foo", &val
, &tm
)) {
7582 d_printf("%s: gencache_get() failed\n", __location__
);
7586 if (strcmp(val
, "bar") != 0) {
7587 d_printf("%s: gencache_get() returned %s, expected %s\n",
7588 __location__
, val
, "bar");
7595 if (!gencache_del("foo")) {
7596 d_printf("%s: gencache_del() failed\n", __location__
);
7599 if (gencache_del("foo")) {
7600 d_printf("%s: second gencache_del() succeeded\n",
7605 if (gencache_get("foo", &val
, &tm
)) {
7606 d_printf("%s: gencache_get() on deleted entry "
7607 "succeeded\n", __location__
);
7611 blob
= data_blob_string_const_null("bar");
7612 tm
= time(NULL
) + 60;
7614 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7615 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7619 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7620 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7624 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7625 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7626 __location__
, (const char *)blob
.data
, "bar");
7627 data_blob_free(&blob
);
7631 data_blob_free(&blob
);
7633 if (!gencache_del("foo")) {
7634 d_printf("%s: gencache_del() failed\n", __location__
);
7637 if (gencache_del("foo")) {
7638 d_printf("%s: second gencache_del() succeeded\n",
7643 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7644 d_printf("%s: gencache_get_data_blob() on deleted entry "
7645 "succeeded\n", __location__
);
7652 static bool rbt_testval(struct db_context
*db
, const char *key
,
7655 struct db_record
*rec
;
7656 TDB_DATA data
= string_tdb_data(value
);
7660 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7662 d_fprintf(stderr
, "fetch_locked failed\n");
7665 status
= rec
->store(rec
, data
, 0);
7666 if (!NT_STATUS_IS_OK(status
)) {
7667 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7672 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
7674 d_fprintf(stderr
, "second fetch_locked failed\n");
7677 if ((rec
->value
.dsize
!= data
.dsize
)
7678 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7679 d_fprintf(stderr
, "Got wrong data back\n");
7689 static bool run_local_rbtree(int dummy
)
7691 struct db_context
*db
;
7695 db
= db_open_rbt(NULL
);
7698 d_fprintf(stderr
, "db_open_rbt failed\n");
7702 for (i
=0; i
<1000; i
++) {
7705 if (asprintf(&key
, "key%ld", random()) == -1) {
7708 if (asprintf(&value
, "value%ld", random()) == -1) {
7713 if (!rbt_testval(db
, key
, value
)) {
7720 if (asprintf(&value
, "value%ld", random()) == -1) {
7725 if (!rbt_testval(db
, key
, value
)) {
7744 local test for character set functions
7746 This is a very simple test for the functionality in convert_string_error()
7748 static bool run_local_convert_string(int dummy
)
7750 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
7751 const char *test_strings
[2] = { "March", "M\303\244rz" };
7755 for (i
=0; i
<2; i
++) {
7756 const char *str
= test_strings
[i
];
7757 int len
= strlen(str
);
7758 size_t converted_size
;
7761 memset(dst
, 'X', sizeof(dst
));
7763 /* first try with real source length */
7764 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7769 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7773 if (converted_size
!= len
) {
7774 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7775 str
, len
, (int)converted_size
);
7779 if (strncmp(str
, dst
, converted_size
) != 0) {
7780 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7784 if (strlen(str
) != converted_size
) {
7785 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7786 (int)strlen(str
), (int)converted_size
);
7790 if (dst
[converted_size
] != 'X') {
7791 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7795 /* now with srclen==-1, this causes the nul to be
7797 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7802 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7806 if (converted_size
!= len
+1) {
7807 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7808 str
, len
, (int)converted_size
);
7812 if (strncmp(str
, dst
, converted_size
) != 0) {
7813 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7817 if (len
+1 != converted_size
) {
7818 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7819 len
+1, (int)converted_size
);
7823 if (dst
[converted_size
] != 'X') {
7824 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7831 TALLOC_FREE(tmp_ctx
);
7834 TALLOC_FREE(tmp_ctx
);
7839 struct talloc_dict_test
{
7843 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7845 int *count
= (int *)priv
;
7850 static bool run_local_talloc_dict(int dummy
)
7852 struct talloc_dict
*dict
;
7853 struct talloc_dict_test
*t
;
7856 dict
= talloc_dict_init(talloc_tos());
7861 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7868 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7873 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
7886 static bool run_local_string_to_sid(int dummy
) {
7889 if (string_to_sid(&sid
, "S--1-5-32-545")) {
7890 printf("allowing S--1-5-32-545\n");
7893 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
7894 printf("allowing S-1-5-32-+545\n");
7897 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")) {
7898 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7901 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
7902 printf("allowing S-1-5-32-545-abc\n");
7905 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
7906 printf("could not parse S-1-5-32-545\n");
7909 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
7910 printf("mis-parsed S-1-5-32-545 as %s\n",
7911 sid_string_tos(&sid
));
7917 static bool run_local_binary_to_sid(int dummy
) {
7918 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
7919 static const char good_binary_sid
[] = {
7920 0x1, /* revision number */
7922 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7923 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7940 static const char long_binary_sid
[] = {
7941 0x1, /* revision number */
7943 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7944 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7945 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7946 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7947 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7948 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7949 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7950 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7951 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7952 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7953 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7954 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7955 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7956 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7957 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7958 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7959 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7960 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7961 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7964 static const char long_binary_sid2
[] = {
7965 0x1, /* revision number */
7967 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7968 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7969 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7970 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7971 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7972 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7973 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7974 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7975 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7976 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7977 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7978 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7979 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7980 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7981 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7982 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7983 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7984 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7985 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7986 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7987 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7988 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7989 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7990 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7991 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7992 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7993 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7994 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7995 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7996 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7997 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7998 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7999 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8002 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8005 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8008 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8014 /* Split a path name into filename and stream name components. Canonicalise
8015 * such that an implicit $DATA token is always explicit.
8017 * The "specification" of this function can be found in the
8018 * run_local_stream_name() function in torture.c, I've tried those
8019 * combinations against a W2k3 server.
8022 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8023 char **pbase
, char **pstream
)
8026 char *stream
= NULL
;
8027 char *sname
; /* stream name */
8028 const char *stype
; /* stream type */
8030 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8032 sname
= strchr_m(fname
, ':');
8034 if (lp_posix_pathnames() || (sname
== NULL
)) {
8035 if (pbase
!= NULL
) {
8036 base
= talloc_strdup(mem_ctx
, fname
);
8037 NT_STATUS_HAVE_NO_MEMORY(base
);
8042 if (pbase
!= NULL
) {
8043 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8044 NT_STATUS_HAVE_NO_MEMORY(base
);
8049 stype
= strchr_m(sname
, ':');
8051 if (stype
== NULL
) {
8052 sname
= talloc_strdup(mem_ctx
, sname
);
8056 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8058 * If there is an explicit stream type, so far we only
8059 * allow $DATA. Is there anything else allowed? -- vl
8061 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8063 return NT_STATUS_OBJECT_NAME_INVALID
;
8065 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8069 if (sname
== NULL
) {
8071 return NT_STATUS_NO_MEMORY
;
8074 if (sname
[0] == '\0') {
8076 * no stream name, so no stream
8081 if (pstream
!= NULL
) {
8082 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8083 if (stream
== NULL
) {
8086 return NT_STATUS_NO_MEMORY
;
8089 * upper-case the type field
8091 strupper_m(strchr_m(stream
, ':')+1);
8095 if (pbase
!= NULL
) {
8098 if (pstream
!= NULL
) {
8101 return NT_STATUS_OK
;
8104 static bool test_stream_name(const char *fname
, const char *expected_base
,
8105 const char *expected_stream
,
8106 NTSTATUS expected_status
)
8110 char *stream
= NULL
;
8112 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8113 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8117 if (!NT_STATUS_IS_OK(status
)) {
8121 if (base
== NULL
) goto error
;
8123 if (strcmp(expected_base
, base
) != 0) goto error
;
8125 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8126 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8128 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8132 TALLOC_FREE(stream
);
8136 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8137 fname
, expected_base
? expected_base
: "<NULL>",
8138 expected_stream
? expected_stream
: "<NULL>",
8139 nt_errstr(expected_status
));
8140 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8141 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8144 TALLOC_FREE(stream
);
8148 static bool run_local_stream_name(int dummy
)
8152 ret
&= test_stream_name(
8153 "bla", "bla", NULL
, NT_STATUS_OK
);
8154 ret
&= test_stream_name(
8155 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8156 ret
&= test_stream_name(
8157 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8158 ret
&= test_stream_name(
8159 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8160 ret
&= test_stream_name(
8161 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8162 ret
&= test_stream_name(
8163 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8164 ret
&= test_stream_name(
8165 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8166 ret
&= test_stream_name(
8167 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8172 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8174 if (a
.length
!= b
.length
) {
8175 printf("a.length=%d != b.length=%d\n",
8176 (int)a
.length
, (int)b
.length
);
8179 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8180 printf("a.data and b.data differ\n");
8186 static bool run_local_memcache(int dummy
)
8188 struct memcache
*cache
;
8190 DATA_BLOB d1
, d2
, d3
;
8191 DATA_BLOB v1
, v2
, v3
;
8193 TALLOC_CTX
*mem_ctx
;
8195 size_t size1
, size2
;
8198 cache
= memcache_init(NULL
, 100);
8200 if (cache
== NULL
) {
8201 printf("memcache_init failed\n");
8205 d1
= data_blob_const("d1", 2);
8206 d2
= data_blob_const("d2", 2);
8207 d3
= data_blob_const("d3", 2);
8209 k1
= data_blob_const("d1", 2);
8210 k2
= data_blob_const("d2", 2);
8212 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8213 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8215 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8216 printf("could not find k1\n");
8219 if (!data_blob_equal(d1
, v1
)) {
8223 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8224 printf("could not find k2\n");
8227 if (!data_blob_equal(d2
, v2
)) {
8231 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8233 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8234 printf("could not find replaced k1\n");
8237 if (!data_blob_equal(d3
, v3
)) {
8241 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8243 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8244 printf("Did find k2, should have been purged\n");
8250 cache
= memcache_init(NULL
, 0);
8252 mem_ctx
= talloc_init("foo");
8254 str1
= talloc_strdup(mem_ctx
, "string1");
8255 str2
= talloc_strdup(mem_ctx
, "string2");
8257 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8258 data_blob_string_const("torture"), &str1
);
8259 size1
= talloc_total_size(cache
);
8261 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8262 data_blob_string_const("torture"), &str2
);
8263 size2
= talloc_total_size(cache
);
8265 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8267 if (size2
> size1
) {
8268 printf("memcache leaks memory!\n");
8278 static void wbclient_done(struct tevent_req
*req
)
8281 struct winbindd_response
*wb_resp
;
8282 int *i
= (int *)tevent_req_callback_data_void(req
);
8284 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8287 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8290 static bool run_local_wbclient(int dummy
)
8292 struct event_context
*ev
;
8293 struct wb_context
**wb_ctx
;
8294 struct winbindd_request wb_req
;
8295 bool result
= false;
8298 BlockSignals(True
, SIGPIPE
);
8300 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
8305 wb_ctx
= talloc_array(ev
, struct wb_context
*, nprocs
);
8306 if (wb_ctx
== NULL
) {
8310 ZERO_STRUCT(wb_req
);
8311 wb_req
.cmd
= WINBINDD_PING
;
8313 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
8315 for (i
=0; i
<nprocs
; i
++) {
8316 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8317 if (wb_ctx
[i
] == NULL
) {
8320 for (j
=0; j
<torture_numops
; j
++) {
8321 struct tevent_req
*req
;
8322 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8323 (j
% 2) == 0, &wb_req
);
8327 tevent_req_set_callback(req
, wbclient_done
, &i
);
8333 while (i
< nprocs
* torture_numops
) {
8334 event_loop_once(ev
);
8343 static void getaddrinfo_finished(struct tevent_req
*req
)
8345 char *name
= (char *)tevent_req_callback_data_void(req
);
8346 struct addrinfo
*ainfo
;
8349 res
= getaddrinfo_recv(req
, &ainfo
);
8351 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
8354 d_printf("gai(%s) succeeded\n", name
);
8355 freeaddrinfo(ainfo
);
8358 static bool run_getaddrinfo_send(int dummy
)
8360 TALLOC_CTX
*frame
= talloc_stackframe();
8361 struct fncall_context
*ctx
;
8362 struct tevent_context
*ev
;
8363 bool result
= false;
8364 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
8365 "www.slashdot.org", "heise.de" };
8366 struct tevent_req
*reqs
[4];
8369 ev
= event_context_init(frame
);
8374 ctx
= fncall_context_init(frame
, 4);
8376 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
8377 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
8379 if (reqs
[i
] == NULL
) {
8382 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
8383 discard_const_p(void, names
[i
]));
8386 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
8387 tevent_loop_once(ev
);
8396 static bool dbtrans_inc(struct db_context
*db
)
8398 struct db_record
*rec
;
8403 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8405 printf(__location__
"fetch_lock failed\n");
8409 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
8410 printf(__location__
"value.dsize = %d\n",
8411 (int)rec
->value
.dsize
);
8415 val
= (uint32_t *)rec
->value
.dptr
;
8418 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
8421 if (!NT_STATUS_IS_OK(status
)) {
8422 printf(__location__
"store failed: %s\n",
8433 static bool run_local_dbtrans(int dummy
)
8435 struct db_context
*db
;
8436 struct db_record
*rec
;
8441 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
8442 O_RDWR
|O_CREAT
, 0600);
8444 printf("Could not open transtest.db\n");
8448 res
= db
->transaction_start(db
);
8450 printf(__location__
"transaction_start failed\n");
8454 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8456 printf(__location__
"fetch_lock failed\n");
8460 if (rec
->value
.dptr
== NULL
) {
8462 status
= rec
->store(
8463 rec
, make_tdb_data((uint8_t *)&initial
,
8466 if (!NT_STATUS_IS_OK(status
)) {
8467 printf(__location__
"store returned %s\n",
8475 res
= db
->transaction_commit(db
);
8477 printf(__location__
"transaction_commit failed\n");
8485 res
= db
->transaction_start(db
);
8487 printf(__location__
"transaction_start failed\n");
8491 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
8492 printf(__location__
"dbwrap_fetch_uint32 failed\n");
8496 for (i
=0; i
<10; i
++) {
8497 if (!dbtrans_inc(db
)) {
8502 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
8503 printf(__location__
"dbwrap_fetch_uint32 failed\n");
8507 if (val2
!= val
+ 10) {
8508 printf(__location__
"val=%d, val2=%d\n",
8509 (int)val
, (int)val2
);
8513 printf("val2=%d\r", val2
);
8515 res
= db
->transaction_commit(db
);
8517 printf(__location__
"transaction_commit failed\n");
8527 * Just a dummy test to be run under a debugger. There's no real way
8528 * to inspect the tevent_select specific function from outside of
8532 static bool run_local_tevent_select(int dummy
)
8534 struct tevent_context
*ev
;
8535 struct tevent_fd
*fd1
, *fd2
;
8536 bool result
= false;
8538 ev
= tevent_context_init_byname(NULL
, "select");
8540 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8544 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8546 d_fprintf(stderr
, "tevent_add_fd failed\n");
8549 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8551 d_fprintf(stderr
, "tevent_add_fd failed\n");
8556 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8558 d_fprintf(stderr
, "tevent_add_fd failed\n");
8568 static double create_procs(bool (*fn
)(int), bool *result
)
8571 volatile pid_t
*child_status
;
8572 volatile bool *child_status_out
;
8575 struct timeval start
;
8579 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
8580 if (!child_status
) {
8581 printf("Failed to setup shared memory\n");
8585 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
8586 if (!child_status_out
) {
8587 printf("Failed to setup result status shared memory\n");
8591 for (i
= 0; i
< nprocs
; i
++) {
8592 child_status
[i
] = 0;
8593 child_status_out
[i
] = True
;
8596 start
= timeval_current();
8598 for (i
=0;i
<nprocs
;i
++) {
8601 pid_t mypid
= getpid();
8602 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8604 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8607 if (torture_open_connection(¤t_cli
, i
)) break;
8609 printf("pid %d failed to start\n", (int)getpid());
8615 child_status
[i
] = getpid();
8617 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8619 child_status_out
[i
] = fn(i
);
8626 for (i
=0;i
<nprocs
;i
++) {
8627 if (child_status
[i
]) synccount
++;
8629 if (synccount
== nprocs
) break;
8631 } while (timeval_elapsed(&start
) < 30);
8633 if (synccount
!= nprocs
) {
8634 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8636 return timeval_elapsed(&start
);
8639 /* start the client load */
8640 start
= timeval_current();
8642 for (i
=0;i
<nprocs
;i
++) {
8643 child_status
[i
] = 0;
8646 printf("%d clients started\n", nprocs
);
8648 for (i
=0;i
<nprocs
;i
++) {
8649 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8654 for (i
=0;i
<nprocs
;i
++) {
8655 if (!child_status_out
[i
]) {
8659 return timeval_elapsed(&start
);
8662 #define FLAG_MULTIPROC 1
8669 {"FDPASS", run_fdpasstest
, 0},
8670 {"LOCK1", run_locktest1
, 0},
8671 {"LOCK2", run_locktest2
, 0},
8672 {"LOCK3", run_locktest3
, 0},
8673 {"LOCK4", run_locktest4
, 0},
8674 {"LOCK5", run_locktest5
, 0},
8675 {"LOCK6", run_locktest6
, 0},
8676 {"LOCK7", run_locktest7
, 0},
8677 {"LOCK8", run_locktest8
, 0},
8678 {"LOCK9", run_locktest9
, 0},
8679 {"UNLINK", run_unlinktest
, 0},
8680 {"BROWSE", run_browsetest
, 0},
8681 {"ATTR", run_attrtest
, 0},
8682 {"TRANS2", run_trans2test
, 0},
8683 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8684 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8685 {"RANDOMIPC", run_randomipc
, 0},
8686 {"NEGNOWAIT", run_negprot_nowait
, 0},
8687 {"NBENCH", run_nbench
, 0},
8688 {"NBENCH2", run_nbench2
, 0},
8689 {"OPLOCK1", run_oplock1
, 0},
8690 {"OPLOCK2", run_oplock2
, 0},
8691 {"OPLOCK4", run_oplock4
, 0},
8692 {"DIR", run_dirtest
, 0},
8693 {"DIR1", run_dirtest1
, 0},
8694 {"DIR-CREATETIME", run_dir_createtime
, 0},
8695 {"DENY1", torture_denytest1
, 0},
8696 {"DENY2", torture_denytest2
, 0},
8697 {"TCON", run_tcon_test
, 0},
8698 {"TCONDEV", run_tcon_devtype_test
, 0},
8699 {"RW1", run_readwritetest
, 0},
8700 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8701 {"RW3", run_readwritelarge
, 0},
8702 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8703 {"OPEN", run_opentest
, 0},
8704 {"POSIX", run_simple_posix_open_test
, 0},
8705 {"POSIX-APPEND", run_posix_append
, 0},
8706 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
8707 {"ASYNC-ECHO", run_async_echo
, 0},
8708 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8709 { "SHORTNAME-TEST", run_shortname_test
, 0},
8710 { "ADDRCHANGE", run_addrchange
, 0},
8712 {"OPENATTR", run_openattrtest
, 0},
8714 {"XCOPY", run_xcopy
, 0},
8715 {"RENAME", run_rename
, 0},
8716 {"DELETE", run_deletetest
, 0},
8717 {"DELETE-LN", run_deletetest_ln
, 0},
8718 {"PROPERTIES", run_properties
, 0},
8719 {"MANGLE", torture_mangle
, 0},
8720 {"MANGLE1", run_mangle1
, 0},
8721 {"W2K", run_w2ktest
, 0},
8722 {"TRANS2SCAN", torture_trans2_scan
, 0},
8723 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8724 {"UTABLE", torture_utable
, 0},
8725 {"CASETABLE", torture_casetable
, 0},
8726 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8727 {"PIPE_NUMBER", run_pipe_number
, 0},
8728 {"TCON2", run_tcon2_test
, 0},
8729 {"IOCTL", torture_ioctl_test
, 0},
8730 {"CHKPATH", torture_chkpath_test
, 0},
8731 {"FDSESS", run_fdsesstest
, 0},
8732 { "EATEST", run_eatest
, 0},
8733 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8734 { "CHAIN1", run_chain1
, 0},
8735 { "CHAIN2", run_chain2
, 0},
8736 { "WINDOWS-WRITE", run_windows_write
, 0},
8737 { "NTTRANS-CREATE", run_nttrans_create
, 0},
8738 { "CLI_ECHO", run_cli_echo
, 0},
8739 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8740 { "TLDAP", run_tldap
},
8741 { "STREAMERROR", run_streamerror
},
8742 { "NOTIFY-BENCH", run_notify_bench
},
8743 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8744 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8745 { "NOTIFY-ONLINE", run_notify_online
},
8746 { "SMB2-BASIC", run_smb2_basic
},
8747 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8748 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8749 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8750 { "LOCAL-BASE64", run_local_base64
, 0},
8751 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8752 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8753 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8754 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8755 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8756 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8757 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8758 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8759 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
8764 /****************************************************************************
8765 run a specified test or "ALL"
8766 ****************************************************************************/
8767 static bool run_test(const char *name
)
8774 if (strequal(name
,"ALL")) {
8775 for (i
=0;torture_ops
[i
].name
;i
++) {
8776 run_test(torture_ops
[i
].name
);
8781 for (i
=0;torture_ops
[i
].name
;i
++) {
8782 fstr_sprintf(randomfname
, "\\XX%x",
8783 (unsigned)random());
8785 if (strequal(name
, torture_ops
[i
].name
)) {
8787 printf("Running %s\n", name
);
8788 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8789 t
= create_procs(torture_ops
[i
].fn
, &result
);
8792 printf("TEST %s FAILED!\n", name
);
8795 struct timeval start
;
8796 start
= timeval_current();
8797 if (!torture_ops
[i
].fn(0)) {
8799 printf("TEST %s FAILED!\n", name
);
8801 t
= timeval_elapsed(&start
);
8803 printf("%s took %g secs\n\n", name
, t
);
8808 printf("Did not find a test named %s\n", name
);
8816 static void usage(void)
8820 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8821 printf("Please use samba4 torture.\n\n");
8823 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8825 printf("\t-d debuglevel\n");
8826 printf("\t-U user%%pass\n");
8827 printf("\t-k use kerberos\n");
8828 printf("\t-N numprocs\n");
8829 printf("\t-n my_netbios_name\n");
8830 printf("\t-W workgroup\n");
8831 printf("\t-o num_operations\n");
8832 printf("\t-O socket_options\n");
8833 printf("\t-m maximum protocol\n");
8834 printf("\t-L use oplocks\n");
8835 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8836 printf("\t-A showall\n");
8837 printf("\t-p port\n");
8838 printf("\t-s seed\n");
8839 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8840 printf("\t-f filename filename to test\n");
8843 printf("tests are:");
8844 for (i
=0;torture_ops
[i
].name
;i
++) {
8845 printf(" %s", torture_ops
[i
].name
);
8849 printf("default test is ALL\n");
8854 /****************************************************************************
8856 ****************************************************************************/
8857 int main(int argc
,char *argv
[])
8863 bool correct
= True
;
8864 TALLOC_CTX
*frame
= talloc_stackframe();
8865 int seed
= time(NULL
);
8867 #ifdef HAVE_SETBUFFER
8868 setbuffer(stdout
, NULL
, 0);
8871 setup_logging("smbtorture", DEBUG_STDOUT
);
8875 if (is_default_dyn_CONFIGFILE()) {
8876 if(getenv("SMB_CONF_PATH")) {
8877 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8880 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
8887 for(p
= argv
[1]; *p
; p
++)
8891 if (strncmp(argv
[1], "//", 2)) {
8895 fstrcpy(host
, &argv
[1][2]);
8896 p
= strchr_m(&host
[2],'/');
8901 fstrcpy(share
, p
+1);
8903 fstrcpy(myname
, get_myname(talloc_tos()));
8905 fprintf(stderr
, "Failed to get my hostname.\n");
8909 if (*username
== 0 && getenv("LOGNAME")) {
8910 fstrcpy(username
,getenv("LOGNAME"));
8916 fstrcpy(workgroup
, lp_workgroup());
8918 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8922 port_to_use
= atoi(optarg
);
8925 seed
= atoi(optarg
);
8928 fstrcpy(workgroup
,optarg
);
8931 max_protocol
= interpret_protocol(optarg
, max_protocol
);
8934 nprocs
= atoi(optarg
);
8937 torture_numops
= atoi(optarg
);
8940 lp_set_cmdline("log level", optarg
);
8949 local_path
= optarg
;
8952 torture_showall
= True
;
8955 fstrcpy(myname
, optarg
);
8958 client_txt
= optarg
;
8965 use_kerberos
= True
;
8967 d_printf("No kerberos support compiled in\n");
8973 fstrcpy(username
,optarg
);
8974 p
= strchr_m(username
,'%');
8977 fstrcpy(password
, p
+1);
8982 fstrcpy(multishare_conn_fname
, optarg
);
8983 use_multishare_conn
= True
;
8986 torture_blocksize
= atoi(optarg
);
8989 test_filename
= SMB_STRDUP(optarg
);
8992 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
8997 d_printf("using seed %d\n", seed
);
9001 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9004 p
= getpass("Password:");
9006 fstrcpy(password
, p
);
9011 printf("host=%s share=%s user=%s myname=%s\n",
9012 host
, share
, username
, myname
);
9014 if (argc
== optind
) {
9015 correct
= run_test("ALL");
9017 for (i
=optind
;i
<argc
;i
++) {
9018 if (!run_test(argv
[i
])) {