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"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
50 fstring host
, workgroup
, share
, password
, username
, myname
;
51 struct cli_credentials
*torture_creds
;
52 static const char *sockops
="TCP_NODELAY";
54 static int port_to_use
=0;
55 int torture_numops
=100;
56 int torture_blocksize
=1024*1024;
57 static int procnum
; /* records process count number when forking */
58 static struct cli_state
*current_cli
;
59 static fstring randomfname
;
60 static bool use_oplocks
;
61 static bool use_level_II_oplocks
;
62 static const char *client_txt
= "client_oplocks.txt";
63 static bool disable_spnego
;
64 static bool use_kerberos
;
65 static bool force_dos_errors
;
66 static fstring multishare_conn_fname
;
67 static bool use_multishare_conn
= False
;
68 static bool do_encrypt
;
69 static const char *local_path
= NULL
;
70 static enum smb_signing_setting signing_state
= SMB_SIGNING_DEFAULT
;
73 bool torture_showall
= False
;
75 static double create_procs(bool (*fn
)(int), bool *result
);
77 /********************************************************************
78 Ensure a connection is encrypted.
79 ********************************************************************/
81 static bool force_cli_encryption(struct cli_state
*c
,
82 const char *sharename
)
84 uint16_t major
, minor
;
85 uint32_t caplow
, caphigh
;
88 if (!SERVER_HAS_UNIX_CIFS(c
)) {
89 d_printf("Encryption required and "
90 "server that doesn't support "
91 "UNIX extensions - failing connect\n");
95 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
97 if (!NT_STATUS_IS_OK(status
)) {
98 d_printf("Encryption required and "
99 "can't get UNIX CIFS extensions "
100 "version from server: %s\n", nt_errstr(status
));
104 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
105 d_printf("Encryption required and "
106 "share %s doesn't support "
107 "encryption.\n", sharename
);
111 status
= cli_smb1_setup_encryption(c
, torture_creds
);
112 if (!NT_STATUS_IS_OK(status
)) {
113 d_printf("Encryption required and "
114 "setup failed with error %s.\n",
123 static struct cli_state
*open_nbt_connection(void)
129 if (disable_spnego
) {
130 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
134 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
137 if (use_level_II_oplocks
) {
138 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
142 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
145 if (force_dos_errors
) {
146 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
149 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
150 signing_state
, flags
, &c
);
151 if (!NT_STATUS_IS_OK(status
)) {
152 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
156 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
161 /****************************************************************************
162 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
163 ****************************************************************************/
165 static bool cli_bad_session_request(int fd
,
166 struct nmb_name
*calling
, struct nmb_name
*called
)
175 uint8_t message_type
;
177 struct tevent_context
*ev
;
178 struct tevent_req
*req
;
180 frame
= talloc_stackframe();
182 iov
[0].iov_base
= len_buf
;
183 iov
[0].iov_len
= sizeof(len_buf
);
185 /* put in the destination name */
187 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
189 if (iov
[1].iov_base
== NULL
) {
192 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
193 talloc_get_size(iov
[1].iov_base
));
197 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
199 if (iov
[2].iov_base
== NULL
) {
202 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
203 talloc_get_size(iov
[2].iov_base
));
205 /* Deliberately corrupt the name len (first byte) */
206 *((uint8_t *)iov
[2].iov_base
) = 100;
208 /* send a session request (RFC 1002) */
209 /* setup the packet length
210 * Remove four bytes from the length count, since the length
211 * field in the NBT Session Service header counts the number
212 * of bytes which follow. The cli_send_smb() function knows
213 * about this and accounts for those four bytes.
217 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
218 SCVAL(len_buf
,0,0x81);
220 len
= write_data_iov(fd
, iov
, 3);
225 ev
= samba_tevent_context_init(frame
);
229 req
= read_smb_send(frame
, ev
, fd
);
233 if (!tevent_req_poll(req
, ev
)) {
236 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
243 message_type
= CVAL(inbuf
, 0);
244 if (message_type
!= 0x83) {
245 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
250 if (smb_len(inbuf
) != 1) {
251 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
252 (int)smb_len(inbuf
));
256 error
= CVAL(inbuf
, 4);
258 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
269 /* Insert a NULL at the first separator of the given path and return a pointer
270 * to the remainder of the string.
273 terminate_path_at_separator(char * path
)
281 if ((p
= strchr_m(path
, '/'))) {
286 if ((p
= strchr_m(path
, '\\'))) {
296 parse a //server/share type UNC name
298 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
299 char **hostname
, char **sharename
)
303 *hostname
= *sharename
= NULL
;
305 if (strncmp(unc_name
, "\\\\", 2) &&
306 strncmp(unc_name
, "//", 2)) {
310 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
311 p
= terminate_path_at_separator(*hostname
);
314 *sharename
= talloc_strdup(mem_ctx
, p
);
315 terminate_path_at_separator(*sharename
);
318 if (*hostname
&& *sharename
) {
322 TALLOC_FREE(*hostname
);
323 TALLOC_FREE(*sharename
);
327 static bool torture_open_connection_share(struct cli_state
**c
,
328 const char *hostname
,
329 const char *sharename
,
334 status
= cli_full_connection_creds(c
,
344 if (!NT_STATUS_IS_OK(status
)) {
345 printf("failed to open share connection: //%s/%s port:%d - %s\n",
346 hostname
, sharename
, port_to_use
, nt_errstr(status
));
350 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
353 return force_cli_encryption(*c
,
359 bool torture_open_connection_flags(struct cli_state
**c
, int conn_index
, int flags
)
361 char **unc_list
= NULL
;
362 int num_unc_names
= 0;
365 if (use_multishare_conn
==True
) {
367 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
368 if (!unc_list
|| num_unc_names
<= 0) {
369 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
373 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
375 printf("Failed to parse UNC name %s\n",
376 unc_list
[conn_index
% num_unc_names
]);
377 TALLOC_FREE(unc_list
);
381 result
= torture_open_connection_share(c
, h
, s
, flags
);
383 /* h, s were copied earlier */
384 TALLOC_FREE(unc_list
);
388 return torture_open_connection_share(c
, host
, share
, flags
);
391 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
393 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
396 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
398 if (use_level_II_oplocks
) {
399 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
402 return torture_open_connection_flags(c
, conn_index
, flags
);
405 bool torture_init_connection(struct cli_state
**pcli
)
407 struct cli_state
*cli
;
409 cli
= open_nbt_connection();
418 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16_t *new_vuid
)
420 uint16_t old_vuid
= cli_state_get_uid(cli
);
424 cli_state_set_uid(cli
, 0);
425 status
= cli_session_setup_creds(cli
, torture_creds
);
426 ret
= NT_STATUS_IS_OK(status
);
427 *new_vuid
= cli_state_get_uid(cli
);
428 cli_state_set_uid(cli
, old_vuid
);
433 bool torture_close_connection(struct cli_state
*c
)
438 status
= cli_tdis(c
);
439 if (!NT_STATUS_IS_OK(status
)) {
440 printf("tdis failed (%s)\n", nt_errstr(status
));
450 /* check if the server produced the expected dos or nt error code */
451 static bool check_both_error(int line
, NTSTATUS status
,
452 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
454 if (NT_STATUS_IS_DOS(status
)) {
458 /* Check DOS error */
459 cclass
= NT_STATUS_DOS_CLASS(status
);
460 num
= NT_STATUS_DOS_CODE(status
);
462 if (eclass
!= cclass
|| ecode
!= num
) {
463 printf("unexpected error code class=%d code=%d\n",
464 (int)cclass
, (int)num
);
465 printf(" expected %d/%d %s (line=%d)\n",
466 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
471 if (!NT_STATUS_EQUAL(nterr
, status
)) {
472 printf("unexpected error code %s\n",
474 printf(" expected %s (line=%d)\n",
475 nt_errstr(nterr
), line
);
484 /* check if the server produced the expected error code */
485 static bool check_error(int line
, NTSTATUS status
,
486 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
488 if (NT_STATUS_IS_DOS(status
)) {
492 /* Check DOS error */
494 cclass
= NT_STATUS_DOS_CLASS(status
);
495 num
= NT_STATUS_DOS_CODE(status
);
497 if (eclass
!= cclass
|| ecode
!= num
) {
498 printf("unexpected error code class=%d code=%d\n",
499 (int)cclass
, (int)num
);
500 printf(" expected %d/%d %s (line=%d)\n",
501 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
509 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
510 printf("unexpected error code %s\n",
512 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
522 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
526 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
528 while (!NT_STATUS_IS_OK(status
)) {
529 if (!check_both_error(__LINE__
, status
, ERRDOS
,
530 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
534 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
541 static bool rw_torture(struct cli_state
*c
)
543 const char *lockfname
= "\\torture.lck";
547 pid_t pid2
, pid
= getpid();
554 memset(buf
, '\0', sizeof(buf
));
556 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
558 if (!NT_STATUS_IS_OK(status
)) {
559 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 printf("open of %s failed (%s)\n",
563 lockfname
, nt_errstr(status
));
567 for (i
=0;i
<torture_numops
;i
++) {
568 unsigned n
= (unsigned)sys_random()%10;
571 printf("%d\r", i
); fflush(stdout
);
573 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
575 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
579 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
581 if (!NT_STATUS_IS_OK(status
)) {
582 printf("open failed (%s)\n", nt_errstr(status
));
587 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
589 if (!NT_STATUS_IS_OK(status
)) {
590 printf("write failed (%s)\n", nt_errstr(status
));
595 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
596 sizeof(pid
)+(j
*sizeof(buf
)),
598 if (!NT_STATUS_IS_OK(status
)) {
599 printf("write failed (%s)\n",
607 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
609 if (!NT_STATUS_IS_OK(status
)) {
610 printf("read failed (%s)\n", nt_errstr(status
));
612 } else if (nread
!= sizeof(pid
)) {
613 printf("read/write compare failed: "
614 "recv %ld req %ld\n", (unsigned long)nread
,
615 (unsigned long)sizeof(pid
));
620 printf("data corruption!\n");
624 status
= cli_close(c
, fnum
);
625 if (!NT_STATUS_IS_OK(status
)) {
626 printf("close failed (%s)\n", nt_errstr(status
));
630 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
631 if (!NT_STATUS_IS_OK(status
)) {
632 printf("unlink failed (%s)\n", nt_errstr(status
));
636 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
637 if (!NT_STATUS_IS_OK(status
)) {
638 printf("unlock failed (%s)\n", nt_errstr(status
));
644 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
651 static bool run_torture(int dummy
)
653 struct cli_state
*cli
;
658 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
660 ret
= rw_torture(cli
);
662 if (!torture_close_connection(cli
)) {
669 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
671 uint16_t fnum
= (uint16_t)-1;
676 unsigned countprev
= 0;
679 NTSTATUS status
= NT_STATUS_OK
;
682 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32_t))
684 SIVAL(buf
, i
, sys_random());
691 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
692 if (!NT_STATUS_IS_OK(status
)) {
693 printf("unlink failed (%s) (normal, this file should "
694 "not exist)\n", nt_errstr(status
));
697 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
699 if (!NT_STATUS_IS_OK(status
)) {
700 printf("first open read/write of %s failed (%s)\n",
701 lockfname
, nt_errstr(status
));
707 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
709 status
= cli_openx(c
, lockfname
, O_RDONLY
,
711 if (NT_STATUS_IS_OK(status
)) {
716 if (!NT_STATUS_IS_OK(status
)) {
717 printf("second open read-only of %s failed (%s)\n",
718 lockfname
, nt_errstr(status
));
724 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
726 if (count
>= countprev
) {
727 printf("%d %8d\r", i
, count
);
730 countprev
+= (sizeof(buf
) / 20);
735 sent
= ((unsigned)sys_random()%(20))+ 1;
736 if (sent
> sizeof(buf
) - count
)
738 sent
= sizeof(buf
) - count
;
741 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
743 if (!NT_STATUS_IS_OK(status
)) {
744 printf("write failed (%s)\n",
751 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
752 sizeof(buf
)-count
, &sent
);
753 if(!NT_STATUS_IS_OK(status
)) {
754 printf("read failed offset:%d size:%ld (%s)\n",
755 count
, (unsigned long)sizeof(buf
)-count
,
759 } else if (sent
> 0) {
760 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
762 printf("read/write compare failed\n");
763 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
772 status
= cli_close(c
, fnum
);
773 if (!NT_STATUS_IS_OK(status
)) {
774 printf("close failed (%s)\n", nt_errstr(status
));
781 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
783 const char *lockfname
= "\\torture2.lck";
793 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
794 if (!NT_STATUS_IS_OK(status
)) {
795 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
798 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
800 if (!NT_STATUS_IS_OK(status
)) {
801 printf("first open read/write of %s failed (%s)\n",
802 lockfname
, nt_errstr(status
));
806 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
807 if (!NT_STATUS_IS_OK(status
)) {
808 printf("second open read-only of %s failed (%s)\n",
809 lockfname
, nt_errstr(status
));
810 cli_close(c1
, fnum1
);
814 for (i
= 0; i
< torture_numops
; i
++)
816 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
818 printf("%d\r", i
); fflush(stdout
);
821 generate_random_buffer((unsigned char *)buf
, buf_size
);
823 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
825 if (!NT_STATUS_IS_OK(status
)) {
826 printf("write failed (%s)\n", nt_errstr(status
));
831 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
832 if(!NT_STATUS_IS_OK(status
)) {
833 printf("read failed (%s)\n", nt_errstr(status
));
836 } else if (bytes_read
!= buf_size
) {
837 printf("read failed\n");
838 printf("read %ld, expected %ld\n",
839 (unsigned long)bytes_read
,
840 (unsigned long)buf_size
);
845 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
847 printf("read/write compare failed\n");
853 status
= cli_close(c2
, fnum2
);
854 if (!NT_STATUS_IS_OK(status
)) {
855 printf("close failed (%s)\n", nt_errstr(status
));
859 status
= cli_close(c1
, fnum1
);
860 if (!NT_STATUS_IS_OK(status
)) {
861 printf("close failed (%s)\n", nt_errstr(status
));
865 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
866 if (!NT_STATUS_IS_OK(status
)) {
867 printf("unlink failed (%s)\n", nt_errstr(status
));
874 static bool run_readwritetest(int dummy
)
876 struct cli_state
*cli1
, *cli2
;
877 bool test1
, test2
= False
;
879 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
882 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
883 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
885 printf("starting readwritetest\n");
887 test1
= rw_torture2(cli1
, cli2
);
888 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
891 test2
= rw_torture2(cli1
, cli1
);
892 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
895 if (!torture_close_connection(cli1
)) {
899 if (!torture_close_connection(cli2
)) {
903 return (test1
&& test2
);
906 static bool run_readwritemulti(int dummy
)
908 struct cli_state
*cli
;
913 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
915 printf("run_readwritemulti: fname %s\n", randomfname
);
916 test
= rw_torture3(cli
, randomfname
);
918 if (!torture_close_connection(cli
)) {
925 static bool run_readwritelarge_internal(void)
927 static struct cli_state
*cli1
;
929 const char *lockfname
= "\\large.dat";
935 if (!torture_open_connection(&cli1
, 0)) {
938 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
939 memset(buf
,'\0',sizeof(buf
));
941 printf("starting readwritelarge_internal\n");
943 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
945 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
947 if (!NT_STATUS_IS_OK(status
)) {
948 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
952 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
954 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
956 if (!NT_STATUS_IS_OK(status
)) {
957 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
961 if (fsize
== sizeof(buf
))
962 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
963 (unsigned long)fsize
);
965 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
966 (unsigned long)fsize
);
970 status
= cli_close(cli1
, fnum1
);
971 if (!NT_STATUS_IS_OK(status
)) {
972 printf("close failed (%s)\n", nt_errstr(status
));
976 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
977 if (!NT_STATUS_IS_OK(status
)) {
978 printf("unlink failed (%s)\n", nt_errstr(status
));
982 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
984 if (!NT_STATUS_IS_OK(status
)) {
985 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
989 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
991 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
993 if (!NT_STATUS_IS_OK(status
)) {
994 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
998 if (fsize
== sizeof(buf
))
999 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1000 (unsigned long)fsize
);
1002 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1003 (unsigned long)fsize
);
1008 /* ToDo - set allocation. JRA */
1009 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1010 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1013 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1015 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1019 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1022 status
= cli_close(cli1
, fnum1
);
1023 if (!NT_STATUS_IS_OK(status
)) {
1024 printf("close failed (%s)\n", nt_errstr(status
));
1028 if (!torture_close_connection(cli1
)) {
1034 static bool run_readwritelarge(int dummy
)
1036 return run_readwritelarge_internal();
1039 static bool run_readwritelarge_signtest(int dummy
)
1042 signing_state
= SMB_SIGNING_REQUIRED
;
1043 ret
= run_readwritelarge_internal();
1044 signing_state
= SMB_SIGNING_DEFAULT
;
1051 #define ival(s) strtol(s, NULL, 0)
1053 /* run a test that simulates an approximate netbench client load */
1054 static bool run_netbench(int client
)
1056 struct cli_state
*cli
;
1061 const char *params
[20];
1062 bool correct
= True
;
1068 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1072 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1074 f
= fopen(client_txt
, "r");
1081 while (fgets(line
, sizeof(line
)-1, f
)) {
1085 line
[strlen(line
)-1] = 0;
1087 /* printf("[%d] %s\n", line_count, line); */
1089 all_string_sub(line
,"client1", cname
, sizeof(line
));
1091 /* parse the command parameters */
1092 params
[0] = strtok_r(line
, " ", &saveptr
);
1094 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1098 if (i
< 2) continue;
1100 if (!strncmp(params
[0],"SMB", 3)) {
1101 printf("ERROR: You are using a dbench 1 load file\n");
1105 if (!strcmp(params
[0],"NTCreateX")) {
1106 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1108 } else if (!strcmp(params
[0],"Close")) {
1109 nb_close(ival(params
[1]));
1110 } else if (!strcmp(params
[0],"Rename")) {
1111 nb_rename(params
[1], params
[2]);
1112 } else if (!strcmp(params
[0],"Unlink")) {
1113 nb_unlink(params
[1]);
1114 } else if (!strcmp(params
[0],"Deltree")) {
1115 nb_deltree(params
[1]);
1116 } else if (!strcmp(params
[0],"Rmdir")) {
1117 nb_rmdir(params
[1]);
1118 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1119 nb_qpathinfo(params
[1]);
1120 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1121 nb_qfileinfo(ival(params
[1]));
1122 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1123 nb_qfsinfo(ival(params
[1]));
1124 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1125 nb_findfirst(params
[1]);
1126 } else if (!strcmp(params
[0],"WriteX")) {
1127 nb_writex(ival(params
[1]),
1128 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1129 } else if (!strcmp(params
[0],"ReadX")) {
1130 nb_readx(ival(params
[1]),
1131 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1132 } else if (!strcmp(params
[0],"Flush")) {
1133 nb_flush(ival(params
[1]));
1135 printf("Unknown operation %s\n", params
[0]);
1143 if (!torture_close_connection(cli
)) {
1151 /* run a test that simulates an approximate netbench client load */
1152 static bool run_nbench(int dummy
)
1155 bool correct
= True
;
1157 nbio_shmem(torture_nprocs
);
1161 signal(SIGALRM
, nb_alarm
);
1163 t
= create_procs(run_netbench
, &correct
);
1166 printf("\nThroughput %g MB/sec\n",
1167 1.0e-6 * nbio_total() / t
);
1173 This test checks for two things:
1175 1) correct support for retaining locks over a close (ie. the server
1176 must not use posix semantics)
1177 2) support for lock timeouts
1179 static bool run_locktest1(int dummy
)
1181 struct cli_state
*cli1
, *cli2
;
1182 const char *fname
= "\\lockt1.lck";
1183 uint16_t fnum1
, fnum2
, fnum3
;
1185 unsigned lock_timeout
;
1188 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1191 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1192 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1194 printf("starting locktest1\n");
1196 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1198 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1200 if (!NT_STATUS_IS_OK(status
)) {
1201 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1205 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1206 if (!NT_STATUS_IS_OK(status
)) {
1207 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1211 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1212 if (!NT_STATUS_IS_OK(status
)) {
1213 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1217 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1218 if (!NT_STATUS_IS_OK(status
)) {
1219 printf("lock1 failed (%s)\n", nt_errstr(status
));
1223 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1224 if (NT_STATUS_IS_OK(status
)) {
1225 printf("lock2 succeeded! This is a locking bug\n");
1228 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1229 NT_STATUS_LOCK_NOT_GRANTED
)) {
1234 lock_timeout
= (1 + (random() % 20));
1235 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1237 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1238 if (NT_STATUS_IS_OK(status
)) {
1239 printf("lock3 succeeded! This is a locking bug\n");
1242 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1243 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1249 if (ABS(t2
- t1
) < lock_timeout
-1) {
1250 printf("error: This server appears not to support timed lock requests\n");
1253 printf("server slept for %u seconds for a %u second timeout\n",
1254 (unsigned int)(t2
-t1
), lock_timeout
);
1256 status
= cli_close(cli1
, fnum2
);
1257 if (!NT_STATUS_IS_OK(status
)) {
1258 printf("close1 failed (%s)\n", nt_errstr(status
));
1262 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1263 if (NT_STATUS_IS_OK(status
)) {
1264 printf("lock4 succeeded! This is a locking bug\n");
1267 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1268 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1273 status
= cli_close(cli1
, fnum1
);
1274 if (!NT_STATUS_IS_OK(status
)) {
1275 printf("close2 failed (%s)\n", nt_errstr(status
));
1279 status
= cli_close(cli2
, fnum3
);
1280 if (!NT_STATUS_IS_OK(status
)) {
1281 printf("close3 failed (%s)\n", nt_errstr(status
));
1285 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1286 if (!NT_STATUS_IS_OK(status
)) {
1287 printf("unlink failed (%s)\n", nt_errstr(status
));
1292 if (!torture_close_connection(cli1
)) {
1296 if (!torture_close_connection(cli2
)) {
1300 printf("Passed locktest1\n");
1305 this checks to see if a secondary tconx can use open files from an
1308 static bool run_tcon_test(int dummy
)
1310 static struct cli_state
*cli
;
1311 const char *fname
= "\\tcontest.tmp";
1313 uint32_t cnum1
, cnum2
, cnum3
;
1314 struct smbXcli_tcon
*orig_tcon
= NULL
;
1315 uint16_t vuid1
, vuid2
;
1320 memset(buf
, '\0', sizeof(buf
));
1322 if (!torture_open_connection(&cli
, 0)) {
1325 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1327 printf("starting tcontest\n");
1329 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1331 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1332 if (!NT_STATUS_IS_OK(status
)) {
1333 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1337 cnum1
= cli_state_get_tid(cli
);
1338 vuid1
= cli_state_get_uid(cli
);
1340 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1341 if (!NT_STATUS_IS_OK(status
)) {
1342 printf("initial write failed (%s)", nt_errstr(status
));
1346 orig_tcon
= cli_state_save_tcon(cli
);
1347 if (orig_tcon
== NULL
) {
1351 status
= cli_tree_connect_creds(cli
, share
, "?????", torture_creds
);
1352 if (!NT_STATUS_IS_OK(status
)) {
1353 printf("%s refused 2nd tree connect (%s)\n", host
,
1359 cnum2
= cli_state_get_tid(cli
);
1360 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1361 vuid2
= cli_state_get_uid(cli
) + 1;
1363 /* try a write with the wrong tid */
1364 cli_state_set_tid(cli
, cnum2
);
1366 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1367 if (NT_STATUS_IS_OK(status
)) {
1368 printf("* server allows write with wrong TID\n");
1371 printf("server fails write with wrong TID : %s\n",
1376 /* try a write with an invalid tid */
1377 cli_state_set_tid(cli
, cnum3
);
1379 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1380 if (NT_STATUS_IS_OK(status
)) {
1381 printf("* server allows write with invalid TID\n");
1384 printf("server fails write with invalid TID : %s\n",
1388 /* try a write with an invalid vuid */
1389 cli_state_set_uid(cli
, vuid2
);
1390 cli_state_set_tid(cli
, cnum1
);
1392 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1393 if (NT_STATUS_IS_OK(status
)) {
1394 printf("* server allows write with invalid VUID\n");
1397 printf("server fails write with invalid VUID : %s\n",
1401 cli_state_set_tid(cli
, cnum1
);
1402 cli_state_set_uid(cli
, vuid1
);
1404 status
= cli_close(cli
, fnum1
);
1405 if (!NT_STATUS_IS_OK(status
)) {
1406 printf("close failed (%s)\n", nt_errstr(status
));
1410 cli_state_set_tid(cli
, cnum2
);
1412 status
= cli_tdis(cli
);
1413 if (!NT_STATUS_IS_OK(status
)) {
1414 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1418 cli_state_restore_tcon(cli
, orig_tcon
);
1420 cli_state_set_tid(cli
, cnum1
);
1422 if (!torture_close_connection(cli
)) {
1431 checks for old style tcon support
1433 static bool run_tcon2_test(int dummy
)
1435 static struct cli_state
*cli
;
1436 uint16_t cnum
, max_xmit
;
1440 if (!torture_open_connection(&cli
, 0)) {
1443 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1445 printf("starting tcon2 test\n");
1447 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1451 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1455 if (!NT_STATUS_IS_OK(status
)) {
1456 printf("tcon2 failed : %s\n", nt_errstr(status
));
1458 printf("tcon OK : max_xmit=%d cnum=%d\n",
1459 (int)max_xmit
, (int)cnum
);
1462 if (!torture_close_connection(cli
)) {
1466 printf("Passed tcon2 test\n");
1470 static bool tcon_devtest(struct cli_state
*cli
,
1471 const char *myshare
, const char *devtype
,
1472 const char *return_devtype
,
1473 NTSTATUS expected_error
)
1478 status
= cli_tree_connect_creds(cli
, myshare
, devtype
, torture_creds
);
1480 if (NT_STATUS_IS_OK(expected_error
)) {
1481 if (NT_STATUS_IS_OK(status
)) {
1482 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1485 printf("tconX to share %s with type %s "
1486 "succeeded but returned the wrong "
1487 "device type (got [%s] but should have got [%s])\n",
1488 myshare
, devtype
, cli
->dev
, return_devtype
);
1492 printf("tconX to share %s with type %s "
1493 "should have succeeded but failed\n",
1499 if (NT_STATUS_IS_OK(status
)) {
1500 printf("tconx to share %s with type %s "
1501 "should have failed but succeeded\n",
1505 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1508 printf("Returned unexpected error\n");
1517 checks for correct tconX support
1519 static bool run_tcon_devtype_test(int dummy
)
1521 static struct cli_state
*cli1
= NULL
;
1522 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
1526 status
= cli_full_connection_creds(&cli1
,
1532 NULL
, /* service_type */
1537 if (!NT_STATUS_IS_OK(status
)) {
1538 printf("could not open connection\n");
1542 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1545 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1548 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1551 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1554 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1557 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1560 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1563 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1566 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1569 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1575 printf("Passed tcondevtest\n");
1582 This test checks that
1584 1) the server supports multiple locking contexts on the one SMB
1585 connection, distinguished by PID.
1587 2) the server correctly fails overlapping locks made by the same PID (this
1588 goes against POSIX behaviour, which is why it is tricky to implement)
1590 3) the server denies unlock requests by an incorrect client PID
1592 static bool run_locktest2(int dummy
)
1594 static struct cli_state
*cli
;
1595 const char *fname
= "\\lockt2.lck";
1596 uint16_t fnum1
, fnum2
, fnum3
;
1597 bool correct
= True
;
1600 if (!torture_open_connection(&cli
, 0)) {
1604 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1606 printf("starting locktest2\n");
1608 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1612 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1613 if (!NT_STATUS_IS_OK(status
)) {
1614 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1618 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1619 if (!NT_STATUS_IS_OK(status
)) {
1620 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1626 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1627 if (!NT_STATUS_IS_OK(status
)) {
1628 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1634 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1635 if (!NT_STATUS_IS_OK(status
)) {
1636 printf("lock1 failed (%s)\n", nt_errstr(status
));
1640 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1641 if (NT_STATUS_IS_OK(status
)) {
1642 printf("WRITE lock1 succeeded! This is a locking bug\n");
1645 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1646 NT_STATUS_LOCK_NOT_GRANTED
)) {
1651 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1652 if (NT_STATUS_IS_OK(status
)) {
1653 printf("WRITE lock2 succeeded! This is a locking bug\n");
1656 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1657 NT_STATUS_LOCK_NOT_GRANTED
)) {
1662 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1663 if (NT_STATUS_IS_OK(status
)) {
1664 printf("READ lock2 succeeded! This is a locking bug\n");
1667 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1668 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1673 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1674 if (!NT_STATUS_IS_OK(status
)) {
1675 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1678 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1679 printf("unlock at 100 succeeded! This is a locking bug\n");
1683 status
= cli_unlock(cli
, fnum1
, 0, 4);
1684 if (NT_STATUS_IS_OK(status
)) {
1685 printf("unlock1 succeeded! This is a locking bug\n");
1688 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1689 NT_STATUS_RANGE_NOT_LOCKED
)) {
1694 status
= cli_unlock(cli
, fnum1
, 0, 8);
1695 if (NT_STATUS_IS_OK(status
)) {
1696 printf("unlock2 succeeded! This is a locking bug\n");
1699 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1700 NT_STATUS_RANGE_NOT_LOCKED
)) {
1705 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1706 if (NT_STATUS_IS_OK(status
)) {
1707 printf("lock3 succeeded! This is a locking bug\n");
1710 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1711 NT_STATUS_LOCK_NOT_GRANTED
)) {
1718 status
= cli_close(cli
, fnum1
);
1719 if (!NT_STATUS_IS_OK(status
)) {
1720 printf("close1 failed (%s)\n", nt_errstr(status
));
1724 status
= cli_close(cli
, fnum2
);
1725 if (!NT_STATUS_IS_OK(status
)) {
1726 printf("close2 failed (%s)\n", nt_errstr(status
));
1730 status
= cli_close(cli
, fnum3
);
1731 if (!NT_STATUS_IS_OK(status
)) {
1732 printf("close3 failed (%s)\n", nt_errstr(status
));
1736 if (!torture_close_connection(cli
)) {
1740 printf("locktest2 finished\n");
1747 This test checks that
1749 1) the server supports the full offset range in lock requests
1751 static bool run_locktest3(int dummy
)
1753 static struct cli_state
*cli1
, *cli2
;
1754 const char *fname
= "\\lockt3.lck";
1755 uint16_t fnum1
, fnum2
;
1758 bool correct
= True
;
1761 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1763 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1766 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1767 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1769 printf("starting locktest3\n");
1771 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1773 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1775 if (!NT_STATUS_IS_OK(status
)) {
1776 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1780 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1781 if (!NT_STATUS_IS_OK(status
)) {
1782 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1786 for (offset
=i
=0;i
<torture_numops
;i
++) {
1789 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1790 if (!NT_STATUS_IS_OK(status
)) {
1791 printf("lock1 %d failed (%s)\n",
1797 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1798 if (!NT_STATUS_IS_OK(status
)) {
1799 printf("lock2 %d failed (%s)\n",
1806 for (offset
=i
=0;i
<torture_numops
;i
++) {
1809 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1810 if (NT_STATUS_IS_OK(status
)) {
1811 printf("error: lock1 %d succeeded!\n", i
);
1815 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1816 if (NT_STATUS_IS_OK(status
)) {
1817 printf("error: lock2 %d succeeded!\n", i
);
1821 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1822 if (NT_STATUS_IS_OK(status
)) {
1823 printf("error: lock3 %d succeeded!\n", i
);
1827 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1828 if (NT_STATUS_IS_OK(status
)) {
1829 printf("error: lock4 %d succeeded!\n", i
);
1834 for (offset
=i
=0;i
<torture_numops
;i
++) {
1837 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1838 if (!NT_STATUS_IS_OK(status
)) {
1839 printf("unlock1 %d failed (%s)\n",
1845 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1846 if (!NT_STATUS_IS_OK(status
)) {
1847 printf("unlock2 %d failed (%s)\n",
1854 status
= cli_close(cli1
, fnum1
);
1855 if (!NT_STATUS_IS_OK(status
)) {
1856 printf("close1 failed (%s)\n", nt_errstr(status
));
1860 status
= cli_close(cli2
, fnum2
);
1861 if (!NT_STATUS_IS_OK(status
)) {
1862 printf("close2 failed (%s)\n", nt_errstr(status
));
1866 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1867 if (!NT_STATUS_IS_OK(status
)) {
1868 printf("unlink failed (%s)\n", nt_errstr(status
));
1872 if (!torture_close_connection(cli1
)) {
1876 if (!torture_close_connection(cli2
)) {
1880 printf("finished locktest3\n");
1885 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1886 char *buf
, off_t offset
, size_t size
,
1887 size_t *nread
, size_t expect
)
1892 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1894 if(!NT_STATUS_IS_OK(status
)) {
1896 } else if (l_nread
!= expect
) {
1907 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1908 printf("** "); correct = False; \
1912 looks at overlapping locks
1914 static bool run_locktest4(int dummy
)
1916 static struct cli_state
*cli1
, *cli2
;
1917 const char *fname
= "\\lockt4.lck";
1918 uint16_t fnum1
, fnum2
, f
;
1921 bool correct
= True
;
1924 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1928 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1929 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1931 printf("starting locktest4\n");
1933 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1935 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1936 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1938 memset(buf
, 0, sizeof(buf
));
1940 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1942 if (!NT_STATUS_IS_OK(status
)) {
1943 printf("Failed to create file: %s\n", nt_errstr(status
));
1948 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1949 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1950 EXPECTED(ret
, False
);
1951 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1953 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
1954 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
1955 EXPECTED(ret
, True
);
1956 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1958 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
1959 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
1960 EXPECTED(ret
, False
);
1961 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1963 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
1964 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
1965 EXPECTED(ret
, True
);
1966 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1968 ret
= (cli_setpid(cli1
, 1),
1969 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
1970 (cli_setpid(cli1
, 2),
1971 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
1972 EXPECTED(ret
, False
);
1973 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1975 ret
= (cli_setpid(cli1
, 1),
1976 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
1977 (cli_setpid(cli1
, 2),
1978 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
1979 EXPECTED(ret
, True
);
1980 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1982 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
1983 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
1984 EXPECTED(ret
, True
);
1985 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1987 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
1988 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
1989 EXPECTED(ret
, False
);
1990 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1992 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
1993 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
1994 EXPECTED(ret
, False
);
1995 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1997 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
1998 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
1999 EXPECTED(ret
, True
);
2000 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2002 ret
= (cli_setpid(cli1
, 1),
2003 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2004 (cli_setpid(cli1
, 2),
2005 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2006 EXPECTED(ret
, False
);
2007 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2009 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2010 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2011 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2012 EXPECTED(ret
, False
);
2013 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2016 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2017 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2018 EXPECTED(ret
, False
);
2019 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2021 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2022 ret
= NT_STATUS_IS_OK(status
);
2024 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2026 ret
= NT_STATUS_IS_OK(status
);
2028 EXPECTED(ret
, False
);
2029 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2032 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2033 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2034 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2035 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2036 EXPECTED(ret
, True
);
2037 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2040 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2041 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2043 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2044 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2046 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2047 EXPECTED(ret
, True
);
2048 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2050 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2051 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2052 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2054 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2055 EXPECTED(ret
, True
);
2056 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2058 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2059 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2060 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2062 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2063 EXPECTED(ret
, True
);
2064 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2066 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2067 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2068 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2069 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2071 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2072 EXPECTED(ret
, True
);
2073 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2075 cli_close(cli1
, fnum1
);
2076 cli_close(cli2
, fnum2
);
2077 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2078 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2079 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2081 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2082 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2083 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2085 cli_close(cli1
, fnum1
);
2086 EXPECTED(ret
, True
);
2087 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2090 cli_close(cli1
, fnum1
);
2091 cli_close(cli2
, fnum2
);
2092 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2093 torture_close_connection(cli1
);
2094 torture_close_connection(cli2
);
2096 printf("finished locktest4\n");
2101 looks at lock upgrade/downgrade.
2103 static bool run_locktest5(int dummy
)
2105 static struct cli_state
*cli1
, *cli2
;
2106 const char *fname
= "\\lockt5.lck";
2107 uint16_t fnum1
, fnum2
, fnum3
;
2110 bool correct
= True
;
2113 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2117 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2118 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2120 printf("starting locktest5\n");
2122 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2124 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2125 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2126 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2128 memset(buf
, 0, sizeof(buf
));
2130 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2132 if (!NT_STATUS_IS_OK(status
)) {
2133 printf("Failed to create file: %s\n", nt_errstr(status
));
2138 /* Check for NT bug... */
2139 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2140 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2141 cli_close(cli1
, fnum1
);
2142 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2143 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2144 ret
= NT_STATUS_IS_OK(status
);
2145 EXPECTED(ret
, True
);
2146 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2147 cli_close(cli1
, fnum1
);
2148 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2149 cli_unlock(cli1
, fnum3
, 0, 1);
2151 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2152 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2153 EXPECTED(ret
, True
);
2154 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2156 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2157 ret
= NT_STATUS_IS_OK(status
);
2158 EXPECTED(ret
, False
);
2160 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2162 /* Unlock the process 2 lock. */
2163 cli_unlock(cli2
, fnum2
, 0, 4);
2165 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2166 ret
= NT_STATUS_IS_OK(status
);
2167 EXPECTED(ret
, False
);
2169 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2171 /* Unlock the process 1 fnum3 lock. */
2172 cli_unlock(cli1
, fnum3
, 0, 4);
2174 /* Stack 2 more locks here. */
2175 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2176 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2178 EXPECTED(ret
, True
);
2179 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2181 /* Unlock the first process lock, then check this was the WRITE lock that was
2184 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2185 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2187 EXPECTED(ret
, True
);
2188 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2190 /* Unlock the process 2 lock. */
2191 cli_unlock(cli2
, fnum2
, 0, 4);
2193 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2195 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2196 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2197 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2199 EXPECTED(ret
, True
);
2200 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2202 /* Ensure the next unlock fails. */
2203 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2204 EXPECTED(ret
, False
);
2205 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2207 /* Ensure connection 2 can get a write lock. */
2208 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2209 ret
= NT_STATUS_IS_OK(status
);
2210 EXPECTED(ret
, True
);
2212 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2216 cli_close(cli1
, fnum1
);
2217 cli_close(cli2
, fnum2
);
2218 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2219 if (!torture_close_connection(cli1
)) {
2222 if (!torture_close_connection(cli2
)) {
2226 printf("finished locktest5\n");
2232 tries the unusual lockingX locktype bits
2234 static bool run_locktest6(int dummy
)
2236 static struct cli_state
*cli
;
2237 const char *fname
[1] = { "\\lock6.txt" };
2242 if (!torture_open_connection(&cli
, 0)) {
2246 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2248 printf("starting locktest6\n");
2251 printf("Testing %s\n", fname
[i
]);
2253 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2255 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2256 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2257 cli_close(cli
, fnum
);
2258 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2260 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2261 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2262 cli_close(cli
, fnum
);
2263 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2265 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2268 torture_close_connection(cli
);
2270 printf("finished locktest6\n");
2274 static bool run_locktest7(int dummy
)
2276 struct cli_state
*cli1
;
2277 const char *fname
= "\\lockt7.lck";
2280 bool correct
= False
;
2284 if (!torture_open_connection(&cli1
, 0)) {
2288 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2290 printf("starting locktest7\n");
2292 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2294 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2296 memset(buf
, 0, sizeof(buf
));
2298 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2300 if (!NT_STATUS_IS_OK(status
)) {
2301 printf("Failed to create file: %s\n", nt_errstr(status
));
2305 cli_setpid(cli1
, 1);
2307 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2308 if (!NT_STATUS_IS_OK(status
)) {
2309 printf("Unable to apply read lock on range 130:4, "
2310 "error was %s\n", nt_errstr(status
));
2313 printf("pid1 successfully locked range 130:4 for READ\n");
2316 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2317 if (!NT_STATUS_IS_OK(status
)) {
2318 printf("pid1 unable to read the range 130:4, error was %s\n",
2321 } else if (nread
!= 4) {
2322 printf("pid1 unable to read the range 130:4, "
2323 "recv %ld req %d\n", (unsigned long)nread
, 4);
2326 printf("pid1 successfully read the range 130:4\n");
2329 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2330 if (!NT_STATUS_IS_OK(status
)) {
2331 printf("pid1 unable to write to the range 130:4, error was "
2332 "%s\n", nt_errstr(status
));
2333 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2334 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2338 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2342 cli_setpid(cli1
, 2);
2344 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2345 if (!NT_STATUS_IS_OK(status
)) {
2346 printf("pid2 unable to read the range 130:4, error was %s\n",
2349 } else if (nread
!= 4) {
2350 printf("pid2 unable to read the range 130:4, "
2351 "recv %ld req %d\n", (unsigned long)nread
, 4);
2354 printf("pid2 successfully read the range 130:4\n");
2357 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2358 if (!NT_STATUS_IS_OK(status
)) {
2359 printf("pid2 unable to write to the range 130:4, error was "
2360 "%s\n", nt_errstr(status
));
2361 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2362 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2366 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2370 cli_setpid(cli1
, 1);
2371 cli_unlock(cli1
, fnum1
, 130, 4);
2373 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2374 if (!NT_STATUS_IS_OK(status
)) {
2375 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2378 printf("pid1 successfully locked range 130:4 for WRITE\n");
2381 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2382 if (!NT_STATUS_IS_OK(status
)) {
2383 printf("pid1 unable to read the range 130:4, error was %s\n",
2386 } else if (nread
!= 4) {
2387 printf("pid1 unable to read the range 130:4, "
2388 "recv %ld req %d\n", (unsigned long)nread
, 4);
2391 printf("pid1 successfully read the range 130:4\n");
2394 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2395 if (!NT_STATUS_IS_OK(status
)) {
2396 printf("pid1 unable to write to the range 130:4, error was "
2397 "%s\n", nt_errstr(status
));
2400 printf("pid1 successfully wrote to the range 130:4\n");
2403 cli_setpid(cli1
, 2);
2405 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2406 if (!NT_STATUS_IS_OK(status
)) {
2407 printf("pid2 unable to read the range 130:4, error was "
2408 "%s\n", nt_errstr(status
));
2409 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2410 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2414 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2415 (unsigned long)nread
);
2419 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2420 if (!NT_STATUS_IS_OK(status
)) {
2421 printf("pid2 unable to write to the range 130:4, error was "
2422 "%s\n", nt_errstr(status
));
2423 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2424 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2428 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2432 cli_unlock(cli1
, fnum1
, 130, 0);
2436 cli_close(cli1
, fnum1
);
2437 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2438 torture_close_connection(cli1
);
2440 printf("finished locktest7\n");
2445 * This demonstrates a problem with our use of GPFS share modes: A file
2446 * descriptor sitting in the pending close queue holding a GPFS share mode
2447 * blocks opening a file another time. Happens with Word 2007 temp files.
2448 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2449 * open is denied with NT_STATUS_SHARING_VIOLATION.
2452 static bool run_locktest8(int dummy
)
2454 struct cli_state
*cli1
;
2455 const char *fname
= "\\lockt8.lck";
2456 uint16_t fnum1
, fnum2
;
2458 bool correct
= False
;
2461 if (!torture_open_connection(&cli1
, 0)) {
2465 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2467 printf("starting locktest8\n");
2469 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2471 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2473 if (!NT_STATUS_IS_OK(status
)) {
2474 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2478 memset(buf
, 0, sizeof(buf
));
2480 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2481 if (!NT_STATUS_IS_OK(status
)) {
2482 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2487 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2488 if (!NT_STATUS_IS_OK(status
)) {
2489 printf("Unable to apply read lock on range 1:1, error was "
2490 "%s\n", nt_errstr(status
));
2494 status
= cli_close(cli1
, fnum1
);
2495 if (!NT_STATUS_IS_OK(status
)) {
2496 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2500 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2501 if (!NT_STATUS_IS_OK(status
)) {
2502 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2510 cli_close(cli1
, fnum1
);
2511 cli_close(cli1
, fnum2
);
2512 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2513 torture_close_connection(cli1
);
2515 printf("finished locktest8\n");
2520 * This test is designed to be run in conjunction with
2521 * external NFS or POSIX locks taken in the filesystem.
2522 * It checks that the smbd server will block until the
2523 * lock is released and then acquire it. JRA.
2526 static bool got_alarm
;
2527 static struct cli_state
*alarm_cli
;
2529 static void alarm_handler(int dummy
)
2534 static void alarm_handler_parent(int dummy
)
2536 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_OK
);
2539 static void do_local_lock(int read_fd
, int write_fd
)
2544 const char *local_pathname
= NULL
;
2547 local_pathname
= talloc_asprintf(talloc_tos(),
2548 "%s/lockt9.lck", local_path
);
2549 if (!local_pathname
) {
2550 printf("child: alloc fail\n");
2554 unlink(local_pathname
);
2555 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2557 printf("child: open of %s failed %s.\n",
2558 local_pathname
, strerror(errno
));
2562 /* Now take a fcntl lock. */
2563 lock
.l_type
= F_WRLCK
;
2564 lock
.l_whence
= SEEK_SET
;
2567 lock
.l_pid
= getpid();
2569 ret
= fcntl(fd
,F_SETLK
,&lock
);
2571 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2572 local_pathname
, strerror(errno
));
2575 printf("child: got lock 0:4 on file %s.\n",
2580 CatchSignal(SIGALRM
, alarm_handler
);
2582 /* Signal the parent. */
2583 if (write(write_fd
, &c
, 1) != 1) {
2584 printf("child: start signal fail %s.\n",
2591 /* Wait for the parent to be ready. */
2592 if (read(read_fd
, &c
, 1) != 1) {
2593 printf("child: reply signal fail %s.\n",
2601 printf("child: released lock 0:4 on file %s.\n",
2607 static bool run_locktest9(int dummy
)
2609 struct cli_state
*cli1
;
2610 const char *fname
= "\\lockt9.lck";
2612 bool correct
= False
;
2613 int pipe_in
[2], pipe_out
[2];
2617 struct timeval start
;
2621 printf("starting locktest9\n");
2623 if (local_path
== NULL
) {
2624 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2628 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2633 if (child_pid
== -1) {
2637 if (child_pid
== 0) {
2639 do_local_lock(pipe_out
[0], pipe_in
[1]);
2649 ret
= read(pipe_in
[0], &c
, 1);
2651 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2656 if (!torture_open_connection(&cli1
, 0)) {
2660 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2662 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
,
2664 if (!NT_STATUS_IS_OK(status
)) {
2665 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2669 /* Ensure the child has the lock. */
2670 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2671 if (NT_STATUS_IS_OK(status
)) {
2672 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2675 d_printf("Child has the lock.\n");
2678 /* Tell the child to wait 5 seconds then exit. */
2679 ret
= write(pipe_out
[1], &c
, 1);
2681 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2686 /* Wait 20 seconds for the lock. */
2688 CatchSignal(SIGALRM
, alarm_handler_parent
);
2691 start
= timeval_current();
2693 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2694 if (!NT_STATUS_IS_OK(status
)) {
2695 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2696 "%s\n", nt_errstr(status
));
2701 seconds
= timeval_elapsed(&start
);
2703 printf("Parent got the lock after %.2f seconds.\n",
2706 status
= cli_close(cli1
, fnum
);
2707 if (!NT_STATUS_IS_OK(status
)) {
2708 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2715 cli_close(cli1
, fnum
);
2716 torture_close_connection(cli1
);
2720 printf("finished locktest9\n");
2725 test whether fnums and tids open on one VC are available on another (a major
2728 static bool run_fdpasstest(int dummy
)
2730 struct cli_state
*cli1
, *cli2
;
2731 const char *fname
= "\\fdpass.tst";
2736 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2739 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2740 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2742 printf("starting fdpasstest\n");
2744 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2746 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2748 if (!NT_STATUS_IS_OK(status
)) {
2749 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2753 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2755 if (!NT_STATUS_IS_OK(status
)) {
2756 printf("write failed (%s)\n", nt_errstr(status
));
2760 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2761 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2762 cli_setpid(cli2
, cli_getpid(cli1
));
2764 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2765 printf("read succeeded! nasty security hole [%s]\n", buf
);
2769 cli_close(cli1
, fnum1
);
2770 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2772 torture_close_connection(cli1
);
2773 torture_close_connection(cli2
);
2775 printf("finished fdpasstest\n");
2779 static bool run_fdsesstest(int dummy
)
2781 struct cli_state
*cli
;
2783 uint16_t saved_vuid
;
2785 uint32_t saved_cnum
;
2786 const char *fname
= "\\fdsess.tst";
2787 const char *fname1
= "\\fdsess1.tst";
2794 if (!torture_open_connection(&cli
, 0))
2796 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2798 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2801 saved_cnum
= cli_state_get_tid(cli
);
2802 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", NULL
)))
2804 new_cnum
= cli_state_get_tid(cli
);
2805 cli_state_set_tid(cli
, saved_cnum
);
2807 printf("starting fdsesstest\n");
2809 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2810 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2812 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2813 if (!NT_STATUS_IS_OK(status
)) {
2814 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2818 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2820 if (!NT_STATUS_IS_OK(status
)) {
2821 printf("write failed (%s)\n", nt_errstr(status
));
2825 saved_vuid
= cli_state_get_uid(cli
);
2826 cli_state_set_uid(cli
, new_vuid
);
2828 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2829 printf("read succeeded with different vuid! "
2830 "nasty security hole [%s]\n", buf
);
2833 /* Try to open a file with different vuid, samba cnum. */
2834 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2835 printf("create with different vuid, same cnum succeeded.\n");
2836 cli_close(cli
, fnum2
);
2837 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2839 printf("create with different vuid, same cnum failed.\n");
2840 printf("This will cause problems with service clients.\n");
2844 cli_state_set_uid(cli
, saved_vuid
);
2846 /* Try with same vuid, different cnum. */
2847 cli_state_set_tid(cli
, new_cnum
);
2849 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2850 printf("read succeeded with different cnum![%s]\n", buf
);
2854 cli_state_set_tid(cli
, saved_cnum
);
2855 cli_close(cli
, fnum1
);
2856 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2858 torture_close_connection(cli
);
2860 printf("finished fdsesstest\n");
2865 This test checks that
2867 1) the server does not allow an unlink on a file that is open
2869 static bool run_unlinktest(int dummy
)
2871 struct cli_state
*cli
;
2872 const char *fname
= "\\unlink.tst";
2874 bool correct
= True
;
2877 if (!torture_open_connection(&cli
, 0)) {
2881 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2883 printf("starting unlink test\n");
2885 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2889 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2890 if (!NT_STATUS_IS_OK(status
)) {
2891 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2895 status
= cli_unlink(cli
, fname
,
2896 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2897 if (NT_STATUS_IS_OK(status
)) {
2898 printf("error: server allowed unlink on an open file\n");
2901 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2902 NT_STATUS_SHARING_VIOLATION
);
2905 cli_close(cli
, fnum
);
2906 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2908 if (!torture_close_connection(cli
)) {
2912 printf("unlink test finished\n");
2919 test how many open files this server supports on the one socket
2921 static bool run_maxfidtest(int dummy
)
2923 struct cli_state
*cli
;
2925 uint16_t fnums
[0x11000];
2928 bool correct
= True
;
2934 printf("failed to connect\n");
2938 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2940 for (i
=0; i
<0x11000; i
++) {
2941 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2942 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2944 if (!NT_STATUS_IS_OK(status
)) {
2945 printf("open of %s failed (%s)\n",
2946 fname
, nt_errstr(status
));
2947 printf("maximum fnum is %d\n", i
);
2955 printf("cleaning up\n");
2957 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2958 cli_close(cli
, fnums
[i
]);
2960 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2961 if (!NT_STATUS_IS_OK(status
)) {
2962 printf("unlink of %s failed (%s)\n",
2963 fname
, nt_errstr(status
));
2970 printf("maxfid test finished\n");
2971 if (!torture_close_connection(cli
)) {
2977 /* generate a random buffer */
2978 static void rand_buf(char *buf
, int len
)
2981 *buf
= (char)sys_random();
2986 /* send smb negprot commands, not reading the response */
2987 static bool run_negprot_nowait(int dummy
)
2989 struct tevent_context
*ev
;
2991 struct cli_state
*cli
;
2992 bool correct
= True
;
2994 printf("starting negprot nowait test\n");
2996 ev
= samba_tevent_context_init(talloc_tos());
3001 if (!(cli
= open_nbt_connection())) {
3006 for (i
=0;i
<50000;i
++) {
3007 struct tevent_req
*req
;
3009 req
= smbXcli_negprot_send(ev
, ev
, cli
->conn
, cli
->timeout
,
3010 PROTOCOL_CORE
, PROTOCOL_NT1
, 0);
3015 if (!tevent_req_poll(req
, ev
)) {
3016 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3024 if (torture_close_connection(cli
)) {
3028 printf("finished negprot nowait test\n");
3033 /* send smb negprot commands, not reading the response */
3034 static bool run_bad_nbt_session(int dummy
)
3036 struct nmb_name called
, calling
;
3037 struct sockaddr_storage ss
;
3042 printf("starting bad nbt session test\n");
3044 make_nmb_name(&calling
, myname
, 0x0);
3045 make_nmb_name(&called
, host
, 0x20);
3047 if (!resolve_name(host
, &ss
, 0x20, true)) {
3048 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3052 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
3053 if (!NT_STATUS_IS_OK(status
)) {
3054 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3059 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3062 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3067 printf("finished bad nbt session test\n");
3071 /* send random IPC commands */
3072 static bool run_randomipc(int dummy
)
3074 char *rparam
= NULL
;
3076 unsigned int rdrcnt
,rprcnt
;
3078 int api
, param_len
, i
;
3079 struct cli_state
*cli
;
3080 bool correct
= True
;
3083 printf("starting random ipc test\n");
3085 if (!torture_open_connection(&cli
, 0)) {
3089 for (i
=0;i
<count
;i
++) {
3090 api
= sys_random() % 500;
3091 param_len
= (sys_random() % 64);
3093 rand_buf(param
, param_len
);
3098 param
, param_len
, 8,
3099 NULL
, 0, CLI_BUFFER_SIZE
,
3103 printf("%d/%d\r", i
,count
);
3106 printf("%d/%d\n", i
, count
);
3108 if (!torture_close_connection(cli
)) {
3115 printf("finished random ipc test\n");
3122 static void browse_callback(const char *sname
, uint32_t stype
,
3123 const char *comment
, void *state
)
3125 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3131 This test checks the browse list code
3134 static bool run_browsetest(int dummy
)
3136 static struct cli_state
*cli
;
3137 bool correct
= True
;
3139 printf("starting browse test\n");
3141 if (!torture_open_connection(&cli
, 0)) {
3145 printf("domain list:\n");
3146 cli_NetServerEnum(cli
, cli
->server_domain
,
3147 SV_TYPE_DOMAIN_ENUM
,
3148 browse_callback
, NULL
);
3150 printf("machine list:\n");
3151 cli_NetServerEnum(cli
, cli
->server_domain
,
3153 browse_callback
, NULL
);
3155 if (!torture_close_connection(cli
)) {
3159 printf("browse test finished\n");
3167 This checks how the getatr calls works
3169 static bool run_attrtest(int dummy
)
3171 struct cli_state
*cli
;
3174 const char *fname
= "\\attrib123456789.tst";
3175 bool correct
= True
;
3178 printf("starting attrib test\n");
3180 if (!torture_open_connection(&cli
, 0)) {
3184 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3185 cli_openx(cli
, fname
,
3186 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3187 cli_close(cli
, fnum
);
3189 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3190 if (!NT_STATUS_IS_OK(status
)) {
3191 printf("getatr failed (%s)\n", nt_errstr(status
));
3195 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3196 printf("ERROR: SMBgetatr bug. time is %s",
3202 t2
= t
-60*60*24; /* 1 day ago */
3204 status
= cli_setatr(cli
, fname
, 0, t2
);
3205 if (!NT_STATUS_IS_OK(status
)) {
3206 printf("setatr failed (%s)\n", nt_errstr(status
));
3210 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3211 if (!NT_STATUS_IS_OK(status
)) {
3212 printf("getatr failed (%s)\n", nt_errstr(status
));
3217 printf("ERROR: getatr/setatr bug. times are\n%s",
3219 printf("%s", ctime(&t2
));
3223 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3225 if (!torture_close_connection(cli
)) {
3229 printf("attrib test finished\n");
3236 This checks a couple of trans2 calls
3238 static bool run_trans2test(int dummy
)
3240 struct cli_state
*cli
;
3243 time_t c_time
, a_time
, m_time
;
3244 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3245 const char *fname
= "\\trans2.tst";
3246 const char *dname
= "\\trans2";
3247 const char *fname2
= "\\trans2\\trans2.tst";
3249 bool correct
= True
;
3253 printf("starting trans2 test\n");
3255 if (!torture_open_connection(&cli
, 0)) {
3259 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3260 if (!NT_STATUS_IS_OK(status
)) {
3261 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3266 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3267 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3268 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3269 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3270 if (!NT_STATUS_IS_OK(status
)) {
3271 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3275 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3276 if (!NT_STATUS_IS_OK(status
)) {
3277 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3280 else if (strcmp(pname
, fname
)) {
3281 printf("qfilename gave different name? [%s] [%s]\n",
3286 cli_close(cli
, fnum
);
3290 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3291 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3293 if (!NT_STATUS_IS_OK(status
)) {
3294 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3297 cli_close(cli
, fnum
);
3299 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3301 if (!NT_STATUS_IS_OK(status
)) {
3302 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3305 time_t t
= time(NULL
);
3307 if (c_time
!= m_time
) {
3308 printf("create time=%s", ctime(&c_time
));
3309 printf("modify time=%s", ctime(&m_time
));
3310 printf("This system appears to have sticky create times\n");
3312 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3313 printf("access time=%s", ctime(&a_time
));
3314 printf("This system appears to set a midnight access time\n");
3318 if (abs(m_time
- t
) > 60*60*24*7) {
3319 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3325 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3326 cli_openx(cli
, fname
,
3327 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3328 cli_close(cli
, fnum
);
3329 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3330 &m_time_ts
, &size
, NULL
, NULL
);
3331 if (!NT_STATUS_IS_OK(status
)) {
3332 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3335 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3336 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3337 printf("This system appears to set a initial 0 write time\n");
3342 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3345 /* check if the server updates the directory modification time
3346 when creating a new file */
3347 status
= cli_mkdir(cli
, dname
);
3348 if (!NT_STATUS_IS_OK(status
)) {
3349 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3353 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3354 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3355 if (!NT_STATUS_IS_OK(status
)) {
3356 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3360 cli_openx(cli
, fname2
,
3361 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3362 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3363 cli_close(cli
, fnum
);
3364 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3365 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3366 if (!NT_STATUS_IS_OK(status
)) {
3367 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3370 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3372 printf("This system does not update directory modification times\n");
3376 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3377 cli_rmdir(cli
, dname
);
3379 if (!torture_close_connection(cli
)) {
3383 printf("trans2 test finished\n");
3389 This checks new W2K calls.
3392 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3394 uint8_t *buf
= NULL
;
3398 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3399 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3400 if (!NT_STATUS_IS_OK(status
)) {
3401 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3404 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3405 dump_data(0, (uint8_t *)buf
, len
);
3412 static bool run_w2ktest(int dummy
)
3414 struct cli_state
*cli
;
3416 const char *fname
= "\\w2ktest\\w2k.tst";
3418 bool correct
= True
;
3420 printf("starting w2k test\n");
3422 if (!torture_open_connection(&cli
, 0)) {
3426 cli_openx(cli
, fname
,
3427 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3429 for (level
= 1004; level
< 1040; level
++) {
3430 new_trans(cli
, fnum
, level
);
3433 cli_close(cli
, fnum
);
3435 if (!torture_close_connection(cli
)) {
3439 printf("w2k test finished\n");
3446 this is a harness for some oplock tests
3448 static bool run_oplock1(int dummy
)
3450 struct cli_state
*cli1
;
3451 const char *fname
= "\\lockt1.lck";
3453 bool correct
= True
;
3456 printf("starting oplock test 1\n");
3458 if (!torture_open_connection(&cli1
, 0)) {
3462 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3464 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3466 cli1
->use_oplocks
= True
;
3468 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3470 if (!NT_STATUS_IS_OK(status
)) {
3471 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3475 cli1
->use_oplocks
= False
;
3477 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3478 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3480 status
= cli_close(cli1
, fnum1
);
3481 if (!NT_STATUS_IS_OK(status
)) {
3482 printf("close2 failed (%s)\n", nt_errstr(status
));
3486 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3487 if (!NT_STATUS_IS_OK(status
)) {
3488 printf("unlink failed (%s)\n", nt_errstr(status
));
3492 if (!torture_close_connection(cli1
)) {
3496 printf("finished oplock test 1\n");
3501 static bool run_oplock2(int dummy
)
3503 struct cli_state
*cli1
, *cli2
;
3504 const char *fname
= "\\lockt2.lck";
3505 uint16_t fnum1
, fnum2
;
3506 int saved_use_oplocks
= use_oplocks
;
3508 bool correct
= True
;
3509 volatile bool *shared_correct
;
3513 shared_correct
= (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3514 *shared_correct
= True
;
3516 use_level_II_oplocks
= True
;
3519 printf("starting oplock test 2\n");
3521 if (!torture_open_connection(&cli1
, 0)) {
3522 use_level_II_oplocks
= False
;
3523 use_oplocks
= saved_use_oplocks
;
3527 if (!torture_open_connection(&cli2
, 1)) {
3528 use_level_II_oplocks
= False
;
3529 use_oplocks
= saved_use_oplocks
;
3533 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3535 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3536 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3538 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3540 if (!NT_STATUS_IS_OK(status
)) {
3541 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3545 /* Don't need the globals any more. */
3546 use_level_II_oplocks
= False
;
3547 use_oplocks
= saved_use_oplocks
;
3551 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3552 if (!NT_STATUS_IS_OK(status
)) {
3553 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3554 *shared_correct
= False
;
3560 status
= cli_close(cli2
, fnum2
);
3561 if (!NT_STATUS_IS_OK(status
)) {
3562 printf("close2 failed (%s)\n", nt_errstr(status
));
3563 *shared_correct
= False
;
3571 /* Ensure cli1 processes the break. Empty file should always return 0
3573 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3574 if (!NT_STATUS_IS_OK(status
)) {
3575 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3577 } else if (nread
!= 0) {
3578 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3579 (unsigned long)nread
, 0);
3583 /* Should now be at level II. */
3584 /* Test if sending a write locks causes a break to none. */
3585 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3586 if (!NT_STATUS_IS_OK(status
)) {
3587 printf("lock failed (%s)\n", nt_errstr(status
));
3591 cli_unlock(cli1
, fnum1
, 0, 4);
3595 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3596 if (!NT_STATUS_IS_OK(status
)) {
3597 printf("lock failed (%s)\n", nt_errstr(status
));
3601 cli_unlock(cli1
, fnum1
, 0, 4);
3605 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3607 status
= cli_close(cli1
, fnum1
);
3608 if (!NT_STATUS_IS_OK(status
)) {
3609 printf("close1 failed (%s)\n", nt_errstr(status
));
3615 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3616 if (!NT_STATUS_IS_OK(status
)) {
3617 printf("unlink failed (%s)\n", nt_errstr(status
));
3621 if (!torture_close_connection(cli1
)) {
3625 if (!*shared_correct
) {
3629 printf("finished oplock test 2\n");
3634 struct oplock4_state
{
3635 struct tevent_context
*ev
;
3636 struct cli_state
*cli
;
3641 static void oplock4_got_break(struct tevent_req
*req
);
3642 static void oplock4_got_open(struct tevent_req
*req
);
3644 static bool run_oplock4(int dummy
)
3646 struct tevent_context
*ev
;
3647 struct cli_state
*cli1
, *cli2
;
3648 struct tevent_req
*oplock_req
, *open_req
;
3649 const char *fname
= "\\lockt4.lck";
3650 const char *fname_ln
= "\\lockt4_ln.lck";
3651 uint16_t fnum1
, fnum2
;
3652 int saved_use_oplocks
= use_oplocks
;
3654 bool correct
= true;
3658 struct oplock4_state
*state
;
3660 printf("starting oplock test 4\n");
3662 if (!torture_open_connection(&cli1
, 0)) {
3663 use_level_II_oplocks
= false;
3664 use_oplocks
= saved_use_oplocks
;
3668 if (!torture_open_connection(&cli2
, 1)) {
3669 use_level_II_oplocks
= false;
3670 use_oplocks
= saved_use_oplocks
;
3674 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3675 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3677 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3678 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3680 /* Create the file. */
3681 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3683 if (!NT_STATUS_IS_OK(status
)) {
3684 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3688 status
= cli_close(cli1
, fnum1
);
3689 if (!NT_STATUS_IS_OK(status
)) {
3690 printf("close1 failed (%s)\n", nt_errstr(status
));
3694 /* Now create a hardlink. */
3695 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3696 if (!NT_STATUS_IS_OK(status
)) {
3697 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3701 /* Prove that opening hardlinks cause deny modes to conflict. */
3702 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3703 if (!NT_STATUS_IS_OK(status
)) {
3704 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3708 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3709 if (NT_STATUS_IS_OK(status
)) {
3710 printf("open of %s succeeded - should fail with sharing violation.\n",
3715 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3716 printf("open of %s should fail with sharing violation. Got %s\n",
3717 fname_ln
, nt_errstr(status
));
3721 status
= cli_close(cli1
, fnum1
);
3722 if (!NT_STATUS_IS_OK(status
)) {
3723 printf("close1 failed (%s)\n", nt_errstr(status
));
3727 cli1
->use_oplocks
= true;
3728 cli2
->use_oplocks
= true;
3730 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3731 if (!NT_STATUS_IS_OK(status
)) {
3732 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3736 ev
= samba_tevent_context_init(talloc_tos());
3738 printf("tevent_context_init failed\n");
3742 state
= talloc(ev
, struct oplock4_state
);
3743 if (state
== NULL
) {
3744 printf("talloc failed\n");
3749 state
->got_break
= &got_break
;
3750 state
->fnum2
= &fnum2
;
3752 oplock_req
= cli_smb_oplock_break_waiter_send(
3753 talloc_tos(), ev
, cli1
);
3754 if (oplock_req
== NULL
) {
3755 printf("cli_smb_oplock_break_waiter_send failed\n");
3758 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3760 open_req
= cli_openx_send(
3761 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3762 if (open_req
== NULL
) {
3763 printf("cli_openx_send failed\n");
3766 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3771 while (!got_break
|| fnum2
== 0xffff) {
3773 ret
= tevent_loop_once(ev
);
3775 printf("tevent_loop_once failed: %s\n",
3781 status
= cli_close(cli2
, fnum2
);
3782 if (!NT_STATUS_IS_OK(status
)) {
3783 printf("close2 failed (%s)\n", nt_errstr(status
));
3787 status
= cli_close(cli1
, fnum1
);
3788 if (!NT_STATUS_IS_OK(status
)) {
3789 printf("close1 failed (%s)\n", nt_errstr(status
));
3793 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3794 if (!NT_STATUS_IS_OK(status
)) {
3795 printf("unlink failed (%s)\n", nt_errstr(status
));
3799 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3800 if (!NT_STATUS_IS_OK(status
)) {
3801 printf("unlink failed (%s)\n", nt_errstr(status
));
3805 if (!torture_close_connection(cli1
)) {
3813 printf("finished oplock test 4\n");
3818 static void oplock4_got_break(struct tevent_req
*req
)
3820 struct oplock4_state
*state
= tevent_req_callback_data(
3821 req
, struct oplock4_state
);
3826 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3828 if (!NT_STATUS_IS_OK(status
)) {
3829 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3833 *state
->got_break
= true;
3835 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3838 printf("cli_oplock_ack_send failed\n");
3843 static void oplock4_got_open(struct tevent_req
*req
)
3845 struct oplock4_state
*state
= tevent_req_callback_data(
3846 req
, struct oplock4_state
);
3849 status
= cli_openx_recv(req
, state
->fnum2
);
3850 if (!NT_STATUS_IS_OK(status
)) {
3851 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
3852 *state
->fnum2
= 0xffff;
3857 Test delete on close semantics.
3859 static bool run_deletetest(int dummy
)
3861 struct cli_state
*cli1
= NULL
;
3862 struct cli_state
*cli2
= NULL
;
3863 const char *fname
= "\\delete.file";
3864 uint16_t fnum1
= (uint16_t)-1;
3865 uint16_t fnum2
= (uint16_t)-1;
3866 bool correct
= false;
3869 printf("starting delete test\n");
3871 if (!torture_open_connection(&cli1
, 0)) {
3875 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3877 /* Test 1 - this should delete the file on close. */
3879 cli_setatr(cli1
, fname
, 0, 0);
3880 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3882 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3883 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3884 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
3885 if (!NT_STATUS_IS_OK(status
)) {
3886 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3890 status
= cli_close(cli1
, fnum1
);
3891 if (!NT_STATUS_IS_OK(status
)) {
3892 printf("[1] close failed (%s)\n", nt_errstr(status
));
3896 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3897 if (NT_STATUS_IS_OK(status
)) {
3898 printf("[1] open of %s succeeded (should fail)\n", fname
);
3902 printf("first delete on close test succeeded.\n");
3904 /* Test 2 - this should delete the file on close. */
3906 cli_setatr(cli1
, fname
, 0, 0);
3907 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3909 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3910 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3911 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3912 if (!NT_STATUS_IS_OK(status
)) {
3913 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3917 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3918 if (!NT_STATUS_IS_OK(status
)) {
3919 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3923 status
= cli_close(cli1
, fnum1
);
3924 if (!NT_STATUS_IS_OK(status
)) {
3925 printf("[2] close failed (%s)\n", nt_errstr(status
));
3929 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3930 if (NT_STATUS_IS_OK(status
)) {
3931 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3932 status
= cli_close(cli1
, fnum1
);
3933 if (!NT_STATUS_IS_OK(status
)) {
3934 printf("[2] close failed (%s)\n", nt_errstr(status
));
3936 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3940 printf("second delete on close test succeeded.\n");
3943 cli_setatr(cli1
, fname
, 0, 0);
3944 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3946 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3947 FILE_ATTRIBUTE_NORMAL
,
3948 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3949 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3950 if (!NT_STATUS_IS_OK(status
)) {
3951 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
3955 /* This should fail with a sharing violation - open for delete is only compatible
3956 with SHARE_DELETE. */
3958 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3959 FILE_ATTRIBUTE_NORMAL
,
3960 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3961 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3962 if (NT_STATUS_IS_OK(status
)) {
3963 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3967 /* This should succeed. */
3968 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3969 FILE_ATTRIBUTE_NORMAL
,
3970 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3971 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3972 if (!NT_STATUS_IS_OK(status
)) {
3973 printf("[3] open - 3 of %s failed (%s)\n", fname
, nt_errstr(status
));
3977 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3978 if (!NT_STATUS_IS_OK(status
)) {
3979 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3983 status
= cli_close(cli1
, fnum1
);
3984 if (!NT_STATUS_IS_OK(status
)) {
3985 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
3989 status
= cli_close(cli1
, fnum2
);
3990 if (!NT_STATUS_IS_OK(status
)) {
3991 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
3995 /* This should fail - file should no longer be there. */
3997 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3998 if (NT_STATUS_IS_OK(status
)) {
3999 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4000 status
= cli_close(cli1
, fnum1
);
4001 if (!NT_STATUS_IS_OK(status
)) {
4002 printf("[3] close failed (%s)\n", nt_errstr(status
));
4004 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4008 printf("third delete on close test succeeded.\n");
4011 cli_setatr(cli1
, fname
, 0, 0);
4012 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4014 status
= cli_ntcreate(cli1
, fname
, 0,
4015 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4016 FILE_ATTRIBUTE_NORMAL
,
4017 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4018 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4019 if (!NT_STATUS_IS_OK(status
)) {
4020 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4024 /* This should succeed. */
4025 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4026 FILE_ATTRIBUTE_NORMAL
,
4027 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4028 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4029 if (!NT_STATUS_IS_OK(status
)) {
4030 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4034 status
= cli_close(cli1
, fnum2
);
4035 if (!NT_STATUS_IS_OK(status
)) {
4036 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4040 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4041 if (!NT_STATUS_IS_OK(status
)) {
4042 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4046 /* This should fail - no more opens once delete on close set. */
4047 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4048 FILE_ATTRIBUTE_NORMAL
,
4049 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4050 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4051 if (NT_STATUS_IS_OK(status
)) {
4052 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4056 status
= cli_close(cli1
, fnum1
);
4057 if (!NT_STATUS_IS_OK(status
)) {
4058 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4062 printf("fourth delete on close test succeeded.\n");
4065 cli_setatr(cli1
, fname
, 0, 0);
4066 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4068 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4069 if (!NT_STATUS_IS_OK(status
)) {
4070 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4074 /* This should fail - only allowed on NT opens with DELETE access. */
4076 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4077 if (NT_STATUS_IS_OK(status
)) {
4078 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4082 status
= cli_close(cli1
, fnum1
);
4083 if (!NT_STATUS_IS_OK(status
)) {
4084 printf("[5] close failed (%s)\n", nt_errstr(status
));
4088 printf("fifth delete on close test succeeded.\n");
4091 cli_setatr(cli1
, fname
, 0, 0);
4092 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4094 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4095 FILE_ATTRIBUTE_NORMAL
,
4096 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4097 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4098 if (!NT_STATUS_IS_OK(status
)) {
4099 printf("[6] open of %s failed (%s)\n", fname
,
4104 /* This should fail - only allowed on NT opens with DELETE access. */
4106 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4107 if (NT_STATUS_IS_OK(status
)) {
4108 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4112 status
= cli_close(cli1
, fnum1
);
4113 if (!NT_STATUS_IS_OK(status
)) {
4114 printf("[6] close failed (%s)\n", nt_errstr(status
));
4118 printf("sixth delete on close test succeeded.\n");
4121 cli_setatr(cli1
, fname
, 0, 0);
4122 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4124 status
= cli_ntcreate(cli1
, fname
, 0,
4125 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4126 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4127 0, 0, &fnum1
, NULL
);
4128 if (!NT_STATUS_IS_OK(status
)) {
4129 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4133 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4134 if (!NT_STATUS_IS_OK(status
)) {
4135 printf("[7] setting delete_on_close on file failed !\n");
4139 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4140 if (!NT_STATUS_IS_OK(status
)) {
4141 printf("[7] unsetting delete_on_close on file failed !\n");
4145 status
= cli_close(cli1
, fnum1
);
4146 if (!NT_STATUS_IS_OK(status
)) {
4147 printf("[7] close - 1 failed (%s)\n", nt_errstr(status
));
4151 /* This next open should succeed - we reset the flag. */
4152 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4153 if (!NT_STATUS_IS_OK(status
)) {
4154 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4158 status
= cli_close(cli1
, fnum1
);
4159 if (!NT_STATUS_IS_OK(status
)) {
4160 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4164 printf("seventh delete on close test succeeded.\n");
4167 cli_setatr(cli1
, fname
, 0, 0);
4168 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4170 if (!torture_open_connection(&cli2
, 1)) {
4171 printf("[8] failed to open second connection.\n");
4175 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4177 status
= cli_ntcreate(cli1
, fname
, 0,
4178 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4179 FILE_ATTRIBUTE_NORMAL
,
4180 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4181 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4182 if (!NT_STATUS_IS_OK(status
)) {
4183 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4187 status
= cli_ntcreate(cli2
, fname
, 0,
4188 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4189 FILE_ATTRIBUTE_NORMAL
,
4190 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4191 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4192 if (!NT_STATUS_IS_OK(status
)) {
4193 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4197 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4198 if (!NT_STATUS_IS_OK(status
)) {
4199 printf("[8] setting delete_on_close on file failed !\n");
4203 status
= cli_close(cli1
, fnum1
);
4204 if (!NT_STATUS_IS_OK(status
)) {
4205 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4209 status
= cli_close(cli2
, fnum2
);
4210 if (!NT_STATUS_IS_OK(status
)) {
4211 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4215 /* This should fail.. */
4216 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4217 if (NT_STATUS_IS_OK(status
)) {
4218 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4222 printf("eighth delete on close test succeeded.\n");
4226 /* This should fail - we need to set DELETE_ACCESS. */
4227 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4228 FILE_ATTRIBUTE_NORMAL
,
4231 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4232 if (NT_STATUS_IS_OK(status
)) {
4233 printf("[9] open of %s succeeded should have failed!\n", fname
);
4237 printf("ninth delete on close test succeeded.\n");
4241 status
= cli_ntcreate(cli1
, fname
, 0,
4242 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4243 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4244 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4246 if (!NT_STATUS_IS_OK(status
)) {
4247 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4251 /* This should delete the file. */
4252 status
= cli_close(cli1
, fnum1
);
4253 if (!NT_STATUS_IS_OK(status
)) {
4254 printf("[10] close failed (%s)\n", nt_errstr(status
));
4258 /* This should fail.. */
4259 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4260 if (NT_STATUS_IS_OK(status
)) {
4261 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4265 printf("tenth delete on close test succeeded.\n");
4269 cli_setatr(cli1
, fname
, 0, 0);
4270 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4272 /* Can we open a read-only file with delete access? */
4274 /* Create a readonly file. */
4275 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4276 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4277 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4278 if (!NT_STATUS_IS_OK(status
)) {
4279 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4283 status
= cli_close(cli1
, fnum1
);
4284 if (!NT_STATUS_IS_OK(status
)) {
4285 printf("[11] close failed (%s)\n", nt_errstr(status
));
4289 /* Now try open for delete access. */
4290 status
= cli_ntcreate(cli1
, fname
, 0,
4291 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4293 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4294 FILE_OPEN
, 0, 0, &fnum1
, NULL
);
4295 if (!NT_STATUS_IS_OK(status
)) {
4296 printf("[11] open of %s failed: %s\n", fname
, nt_errstr(status
));
4300 cli_close(cli1
, fnum1
);
4302 printf("eleventh delete on close test succeeded.\n");
4306 * like test 4 but with initial delete on close
4309 cli_setatr(cli1
, fname
, 0, 0);
4310 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4312 status
= cli_ntcreate(cli1
, fname
, 0,
4313 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4314 FILE_ATTRIBUTE_NORMAL
,
4315 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4317 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4318 if (!NT_STATUS_IS_OK(status
)) {
4319 printf("[12] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4323 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4324 FILE_ATTRIBUTE_NORMAL
,
4325 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4326 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4327 if (!NT_STATUS_IS_OK(status
)) {
4328 printf("[12] open 2 of %s failed(%s).\n", fname
, nt_errstr(status
));
4332 status
= cli_close(cli1
, fnum2
);
4333 if (!NT_STATUS_IS_OK(status
)) {
4334 printf("[12] close 1 failed (%s)\n", nt_errstr(status
));
4338 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4339 if (!NT_STATUS_IS_OK(status
)) {
4340 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4344 /* This should fail - no more opens once delete on close set. */
4345 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4346 FILE_ATTRIBUTE_NORMAL
,
4347 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4348 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4349 if (NT_STATUS_IS_OK(status
)) {
4350 printf("[12] open 3 of %s succeeded - should fail).\n", fname
);
4354 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4355 if (!NT_STATUS_IS_OK(status
)) {
4356 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status
));
4360 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4361 FILE_ATTRIBUTE_NORMAL
,
4362 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4363 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4364 if (!NT_STATUS_IS_OK(status
)) {
4365 printf("[12] open 4 of %s failed (%s)\n", fname
, nt_errstr(status
));
4369 status
= cli_close(cli1
, fnum2
);
4370 if (!NT_STATUS_IS_OK(status
)) {
4371 printf("[12] close 2 failed (%s)\n", nt_errstr(status
));
4375 status
= cli_close(cli1
, fnum1
);
4376 if (!NT_STATUS_IS_OK(status
)) {
4377 printf("[12] close 3 failed (%s)\n", nt_errstr(status
));
4382 * setting delete on close on the handle does
4383 * not unset the initial delete on close...
4385 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4386 FILE_ATTRIBUTE_NORMAL
,
4387 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4388 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4389 if (NT_STATUS_IS_OK(status
)) {
4390 printf("[12] open 5 of %s succeeded - should fail).\n", fname
);
4392 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4393 printf("ntcreate returned %s, expected "
4394 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4399 printf("twelfth delete on close test succeeded.\n");
4402 printf("finished delete test\n");
4407 /* FIXME: This will crash if we aborted before cli2 got
4408 * intialized, because these functions don't handle
4409 * uninitialized connections. */
4411 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4412 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4413 cli_setatr(cli1
, fname
, 0, 0);
4414 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4416 if (cli1
&& !torture_close_connection(cli1
)) {
4419 if (cli2
&& !torture_close_connection(cli2
)) {
4427 Test wildcard delete.
4429 static bool run_wild_deletetest(int dummy
)
4431 struct cli_state
*cli
= NULL
;
4432 const char *dname
= "\\WTEST";
4433 const char *fname
= "\\WTEST\\A";
4434 const char *wunlink_name
= "\\WTEST\\*";
4435 uint16_t fnum1
= (uint16_t)-1;
4436 bool correct
= false;
4439 printf("starting wildcard delete test\n");
4441 if (!torture_open_connection(&cli
, 0)) {
4445 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4447 cli_unlink(cli
, fname
, 0);
4448 cli_rmdir(cli
, dname
);
4449 status
= cli_mkdir(cli
, dname
);
4450 if (!NT_STATUS_IS_OK(status
)) {
4451 printf("mkdir of %s failed %s!\n", dname
, nt_errstr(status
));
4454 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDONLY
, DENY_NONE
, &fnum1
);
4455 if (!NT_STATUS_IS_OK(status
)) {
4456 printf("open of %s failed %s!\n", fname
, nt_errstr(status
));
4459 status
= cli_close(cli
, fnum1
);
4463 * Note the unlink attribute-type of zero. This should
4464 * map into FILE_ATTRIBUTE_NORMAL at the server even
4465 * on a wildcard delete.
4468 status
= cli_unlink(cli
, wunlink_name
, 0);
4469 if (!NT_STATUS_IS_OK(status
)) {
4470 printf("unlink of %s failed %s!\n",
4471 wunlink_name
, nt_errstr(status
));
4475 printf("finished wildcard delete test\n");
4481 if (fnum1
!= (uint16_t)-1) cli_close(cli
, fnum1
);
4482 cli_unlink(cli
, fname
, 0);
4483 cli_rmdir(cli
, dname
);
4485 if (cli
&& !torture_close_connection(cli
)) {
4491 static bool run_deletetest_ln(int dummy
)
4493 struct cli_state
*cli
;
4494 const char *fname
= "\\delete1";
4495 const char *fname_ln
= "\\delete1_ln";
4499 bool correct
= true;
4502 printf("starting deletetest-ln\n");
4504 if (!torture_open_connection(&cli
, 0)) {
4508 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4509 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4511 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4513 /* Create the file. */
4514 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4515 if (!NT_STATUS_IS_OK(status
)) {
4516 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4520 status
= cli_close(cli
, fnum
);
4521 if (!NT_STATUS_IS_OK(status
)) {
4522 printf("close1 failed (%s)\n", nt_errstr(status
));
4526 /* Now create a hardlink. */
4527 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4528 if (!NT_STATUS_IS_OK(status
)) {
4529 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4533 /* Open the original file. */
4534 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4535 FILE_ATTRIBUTE_NORMAL
,
4536 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4537 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4538 if (!NT_STATUS_IS_OK(status
)) {
4539 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4543 /* Unlink the hard link path. */
4544 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4545 FILE_ATTRIBUTE_NORMAL
,
4546 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4547 FILE_OPEN_IF
, 0, 0, &fnum1
, NULL
);
4548 if (!NT_STATUS_IS_OK(status
)) {
4549 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4552 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4553 if (!NT_STATUS_IS_OK(status
)) {
4554 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4555 __location__
, fname_ln
, nt_errstr(status
));
4559 status
= cli_close(cli
, fnum1
);
4560 if (!NT_STATUS_IS_OK(status
)) {
4561 printf("close %s failed (%s)\n",
4562 fname_ln
, nt_errstr(status
));
4566 status
= cli_close(cli
, fnum
);
4567 if (!NT_STATUS_IS_OK(status
)) {
4568 printf("close %s failed (%s)\n",
4569 fname
, nt_errstr(status
));
4573 /* Ensure the original file is still there. */
4574 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4575 if (!NT_STATUS_IS_OK(status
)) {
4576 printf("%s getatr on file %s failed (%s)\n",
4583 /* Ensure the link path is gone. */
4584 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4585 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4586 printf("%s, getatr for file %s returned wrong error code %s "
4587 "- should have been deleted\n",
4589 fname_ln
, nt_errstr(status
));
4593 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4594 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4596 if (!torture_close_connection(cli
)) {
4600 printf("finished deletetest-ln\n");
4606 print out server properties
4608 static bool run_properties(int dummy
)
4610 struct cli_state
*cli
;
4611 bool correct
= True
;
4613 printf("starting properties test\n");
4617 if (!torture_open_connection(&cli
, 0)) {
4621 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4623 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
4625 if (!torture_close_connection(cli
)) {
4634 /* FIRST_DESIRED_ACCESS 0xf019f */
4635 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4636 FILE_READ_EA| /* 0xf */ \
4637 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4638 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4639 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4640 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4641 /* SECOND_DESIRED_ACCESS 0xe0080 */
4642 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4643 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4644 WRITE_OWNER_ACCESS /* 0xe0000 */
4647 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4648 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4650 WRITE_OWNER_ACCESS /* */
4654 Test ntcreate calls made by xcopy
4656 static bool run_xcopy(int dummy
)
4658 static struct cli_state
*cli1
;
4659 const char *fname
= "\\test.txt";
4660 bool correct
= True
;
4661 uint16_t fnum1
, fnum2
;
4664 printf("starting xcopy test\n");
4666 if (!torture_open_connection(&cli1
, 0)) {
4670 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4671 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4672 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
, NULL
);
4673 if (!NT_STATUS_IS_OK(status
)) {
4674 printf("First open failed - %s\n", nt_errstr(status
));
4678 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4679 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4680 FILE_OPEN
, 0x200000, 0, &fnum2
, NULL
);
4681 if (!NT_STATUS_IS_OK(status
)) {
4682 printf("second open failed - %s\n", nt_errstr(status
));
4686 if (!torture_close_connection(cli1
)) {
4694 Test rename on files open with share delete and no share delete.
4696 static bool run_rename(int dummy
)
4698 static struct cli_state
*cli1
;
4699 const char *fname
= "\\test.txt";
4700 const char *fname1
= "\\test1.txt";
4701 bool correct
= True
;
4706 printf("starting rename test\n");
4708 if (!torture_open_connection(&cli1
, 0)) {
4712 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4713 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4715 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4716 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4717 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4718 if (!NT_STATUS_IS_OK(status
)) {
4719 printf("First open failed - %s\n", nt_errstr(status
));
4723 status
= cli_rename(cli1
, fname
, fname1
, false);
4724 if (!NT_STATUS_IS_OK(status
)) {
4725 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4727 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4731 status
= cli_close(cli1
, fnum1
);
4732 if (!NT_STATUS_IS_OK(status
)) {
4733 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4737 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4738 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4739 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4741 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4743 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4745 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4746 if (!NT_STATUS_IS_OK(status
)) {
4747 printf("Second open failed - %s\n", nt_errstr(status
));
4751 status
= cli_rename(cli1
, fname
, fname1
, false);
4752 if (!NT_STATUS_IS_OK(status
)) {
4753 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4756 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4759 status
= cli_close(cli1
, fnum1
);
4760 if (!NT_STATUS_IS_OK(status
)) {
4761 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4765 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4766 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4768 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4769 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4770 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4771 if (!NT_STATUS_IS_OK(status
)) {
4772 printf("Third open failed - %s\n", nt_errstr(status
));
4781 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4782 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
, NULL
))) {
4783 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4786 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4787 printf("[8] setting delete_on_close on file failed !\n");
4791 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4792 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4798 status
= cli_rename(cli1
, fname
, fname1
, false);
4799 if (!NT_STATUS_IS_OK(status
)) {
4800 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4803 printf("Third rename succeeded (SHARE_NONE)\n");
4806 status
= cli_close(cli1
, fnum1
);
4807 if (!NT_STATUS_IS_OK(status
)) {
4808 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4812 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4813 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4817 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4818 FILE_ATTRIBUTE_NORMAL
,
4819 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4820 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4821 if (!NT_STATUS_IS_OK(status
)) {
4822 printf("Fourth open failed - %s\n", nt_errstr(status
));
4826 status
= cli_rename(cli1
, fname
, fname1
, false);
4827 if (!NT_STATUS_IS_OK(status
)) {
4828 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4830 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4834 status
= cli_close(cli1
, fnum1
);
4835 if (!NT_STATUS_IS_OK(status
)) {
4836 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4840 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4841 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4845 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4846 FILE_ATTRIBUTE_NORMAL
,
4847 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4848 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4849 if (!NT_STATUS_IS_OK(status
)) {
4850 printf("Fifth open failed - %s\n", nt_errstr(status
));
4854 status
= cli_rename(cli1
, fname
, fname1
, false);
4855 if (!NT_STATUS_IS_OK(status
)) {
4856 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4859 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4863 * Now check if the first name still exists ...
4866 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4867 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4868 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4869 printf("Opening original file after rename of open file fails: %s\n",
4873 printf("Opening original file after rename of open file works ...\n");
4874 (void)cli_close(cli1, fnum2);
4878 status
= cli_close(cli1
, fnum1
);
4879 if (!NT_STATUS_IS_OK(status
)) {
4880 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4884 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4885 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4886 if (!NT_STATUS_IS_OK(status
)) {
4887 printf("getatr on file %s failed - %s ! \n",
4888 fname1
, nt_errstr(status
));
4891 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4892 printf("Renamed file %s has wrong attr 0x%x "
4893 "(should be 0x%x)\n",
4896 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4899 printf("Renamed file %s has archive bit set\n", fname1
);
4903 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4904 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4906 if (!torture_close_connection(cli1
)) {
4914 Test rename into a directory with an ACL denying it.
4916 static bool run_rename_access(int dummy
)
4918 static struct cli_state
*cli
= NULL
;
4919 static struct cli_state
*posix_cli
= NULL
;
4920 const char *src
= "test.txt";
4921 const char *dname
= "dir";
4922 const char *dst
= "dir\\test.txt";
4923 const char *dsrc
= "test.dir";
4924 const char *ddst
= "dir\\test.dir";
4925 uint16_t fnum
= (uint16_t)-1;
4926 struct security_descriptor
*sd
= NULL
;
4927 struct security_descriptor
*newsd
= NULL
;
4929 TALLOC_CTX
*frame
= NULL
;
4931 frame
= talloc_stackframe();
4932 printf("starting rename access test\n");
4934 /* Windows connection. */
4935 if (!torture_open_connection(&cli
, 0)) {
4939 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4941 /* Posix connection. */
4942 if (!torture_open_connection(&posix_cli
, 0)) {
4946 smbXcli_conn_set_sockopt(posix_cli
->conn
, sockops
);
4948 status
= torture_setup_unix_extensions(posix_cli
);
4949 if (!NT_STATUS_IS_OK(status
)) {
4953 /* Start with a clean slate. */
4954 cli_unlink(cli
, src
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4955 cli_unlink(cli
, dst
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4956 cli_rmdir(cli
, dsrc
);
4957 cli_rmdir(cli
, ddst
);
4958 cli_rmdir(cli
, dname
);
4961 * Setup the destination directory with a DENY ACE to
4962 * prevent new files within it.
4964 status
= cli_ntcreate(cli
,
4967 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
|
4968 WRITE_DAC_ACCESS
|FILE_READ_DATA
|
4970 FILE_ATTRIBUTE_DIRECTORY
,
4971 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4973 FILE_DIRECTORY_FILE
,
4977 if (!NT_STATUS_IS_OK(status
)) {
4978 printf("Create of %s - %s\n", dname
, nt_errstr(status
));
4982 status
= cli_query_secdesc(cli
,
4986 if (!NT_STATUS_IS_OK(status
)) {
4987 printf("cli_query_secdesc failed for %s (%s)\n",
4988 dname
, nt_errstr(status
));
4992 newsd
= security_descriptor_dacl_create(frame
,
4997 SEC_ACE_TYPE_ACCESS_DENIED
,
4998 SEC_DIR_ADD_FILE
|SEC_DIR_ADD_SUBDIR
,
5001 if (newsd
== NULL
) {
5004 sd
->dacl
= security_acl_concatenate(frame
,
5007 if (sd
->dacl
== NULL
) {
5010 status
= cli_set_secdesc(cli
, fnum
, sd
);
5011 if (!NT_STATUS_IS_OK(status
)) {
5012 printf("cli_set_secdesc failed for %s (%s)\n",
5013 dname
, nt_errstr(status
));
5016 status
= cli_close(cli
, fnum
);
5017 if (!NT_STATUS_IS_OK(status
)) {
5018 printf("close failed for %s (%s)\n",
5019 dname
, nt_errstr(status
));
5022 /* Now go around the back and chmod to 777 via POSIX. */
5023 status
= cli_posix_chmod(posix_cli
, dname
, 0777);
5024 if (!NT_STATUS_IS_OK(status
)) {
5025 printf("cli_posix_chmod failed for %s (%s)\n",
5026 dname
, nt_errstr(status
));
5030 /* Check we can't create a file within dname via Windows. */
5031 status
= cli_openx(cli
, dst
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5032 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5033 cli_close(posix_cli
, fnum
);
5034 printf("Create of %s should be ACCESS denied, was %s\n",
5035 dst
, nt_errstr(status
));
5039 /* Make the sample file/directory. */
5040 status
= cli_openx(cli
, src
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5041 if (!NT_STATUS_IS_OK(status
)) {
5042 printf("open of %s failed (%s)\n", src
, nt_errstr(status
));
5045 status
= cli_close(cli
, fnum
);
5046 if (!NT_STATUS_IS_OK(status
)) {
5047 printf("cli_close failed (%s)\n", nt_errstr(status
));
5051 status
= cli_mkdir(cli
, dsrc
);
5052 if (!NT_STATUS_IS_OK(status
)) {
5053 printf("cli_mkdir of %s failed (%s)\n",
5054 dsrc
, nt_errstr(status
));
5059 * OK - renames of the new file and directory into the
5060 * dst directory should fail.
5063 status
= cli_rename(cli
, src
, dst
, false);
5064 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5065 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5066 src
, dst
, nt_errstr(status
));
5069 status
= cli_rename(cli
, dsrc
, ddst
, false);
5070 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5071 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5072 src
, dst
, nt_errstr(status
));
5082 torture_close_connection(posix_cli
);
5086 if (fnum
!= (uint64_t)-1) {
5087 cli_close(cli
, fnum
);
5089 cli_unlink(cli
, src
,
5090 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5091 cli_unlink(cli
, dst
,
5092 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5093 cli_rmdir(cli
, dsrc
);
5094 cli_rmdir(cli
, ddst
);
5095 cli_rmdir(cli
, dname
);
5097 torture_close_connection(cli
);
5105 Test owner rights ACE.
5107 static bool run_owner_rights(int dummy
)
5109 static struct cli_state
*cli
= NULL
;
5110 const char *fname
= "owner_rights.txt";
5111 uint16_t fnum
= (uint16_t)-1;
5112 struct security_descriptor
*sd
= NULL
;
5113 struct security_descriptor
*newsd
= NULL
;
5115 TALLOC_CTX
*frame
= NULL
;
5117 frame
= talloc_stackframe();
5118 printf("starting owner rights test\n");
5120 /* Windows connection. */
5121 if (!torture_open_connection(&cli
, 0)) {
5125 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5127 /* Start with a clean slate. */
5128 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5130 /* Create the test file. */
5131 /* Now try and open for read and write-dac. */
5132 status
= cli_ntcreate(cli
,
5136 FILE_ATTRIBUTE_NORMAL
,
5137 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5144 if (!NT_STATUS_IS_OK(status
)) {
5145 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5149 /* Get the original SD. */
5150 status
= cli_query_secdesc(cli
,
5154 if (!NT_STATUS_IS_OK(status
)) {
5155 printf("cli_query_secdesc failed for %s (%s)\n",
5156 fname
, nt_errstr(status
));
5161 * Add an "owner-rights" ACE denying WRITE_DATA,
5162 * and an "owner-rights" ACE allowing READ_DATA.
5165 newsd
= security_descriptor_dacl_create(frame
,
5170 SEC_ACE_TYPE_ACCESS_DENIED
,
5174 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5178 if (newsd
== NULL
) {
5181 sd
->dacl
= security_acl_concatenate(frame
,
5184 if (sd
->dacl
== NULL
) {
5187 status
= cli_set_secdesc(cli
, fnum
, sd
);
5188 if (!NT_STATUS_IS_OK(status
)) {
5189 printf("cli_set_secdesc failed for %s (%s)\n",
5190 fname
, nt_errstr(status
));
5193 status
= cli_close(cli
, fnum
);
5194 if (!NT_STATUS_IS_OK(status
)) {
5195 printf("close failed for %s (%s)\n",
5196 fname
, nt_errstr(status
));
5199 fnum
= (uint16_t)-1;
5201 /* Try and open for FILE_WRITE_DATA */
5202 status
= cli_ntcreate(cli
,
5206 FILE_ATTRIBUTE_NORMAL
,
5207 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5214 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5215 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5219 /* Now try and open for FILE_READ_DATA */
5220 status
= cli_ntcreate(cli
,
5224 FILE_ATTRIBUTE_NORMAL
,
5225 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5232 if (!NT_STATUS_IS_OK(status
)) {
5233 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5237 status
= cli_close(cli
, fnum
);
5238 if (!NT_STATUS_IS_OK(status
)) {
5239 printf("close failed for %s (%s)\n",
5240 fname
, nt_errstr(status
));
5244 /* Restore clean slate. */
5246 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5248 /* Create the test file. */
5249 status
= cli_ntcreate(cli
,
5253 FILE_ATTRIBUTE_NORMAL
,
5254 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5261 if (!NT_STATUS_IS_OK(status
)) {
5262 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5266 /* Get the original SD. */
5267 status
= cli_query_secdesc(cli
,
5271 if (!NT_STATUS_IS_OK(status
)) {
5272 printf("cli_query_secdesc failed for %s (%s)\n",
5273 fname
, nt_errstr(status
));
5278 * Add an "owner-rights ACE denying WRITE_DATA,
5279 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5282 newsd
= security_descriptor_dacl_create(frame
,
5287 SEC_ACE_TYPE_ACCESS_DENIED
,
5291 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5292 FILE_READ_DATA
|FILE_WRITE_DATA
,
5295 if (newsd
== NULL
) {
5298 sd
->dacl
= security_acl_concatenate(frame
,
5301 if (sd
->dacl
== NULL
) {
5304 status
= cli_set_secdesc(cli
, fnum
, sd
);
5305 if (!NT_STATUS_IS_OK(status
)) {
5306 printf("cli_set_secdesc failed for %s (%s)\n",
5307 fname
, nt_errstr(status
));
5310 status
= cli_close(cli
, fnum
);
5311 if (!NT_STATUS_IS_OK(status
)) {
5312 printf("close failed for %s (%s)\n",
5313 fname
, nt_errstr(status
));
5316 fnum
= (uint16_t)-1;
5318 /* Try and open for FILE_WRITE_DATA */
5319 status
= cli_ntcreate(cli
,
5323 FILE_ATTRIBUTE_NORMAL
,
5324 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5331 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5332 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5336 /* Now try and open for FILE_READ_DATA */
5337 status
= cli_ntcreate(cli
,
5341 FILE_ATTRIBUTE_NORMAL
,
5342 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5349 if (!NT_STATUS_IS_OK(status
)) {
5350 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5354 status
= cli_close(cli
, fnum
);
5355 if (!NT_STATUS_IS_OK(status
)) {
5356 printf("close failed for %s (%s)\n",
5357 fname
, nt_errstr(status
));
5361 /* Restore clean slate. */
5363 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5366 /* Create the test file. */
5367 status
= cli_ntcreate(cli
,
5371 FILE_ATTRIBUTE_NORMAL
,
5372 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5379 if (!NT_STATUS_IS_OK(status
)) {
5380 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5384 /* Get the original SD. */
5385 status
= cli_query_secdesc(cli
,
5389 if (!NT_STATUS_IS_OK(status
)) {
5390 printf("cli_query_secdesc failed for %s (%s)\n",
5391 fname
, nt_errstr(status
));
5396 * Add an "authenticated users" ACE allowing READ_DATA,
5397 * add an "owner-rights" denying READ_DATA,
5398 * and an "authenticated users" ACE allowing WRITE_DATA.
5401 newsd
= security_descriptor_dacl_create(frame
,
5405 SID_NT_AUTHENTICATED_USERS
,
5406 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5410 SEC_ACE_TYPE_ACCESS_DENIED
,
5413 SID_NT_AUTHENTICATED_USERS
,
5414 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5418 if (newsd
== NULL
) {
5419 printf("newsd == NULL\n");
5422 sd
->dacl
= security_acl_concatenate(frame
,
5425 if (sd
->dacl
== NULL
) {
5426 printf("sd->dacl == NULL\n");
5429 status
= cli_set_secdesc(cli
, fnum
, sd
);
5430 if (!NT_STATUS_IS_OK(status
)) {
5431 printf("cli_set_secdesc failed for %s (%s)\n",
5432 fname
, nt_errstr(status
));
5435 status
= cli_close(cli
, fnum
);
5436 if (!NT_STATUS_IS_OK(status
)) {
5437 printf("close failed for %s (%s)\n",
5438 fname
, nt_errstr(status
));
5441 fnum
= (uint16_t)-1;
5443 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5444 status
= cli_ntcreate(cli
,
5447 FILE_READ_DATA
|FILE_WRITE_DATA
,
5448 FILE_ATTRIBUTE_NORMAL
,
5449 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5456 if (!NT_STATUS_IS_OK(status
)) {
5457 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5461 status
= cli_close(cli
, fnum
);
5462 if (!NT_STATUS_IS_OK(status
)) {
5463 printf("close failed for %s (%s)\n",
5464 fname
, nt_errstr(status
));
5468 cli_unlink(cli
, fname
,
5469 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5477 if (fnum
!= (uint16_t)-1) {
5478 cli_close(cli
, fnum
);
5480 cli_unlink(cli
, fname
,
5481 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5482 torture_close_connection(cli
);
5489 static bool run_pipe_number(int dummy
)
5491 struct cli_state
*cli1
;
5492 const char *pipe_name
= "\\SPOOLSS";
5497 printf("starting pipenumber test\n");
5498 if (!torture_open_connection(&cli1
, 0)) {
5502 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5504 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
5505 FILE_ATTRIBUTE_NORMAL
,
5506 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5507 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
5508 if (!NT_STATUS_IS_OK(status
)) {
5509 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
5513 printf("\r%6d", num_pipes
);
5516 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
5517 torture_close_connection(cli1
);
5522 Test open mode returns on read-only files.
5524 static bool run_opentest(int dummy
)
5526 static struct cli_state
*cli1
;
5527 static struct cli_state
*cli2
;
5528 const char *fname
= "\\readonly.file";
5529 uint16_t fnum1
, fnum2
;
5532 bool correct
= True
;
5536 printf("starting open test\n");
5538 if (!torture_open_connection(&cli1
, 0)) {
5542 cli_setatr(cli1
, fname
, 0, 0);
5543 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5545 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5547 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
5548 if (!NT_STATUS_IS_OK(status
)) {
5549 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5553 status
= cli_close(cli1
, fnum1
);
5554 if (!NT_STATUS_IS_OK(status
)) {
5555 printf("close2 failed (%s)\n", nt_errstr(status
));
5559 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
5560 if (!NT_STATUS_IS_OK(status
)) {
5561 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
5565 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
5566 if (!NT_STATUS_IS_OK(status
)) {
5567 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5571 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5572 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
5574 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
5575 NT_STATUS_ACCESS_DENIED
)) {
5576 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5579 printf("finished open test 1\n");
5581 cli_close(cli1
, fnum1
);
5583 /* Now try not readonly and ensure ERRbadshare is returned. */
5585 cli_setatr(cli1
, fname
, 0, 0);
5587 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
5588 if (!NT_STATUS_IS_OK(status
)) {
5589 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5593 /* This will fail - but the error should be ERRshare. */
5594 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
5596 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
5597 NT_STATUS_SHARING_VIOLATION
)) {
5598 printf("correct error code ERRDOS/ERRbadshare returned\n");
5601 status
= cli_close(cli1
, fnum1
);
5602 if (!NT_STATUS_IS_OK(status
)) {
5603 printf("close2 failed (%s)\n", nt_errstr(status
));
5607 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5609 printf("finished open test 2\n");
5611 /* Test truncate open disposition on file opened for read. */
5612 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
5613 if (!NT_STATUS_IS_OK(status
)) {
5614 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
5618 /* write 20 bytes. */
5620 memset(buf
, '\0', 20);
5622 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
5623 if (!NT_STATUS_IS_OK(status
)) {
5624 printf("write failed (%s)\n", nt_errstr(status
));
5628 status
= cli_close(cli1
, fnum1
);
5629 if (!NT_STATUS_IS_OK(status
)) {
5630 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
5634 /* Ensure size == 20. */
5635 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5636 if (!NT_STATUS_IS_OK(status
)) {
5637 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5642 printf("(3) file size != 20\n");
5646 /* Now test if we can truncate a file opened for readonly. */
5647 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
5648 if (!NT_STATUS_IS_OK(status
)) {
5649 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
5653 status
= cli_close(cli1
, fnum1
);
5654 if (!NT_STATUS_IS_OK(status
)) {
5655 printf("close2 failed (%s)\n", nt_errstr(status
));
5659 /* Ensure size == 0. */
5660 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5661 if (!NT_STATUS_IS_OK(status
)) {
5662 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5667 printf("(3) file size != 0\n");
5670 printf("finished open test 3\n");
5672 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5674 printf("Do ctemp tests\n");
5675 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
5676 if (!NT_STATUS_IS_OK(status
)) {
5677 printf("ctemp failed (%s)\n", nt_errstr(status
));
5681 printf("ctemp gave path %s\n", tmp_path
);
5682 status
= cli_close(cli1
, fnum1
);
5683 if (!NT_STATUS_IS_OK(status
)) {
5684 printf("close of temp failed (%s)\n", nt_errstr(status
));
5687 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5688 if (!NT_STATUS_IS_OK(status
)) {
5689 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5692 /* Test the non-io opens... */
5694 if (!torture_open_connection(&cli2
, 1)) {
5698 cli_setatr(cli2
, fname
, 0, 0);
5699 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5701 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
5703 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5704 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5705 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5706 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5707 if (!NT_STATUS_IS_OK(status
)) {
5708 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5712 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5713 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5714 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5715 if (!NT_STATUS_IS_OK(status
)) {
5716 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5720 status
= cli_close(cli1
, fnum1
);
5721 if (!NT_STATUS_IS_OK(status
)) {
5722 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5726 status
= cli_close(cli2
, fnum2
);
5727 if (!NT_STATUS_IS_OK(status
)) {
5728 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5732 printf("non-io open test #1 passed.\n");
5734 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5736 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5738 status
= cli_ntcreate(cli1
, fname
, 0,
5739 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5740 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5741 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5742 if (!NT_STATUS_IS_OK(status
)) {
5743 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5747 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5748 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5749 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5750 if (!NT_STATUS_IS_OK(status
)) {
5751 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5755 status
= cli_close(cli1
, fnum1
);
5756 if (!NT_STATUS_IS_OK(status
)) {
5757 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5761 status
= cli_close(cli2
, fnum2
);
5762 if (!NT_STATUS_IS_OK(status
)) {
5763 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5767 printf("non-io open test #2 passed.\n");
5769 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5771 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5773 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5774 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5775 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5776 if (!NT_STATUS_IS_OK(status
)) {
5777 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5781 status
= cli_ntcreate(cli2
, fname
, 0,
5782 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5783 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5784 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5785 if (!NT_STATUS_IS_OK(status
)) {
5786 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5790 status
= cli_close(cli1
, fnum1
);
5791 if (!NT_STATUS_IS_OK(status
)) {
5792 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5796 status
= cli_close(cli2
, fnum2
);
5797 if (!NT_STATUS_IS_OK(status
)) {
5798 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5802 printf("non-io open test #3 passed.\n");
5804 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5806 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5808 status
= cli_ntcreate(cli1
, fname
, 0,
5809 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5810 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5811 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5812 if (!NT_STATUS_IS_OK(status
)) {
5813 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5817 status
= cli_ntcreate(cli2
, fname
, 0,
5818 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5819 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5820 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5821 if (NT_STATUS_IS_OK(status
)) {
5822 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5826 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5828 status
= cli_close(cli1
, fnum1
);
5829 if (!NT_STATUS_IS_OK(status
)) {
5830 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5834 printf("non-io open test #4 passed.\n");
5836 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5838 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5840 status
= cli_ntcreate(cli1
, fname
, 0,
5841 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5842 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5843 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5844 if (!NT_STATUS_IS_OK(status
)) {
5845 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5849 status
= cli_ntcreate(cli2
, fname
, 0,
5850 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5851 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5852 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5853 if (!NT_STATUS_IS_OK(status
)) {
5854 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5858 status
= cli_close(cli1
, fnum1
);
5859 if (!NT_STATUS_IS_OK(status
)) {
5860 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5864 status
= cli_close(cli2
, fnum2
);
5865 if (!NT_STATUS_IS_OK(status
)) {
5866 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5870 printf("non-io open test #5 passed.\n");
5872 printf("TEST #6 testing 1 non-io open, one io open\n");
5874 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5876 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5877 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5878 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5879 if (!NT_STATUS_IS_OK(status
)) {
5880 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5884 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5885 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5886 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5887 if (!NT_STATUS_IS_OK(status
)) {
5888 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5892 status
= cli_close(cli1
, fnum1
);
5893 if (!NT_STATUS_IS_OK(status
)) {
5894 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5898 status
= cli_close(cli2
, fnum2
);
5899 if (!NT_STATUS_IS_OK(status
)) {
5900 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5904 printf("non-io open test #6 passed.\n");
5906 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5908 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5910 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5911 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5912 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5913 if (!NT_STATUS_IS_OK(status
)) {
5914 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5918 status
= cli_ntcreate(cli2
, fname
, 0,
5919 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5920 FILE_ATTRIBUTE_NORMAL
,
5921 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5922 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5923 if (NT_STATUS_IS_OK(status
)) {
5924 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5928 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5930 status
= cli_close(cli1
, fnum1
);
5931 if (!NT_STATUS_IS_OK(status
)) {
5932 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5936 printf("non-io open test #7 passed.\n");
5938 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5940 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5941 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5942 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5943 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5944 if (!NT_STATUS_IS_OK(status
)) {
5945 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5950 /* Write to ensure we have to update the file time. */
5951 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5953 if (!NT_STATUS_IS_OK(status
)) {
5954 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5959 status
= cli_close(cli1
, fnum1
);
5960 if (!NT_STATUS_IS_OK(status
)) {
5961 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5967 if (!torture_close_connection(cli1
)) {
5970 if (!torture_close_connection(cli2
)) {
5977 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5979 uint16_t major
, minor
;
5980 uint32_t caplow
, caphigh
;
5983 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5984 printf("Server doesn't support UNIX CIFS extensions.\n");
5985 return NT_STATUS_NOT_SUPPORTED
;
5988 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5990 if (!NT_STATUS_IS_OK(status
)) {
5991 printf("Server didn't return UNIX CIFS extensions: %s\n",
5996 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5998 if (!NT_STATUS_IS_OK(status
)) {
5999 printf("Server doesn't support setting UNIX CIFS extensions: "
6000 "%s.\n", nt_errstr(status
));
6004 return NT_STATUS_OK
;
6008 Test POSIX open /mkdir calls.
6010 static bool run_simple_posix_open_test(int dummy
)
6012 static struct cli_state
*cli1
;
6013 const char *fname
= "posix:file";
6014 const char *hname
= "posix:hlink";
6015 const char *sname
= "posix:symlink";
6016 const char *dname
= "posix:dir";
6019 uint16_t fnum1
= (uint16_t)-1;
6020 SMB_STRUCT_STAT sbuf
;
6021 bool correct
= false;
6024 const char *fname_windows
= "windows_file";
6025 uint16_t fnum2
= (uint16_t)-1;
6027 printf("Starting simple POSIX open test\n");
6029 if (!torture_open_connection(&cli1
, 0)) {
6033 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6035 status
= torture_setup_unix_extensions(cli1
);
6036 if (!NT_STATUS_IS_OK(status
)) {
6040 cli_setatr(cli1
, fname
, 0, 0);
6041 cli_posix_unlink(cli1
, fname
);
6042 cli_setatr(cli1
, dname
, 0, 0);
6043 cli_posix_rmdir(cli1
, dname
);
6044 cli_setatr(cli1
, hname
, 0, 0);
6045 cli_posix_unlink(cli1
, hname
);
6046 cli_setatr(cli1
, sname
, 0, 0);
6047 cli_posix_unlink(cli1
, sname
);
6048 cli_setatr(cli1
, fname_windows
, 0, 0);
6049 cli_posix_unlink(cli1
, fname_windows
);
6051 /* Create a directory. */
6052 status
= cli_posix_mkdir(cli1
, dname
, 0777);
6053 if (!NT_STATUS_IS_OK(status
)) {
6054 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
6058 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6060 if (!NT_STATUS_IS_OK(status
)) {
6061 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6065 /* Test ftruncate - set file size. */
6066 status
= cli_ftruncate(cli1
, fnum1
, 1000);
6067 if (!NT_STATUS_IS_OK(status
)) {
6068 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6072 /* Ensure st_size == 1000 */
6073 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6074 if (!NT_STATUS_IS_OK(status
)) {
6075 printf("stat failed (%s)\n", nt_errstr(status
));
6079 if (sbuf
.st_ex_size
!= 1000) {
6080 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
6084 /* Ensure st_mode == 0600 */
6085 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
6086 printf("posix_open - bad permissions 0%o != 0600\n",
6087 (unsigned int)(sbuf
.st_ex_mode
& 07777));
6091 /* Test ftruncate - set file size back to zero. */
6092 status
= cli_ftruncate(cli1
, fnum1
, 0);
6093 if (!NT_STATUS_IS_OK(status
)) {
6094 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6098 status
= cli_close(cli1
, fnum1
);
6099 if (!NT_STATUS_IS_OK(status
)) {
6100 printf("close failed (%s)\n", nt_errstr(status
));
6104 /* Now open the file again for read only. */
6105 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
6106 if (!NT_STATUS_IS_OK(status
)) {
6107 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
6111 /* Now unlink while open. */
6112 status
= cli_posix_unlink(cli1
, fname
);
6113 if (!NT_STATUS_IS_OK(status
)) {
6114 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
6118 status
= cli_close(cli1
, fnum1
);
6119 if (!NT_STATUS_IS_OK(status
)) {
6120 printf("close(2) failed (%s)\n", nt_errstr(status
));
6124 /* Ensure the file has gone. */
6125 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
6126 if (NT_STATUS_IS_OK(status
)) {
6127 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
6131 /* Create again to test open with O_TRUNC. */
6132 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
6133 if (!NT_STATUS_IS_OK(status
)) {
6134 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6138 /* Test ftruncate - set file size. */
6139 status
= cli_ftruncate(cli1
, fnum1
, 1000);
6140 if (!NT_STATUS_IS_OK(status
)) {
6141 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6145 /* Ensure st_size == 1000 */
6146 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6147 if (!NT_STATUS_IS_OK(status
)) {
6148 printf("stat failed (%s)\n", nt_errstr(status
));
6152 if (sbuf
.st_ex_size
!= 1000) {
6153 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
6157 status
= cli_close(cli1
, fnum1
);
6158 if (!NT_STATUS_IS_OK(status
)) {
6159 printf("close(2) failed (%s)\n", nt_errstr(status
));
6163 /* Re-open with O_TRUNC. */
6164 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
6165 if (!NT_STATUS_IS_OK(status
)) {
6166 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6170 /* Ensure st_size == 0 */
6171 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6172 if (!NT_STATUS_IS_OK(status
)) {
6173 printf("stat failed (%s)\n", nt_errstr(status
));
6177 if (sbuf
.st_ex_size
!= 0) {
6178 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
6182 status
= cli_close(cli1
, fnum1
);
6183 if (!NT_STATUS_IS_OK(status
)) {
6184 printf("close failed (%s)\n", nt_errstr(status
));
6188 status
= cli_posix_unlink(cli1
, fname
);
6189 if (!NT_STATUS_IS_OK(status
)) {
6190 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
6194 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
6195 if (!NT_STATUS_IS_OK(status
)) {
6196 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6197 dname
, nt_errstr(status
));
6201 cli_close(cli1
, fnum1
);
6203 /* What happens when we try and POSIX open a directory for write ? */
6204 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
6205 if (NT_STATUS_IS_OK(status
)) {
6206 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
6209 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
6210 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
6215 /* Create the file. */
6216 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6218 if (!NT_STATUS_IS_OK(status
)) {
6219 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6223 /* Write some data into it. */
6224 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6226 if (!NT_STATUS_IS_OK(status
)) {
6227 printf("cli_write failed: %s\n", nt_errstr(status
));
6231 cli_close(cli1
, fnum1
);
6233 /* Now create a hardlink. */
6234 status
= cli_posix_hardlink(cli1
, fname
, hname
);
6235 if (!NT_STATUS_IS_OK(status
)) {
6236 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
6240 /* Now create a symlink. */
6241 status
= cli_posix_symlink(cli1
, fname
, sname
);
6242 if (!NT_STATUS_IS_OK(status
)) {
6243 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
6247 /* Open the hardlink for read. */
6248 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
6249 if (!NT_STATUS_IS_OK(status
)) {
6250 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
6254 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
6255 if (!NT_STATUS_IS_OK(status
)) {
6256 printf("POSIX read of %s failed (%s)\n", hname
,
6259 } else if (nread
!= 10) {
6260 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6261 hname
, (unsigned long)nread
, 10);
6265 if (memcmp(buf
, "TEST DATA\n", 10)) {
6266 printf("invalid data read from hardlink\n");
6270 /* Do a POSIX lock/unlock. */
6271 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
6272 if (!NT_STATUS_IS_OK(status
)) {
6273 printf("POSIX lock failed %s\n", nt_errstr(status
));
6277 /* Punch a hole in the locked area. */
6278 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
6279 if (!NT_STATUS_IS_OK(status
)) {
6280 printf("POSIX unlock failed %s\n", nt_errstr(status
));
6284 cli_close(cli1
, fnum1
);
6286 /* Open the symlink for read - this should fail. A POSIX
6287 client should not be doing opens on a symlink. */
6288 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
6289 if (NT_STATUS_IS_OK(status
)) {
6290 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
6293 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6294 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
6295 printf("POSIX open of %s should have failed "
6296 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6297 "failed with %s instead.\n",
6298 sname
, nt_errstr(status
));
6303 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
6304 if (!NT_STATUS_IS_OK(status
)) {
6305 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
6309 if (strcmp(namebuf
, fname
) != 0) {
6310 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6311 sname
, fname
, namebuf
);
6315 status
= cli_posix_rmdir(cli1
, dname
);
6316 if (!NT_STATUS_IS_OK(status
)) {
6317 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
6321 /* Check directory opens with a specific permission. */
6322 status
= cli_posix_mkdir(cli1
, dname
, 0700);
6323 if (!NT_STATUS_IS_OK(status
)) {
6324 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
6328 /* Ensure st_mode == 0700 */
6329 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
6330 if (!NT_STATUS_IS_OK(status
)) {
6331 printf("stat failed (%s)\n", nt_errstr(status
));
6335 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
6336 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6337 (unsigned int)(sbuf
.st_ex_mode
& 07777));
6342 * Now create a Windows file, and attempt a POSIX unlink.
6343 * This should fail with a sharing violation but due to:
6345 * [Bug 9571] Unlink after open causes smbd to panic
6347 * ensure we've fixed the lock ordering violation.
6350 status
= cli_ntcreate(cli1
, fname_windows
, 0,
6351 FILE_READ_DATA
|FILE_WRITE_DATA
, 0,
6352 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6354 0x0, 0x0, &fnum2
, NULL
);
6355 if (!NT_STATUS_IS_OK(status
)) {
6356 printf("Windows create of %s failed (%s)\n", fname_windows
,
6361 /* Now try posix_unlink. */
6362 status
= cli_posix_unlink(cli1
, fname_windows
);
6363 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6364 printf("POSIX unlink of %s should fail "
6365 "with NT_STATUS_SHARING_VIOLATION "
6366 "got %s instead !\n",
6372 cli_close(cli1
, fnum2
);
6374 printf("Simple POSIX open test passed\n");
6379 if (fnum1
!= (uint16_t)-1) {
6380 cli_close(cli1
, fnum1
);
6381 fnum1
= (uint16_t)-1;
6384 if (fnum2
!= (uint16_t)-1) {
6385 cli_close(cli1
, fnum2
);
6386 fnum2
= (uint16_t)-1;
6389 cli_setatr(cli1
, sname
, 0, 0);
6390 cli_posix_unlink(cli1
, sname
);
6391 cli_setatr(cli1
, hname
, 0, 0);
6392 cli_posix_unlink(cli1
, hname
);
6393 cli_setatr(cli1
, fname
, 0, 0);
6394 cli_posix_unlink(cli1
, fname
);
6395 cli_setatr(cli1
, dname
, 0, 0);
6396 cli_posix_rmdir(cli1
, dname
);
6397 cli_setatr(cli1
, fname_windows
, 0, 0);
6398 cli_posix_unlink(cli1
, fname_windows
);
6400 if (!torture_close_connection(cli1
)) {
6408 Test POSIX and Windows ACLs are rejected on symlinks.
6410 static bool run_acl_symlink_test(int dummy
)
6412 static struct cli_state
*cli
;
6413 const char *fname
= "posix_file";
6414 const char *sname
= "posix_symlink";
6415 uint16_t fnum
= (uint16_t)-1;
6416 bool correct
= false;
6418 char *posix_acl
= NULL
;
6419 size_t posix_acl_len
= 0;
6420 char *posix_acl_sym
= NULL
;
6421 size_t posix_acl_len_sym
= 0;
6422 struct security_descriptor
*sd
= NULL
;
6423 struct security_descriptor
*sd_sym
= NULL
;
6424 TALLOC_CTX
*frame
= NULL
;
6426 frame
= talloc_stackframe();
6428 printf("Starting acl symlink test\n");
6430 if (!torture_open_connection(&cli
, 0)) {
6435 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6437 status
= torture_setup_unix_extensions(cli
);
6438 if (!NT_STATUS_IS_OK(status
)) {
6443 cli_setatr(cli
, fname
, 0, 0);
6444 cli_posix_unlink(cli
, fname
);
6445 cli_setatr(cli
, sname
, 0, 0);
6446 cli_posix_unlink(cli
, sname
);
6448 status
= cli_ntcreate(cli
,
6451 READ_CONTROL_ACCESS
,
6453 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6460 if (!NT_STATUS_IS_OK(status
)) {
6461 printf("cli_ntcreate of %s failed (%s)\n",
6467 /* Get the Windows ACL on the file. */
6468 status
= cli_query_secdesc(cli
,
6472 if (!NT_STATUS_IS_OK(status
)) {
6473 printf("cli_query_secdesc failed (%s)\n",
6478 /* Get the POSIX ACL on the file. */
6479 status
= cli_posix_getacl(cli
,
6485 if (!NT_STATUS_IS_OK(status
)) {
6486 printf("cli_posix_getacl failed (%s)\n",
6491 status
= cli_close(cli
, fnum
);
6492 if (!NT_STATUS_IS_OK(status
)) {
6493 printf("close failed (%s)\n", nt_errstr(status
));
6496 fnum
= (uint16_t)-1;
6498 /* Now create a symlink. */
6499 status
= cli_posix_symlink(cli
, fname
, sname
);
6500 if (!NT_STATUS_IS_OK(status
)) {
6501 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6508 /* Open a handle on the symlink. */
6509 status
= cli_ntcreate(cli
,
6512 READ_CONTROL_ACCESS
|SEC_STD_WRITE_DAC
,
6514 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6521 if (!NT_STATUS_IS_OK(status
)) {
6522 printf("cli_posix_open of %s failed (%s)\n",
6528 /* Get the Windows ACL on the symlink handle. Should fail */
6529 status
= cli_query_secdesc(cli
,
6534 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6535 printf("cli_query_secdesc on a symlink gave %s. "
6536 "Should be NT_STATUS_ACCESS_DENIED.\n",
6541 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6542 status
= cli_posix_getacl(cli
,
6548 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6549 printf("cli_posix_getacl on a symlink gave %s. "
6550 "Should be NT_STATUS_ACCESS_DENIED.\n",
6555 /* Set the Windows ACL on the symlink handle. Should fail */
6556 status
= cli_set_security_descriptor(cli
,
6561 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6562 printf("cli_query_secdesc on a symlink gave %s. "
6563 "Should be NT_STATUS_ACCESS_DENIED.\n",
6568 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6569 status
= cli_posix_setacl(cli
,
6574 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6575 printf("cli_posix_getacl on a symlink gave %s. "
6576 "Should be NT_STATUS_ACCESS_DENIED.\n",
6581 printf("ACL symlink test passed\n");
6586 if (fnum
!= (uint16_t)-1) {
6587 cli_close(cli
, fnum
);
6588 fnum
= (uint16_t)-1;
6591 cli_setatr(cli
, sname
, 0, 0);
6592 cli_posix_unlink(cli
, sname
);
6593 cli_setatr(cli
, fname
, 0, 0);
6594 cli_posix_unlink(cli
, fname
);
6596 if (!torture_close_connection(cli
)) {
6605 Test POSIX can delete a file containing streams.
6607 static bool run_posix_stream_delete(int dummy
)
6609 struct cli_state
*cli1
= NULL
;
6610 struct cli_state
*cli2
= NULL
;
6611 const char *fname
= "streamfile";
6612 const char *stream_fname
= "streamfile:Zone.Identifier:$DATA";
6613 uint16_t fnum1
= (uint16_t)-1;
6614 bool correct
= false;
6616 TALLOC_CTX
*frame
= NULL
;
6618 frame
= talloc_stackframe();
6620 printf("Starting POSIX stream delete test\n");
6622 if (!torture_open_connection(&cli1
, 0) ||
6623 !torture_open_connection(&cli2
, 1)) {
6628 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6629 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
6631 status
= torture_setup_unix_extensions(cli2
);
6632 if (!NT_STATUS_IS_OK(status
)) {
6636 cli_setatr(cli1
, fname
, 0, 0);
6637 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6639 /* Create the file. */
6640 status
= cli_ntcreate(cli1
,
6643 READ_CONTROL_ACCESS
,
6645 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6652 if (!NT_STATUS_IS_OK(status
)) {
6653 printf("cli_ntcreate of %s failed (%s)\n",
6659 status
= cli_close(cli1
, fnum1
);
6660 if (!NT_STATUS_IS_OK(status
)) {
6661 printf("cli_close of %s failed (%s)\n",
6666 fnum1
= (uint16_t)-1;
6668 /* Now create the stream. */
6669 status
= cli_ntcreate(cli1
,
6674 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6681 if (!NT_STATUS_IS_OK(status
)) {
6682 printf("cli_ntcreate of %s failed (%s)\n",
6688 /* Leave the stream handle open... */
6690 /* POSIX unlink should fail. */
6691 status
= cli_posix_unlink(cli2
, fname
);
6692 if (NT_STATUS_IS_OK(status
)) {
6693 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6698 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6699 printf("cli_posix_unlink of %s failed with (%s) "
6700 "should have been NT_STATUS_SHARING_VIOLATION\n",
6706 /* Close the stream handle. */
6707 status
= cli_close(cli1
, fnum1
);
6708 if (!NT_STATUS_IS_OK(status
)) {
6709 printf("cli_close of %s failed (%s)\n",
6714 fnum1
= (uint16_t)-1;
6716 /* POSIX unlink after stream handle closed should succeed. */
6717 status
= cli_posix_unlink(cli2
, fname
);
6718 if (!NT_STATUS_IS_OK(status
)) {
6719 printf("cli_posix_unlink of %s failed (%s)\n",
6725 printf("POSIX stream delete test passed\n");
6730 if (fnum1
!= (uint16_t)-1) {
6731 cli_close(cli1
, fnum1
);
6732 fnum1
= (uint16_t)-1;
6735 cli_setatr(cli1
, fname
, 0, 0);
6736 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6738 if (!torture_close_connection(cli1
)) {
6741 if (!torture_close_connection(cli2
)) {
6750 Test setting EA's are rejected on symlinks.
6752 static bool run_ea_symlink_test(int dummy
)
6754 static struct cli_state
*cli
;
6755 const char *fname
= "posix_file_ea";
6756 const char *sname
= "posix_symlink_ea";
6757 const char *ea_name
= "testea_name";
6758 const char *ea_value
= "testea_value";
6759 uint16_t fnum
= (uint16_t)-1;
6760 bool correct
= false;
6763 struct ea_struct
*eas
= NULL
;
6764 TALLOC_CTX
*frame
= NULL
;
6766 frame
= talloc_stackframe();
6768 printf("Starting EA symlink test\n");
6770 if (!torture_open_connection(&cli
, 0)) {
6775 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6777 status
= torture_setup_unix_extensions(cli
);
6778 if (!NT_STATUS_IS_OK(status
)) {
6783 cli_setatr(cli
, fname
, 0, 0);
6784 cli_posix_unlink(cli
, fname
);
6785 cli_setatr(cli
, sname
, 0, 0);
6786 cli_posix_unlink(cli
, sname
);
6788 status
= cli_ntcreate(cli
,
6791 READ_CONTROL_ACCESS
,
6793 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6800 if (!NT_STATUS_IS_OK(status
)) {
6801 printf("cli_ntcreate of %s failed (%s)\n",
6807 status
= cli_close(cli
, fnum
);
6808 if (!NT_STATUS_IS_OK(status
)) {
6809 printf("close failed (%s)\n",
6813 fnum
= (uint16_t)-1;
6815 /* Set an EA on the path. */
6816 status
= cli_set_ea_path(cli
,
6820 strlen(ea_value
)+1);
6822 if (!NT_STATUS_IS_OK(status
)) {
6823 printf("cli_set_ea_path failed (%s)\n",
6828 /* Now create a symlink. */
6829 status
= cli_posix_symlink(cli
, fname
, sname
);
6830 if (!NT_STATUS_IS_OK(status
)) {
6831 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6838 /* Get the EA list on the path. Should return value set. */
6839 status
= cli_get_ea_list_path(cli
,
6845 if (!NT_STATUS_IS_OK(status
)) {
6846 printf("cli_get_ea_list_path failed (%s)\n",
6851 /* Ensure the EA we set is there. */
6852 for (i
=0; i
<num_eas
; i
++) {
6853 if (strcmp(eas
[i
].name
, ea_name
) == 0 &&
6854 eas
[i
].value
.length
== strlen(ea_value
)+1 &&
6855 memcmp(eas
[i
].value
.data
,
6857 eas
[i
].value
.length
) == 0) {
6863 printf("Didn't find EA on pathname %s\n",
6871 /* Get the EA list on the symlink. Should return empty list. */
6872 status
= cli_get_ea_list_path(cli
,
6878 if (!NT_STATUS_IS_OK(status
)) {
6879 printf("cli_get_ea_list_path failed (%s)\n",
6885 printf("cli_get_ea_list_path failed (%s)\n",
6890 /* Set an EA on the symlink. Should fail. */
6891 status
= cli_set_ea_path(cli
,
6895 strlen(ea_value
)+1);
6897 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6898 printf("cli_set_ea_path on a symlink gave %s. "
6899 "Should be NT_STATUS_ACCESS_DENIED.\n",
6904 printf("EA symlink test passed\n");
6909 if (fnum
!= (uint16_t)-1) {
6910 cli_close(cli
, fnum
);
6911 fnum
= (uint16_t)-1;
6914 cli_setatr(cli
, sname
, 0, 0);
6915 cli_posix_unlink(cli
, sname
);
6916 cli_setatr(cli
, fname
, 0, 0);
6917 cli_posix_unlink(cli
, fname
);
6919 if (!torture_close_connection(cli
)) {
6928 Test POSIX locks are OFD-locks.
6930 static bool run_posix_ofd_lock_test(int dummy
)
6932 static struct cli_state
*cli
;
6933 const char *fname
= "posix_file";
6934 uint16_t fnum1
= (uint16_t)-1;
6935 uint16_t fnum2
= (uint16_t)-1;
6936 bool correct
= false;
6938 TALLOC_CTX
*frame
= NULL
;
6940 frame
= talloc_stackframe();
6942 printf("Starting POSIX ofd-lock test\n");
6944 if (!torture_open_connection(&cli
, 0)) {
6949 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6951 status
= torture_setup_unix_extensions(cli
);
6952 if (!NT_STATUS_IS_OK(status
)) {
6957 cli_setatr(cli
, fname
, 0, 0);
6958 cli_posix_unlink(cli
, fname
);
6960 /* Open the file twice. */
6961 status
= cli_posix_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6963 if (!NT_STATUS_IS_OK(status
)) {
6964 printf("First POSIX open of %s failed\n", fname
);
6968 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum2
);
6969 if (!NT_STATUS_IS_OK(status
)) {
6970 printf("First POSIX open of %s failed\n", fname
);
6974 /* Set a 0-50 lock on fnum1. */
6975 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
6976 if (!NT_STATUS_IS_OK(status
)) {
6977 printf("POSIX lock (1) failed %s\n", nt_errstr(status
));
6981 /* Set a 60-100 lock on fnum2. */
6982 status
= cli_posix_lock(cli
, fnum2
, 60, 100, false, WRITE_LOCK
);
6983 if (!NT_STATUS_IS_OK(status
)) {
6984 printf("POSIX lock (2) failed %s\n", nt_errstr(status
));
6988 /* close fnum1 - 0-50 lock should go away. */
6989 status
= cli_close(cli
, fnum1
);
6990 if (!NT_STATUS_IS_OK(status
)) {
6991 printf("close failed (%s)\n",
6995 fnum1
= (uint16_t)-1;
6997 /* Change the lock context. */
6998 cli_setpid(cli
, cli_getpid(cli
) + 1);
7000 /* Re-open fnum1. */
7001 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum1
);
7002 if (!NT_STATUS_IS_OK(status
)) {
7003 printf("Third POSIX open of %s failed\n", fname
);
7007 /* 60-100 lock should still be there. */
7008 status
= cli_posix_lock(cli
, fnum1
, 60, 100, false, WRITE_LOCK
);
7009 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
7010 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status
));
7014 /* 0-50 lock should be gone. */
7015 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
7016 if (!NT_STATUS_IS_OK(status
)) {
7017 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status
));
7021 printf("POSIX OFD lock test passed\n");
7026 if (fnum1
!= (uint16_t)-1) {
7027 cli_close(cli
, fnum1
);
7028 fnum1
= (uint16_t)-1;
7030 if (fnum2
!= (uint16_t)-1) {
7031 cli_close(cli
, fnum2
);
7032 fnum2
= (uint16_t)-1;
7035 cli_setatr(cli
, fname
, 0, 0);
7036 cli_posix_unlink(cli
, fname
);
7038 if (!torture_close_connection(cli
)) {
7046 static uint32_t open_attrs_table
[] = {
7047 FILE_ATTRIBUTE_NORMAL
,
7048 FILE_ATTRIBUTE_ARCHIVE
,
7049 FILE_ATTRIBUTE_READONLY
,
7050 FILE_ATTRIBUTE_HIDDEN
,
7051 FILE_ATTRIBUTE_SYSTEM
,
7053 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
7054 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
7055 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
7056 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
7057 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
7058 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
7060 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
7061 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
7062 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
7063 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
7066 struct trunc_open_results
{
7069 uint32_t trunc_attr
;
7070 uint32_t result_attr
;
7073 static struct trunc_open_results attr_results
[] = {
7074 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
7075 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
7076 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
7077 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
7078 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
7079 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
7080 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7081 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7082 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
7083 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7084 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7085 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
7086 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7087 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7088 { 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
},
7089 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7090 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7091 { 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
},
7092 { 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
},
7093 { 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
},
7094 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7095 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7096 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
7097 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7098 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7099 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
7102 static bool run_openattrtest(int dummy
)
7104 static struct cli_state
*cli1
;
7105 const char *fname
= "\\openattr.file";
7107 bool correct
= True
;
7109 unsigned int i
, j
, k
, l
;
7112 printf("starting open attr test\n");
7114 if (!torture_open_connection(&cli1
, 0)) {
7118 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7120 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32_t); i
++) {
7121 cli_setatr(cli1
, fname
, 0, 0);
7122 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7124 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
7125 open_attrs_table
[i
], FILE_SHARE_NONE
,
7126 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7127 if (!NT_STATUS_IS_OK(status
)) {
7128 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
7132 status
= cli_close(cli1
, fnum1
);
7133 if (!NT_STATUS_IS_OK(status
)) {
7134 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
7138 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32_t); j
++) {
7139 status
= cli_ntcreate(cli1
, fname
, 0,
7140 FILE_READ_DATA
|FILE_WRITE_DATA
,
7141 open_attrs_table
[j
],
7142 FILE_SHARE_NONE
, FILE_OVERWRITE
,
7143 0, 0, &fnum1
, NULL
);
7144 if (!NT_STATUS_IS_OK(status
)) {
7145 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
7146 if (attr_results
[l
].num
== k
) {
7147 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7148 k
, open_attrs_table
[i
],
7149 open_attrs_table
[j
],
7150 fname
, NT_STATUS_V(status
), nt_errstr(status
));
7155 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
7156 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7157 k
, open_attrs_table
[i
], open_attrs_table
[j
],
7162 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
7168 status
= cli_close(cli1
, fnum1
);
7169 if (!NT_STATUS_IS_OK(status
)) {
7170 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
7174 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
7175 if (!NT_STATUS_IS_OK(status
)) {
7176 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
7181 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7182 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
7185 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
7186 if (attr_results
[l
].num
== k
) {
7187 if (attr
!= attr_results
[l
].result_attr
||
7188 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
7189 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
7190 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7191 open_attrs_table
[i
],
7192 open_attrs_table
[j
],
7194 attr_results
[l
].result_attr
);
7204 cli_setatr(cli1
, fname
, 0, 0);
7205 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7207 printf("open attr test %s.\n", correct
? "passed" : "failed");
7209 if (!torture_close_connection(cli1
)) {
7215 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
7216 const char *name
, void *state
)
7218 int *matched
= (int *)state
;
7219 if (matched
!= NULL
) {
7222 return NT_STATUS_OK
;
7226 test directory listing speed
7228 static bool run_dirtest(int dummy
)
7231 static struct cli_state
*cli
;
7233 struct timeval core_start
;
7234 bool correct
= True
;
7237 printf("starting directory test\n");
7239 if (!torture_open_connection(&cli
, 0)) {
7243 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7246 for (i
=0;i
<torture_numops
;i
++) {
7248 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
7249 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
7250 fprintf(stderr
,"Failed to open %s\n", fname
);
7253 cli_close(cli
, fnum
);
7256 core_start
= timeval_current();
7259 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
7260 printf("Matched %d\n", matched
);
7263 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
7264 printf("Matched %d\n", matched
);
7267 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
7268 printf("Matched %d\n", matched
);
7270 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
7273 for (i
=0;i
<torture_numops
;i
++) {
7275 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
7276 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7279 if (!torture_close_connection(cli
)) {
7283 printf("finished dirtest\n");
7288 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
7291 struct cli_state
*pcli
= (struct cli_state
*)state
;
7293 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
7295 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7296 return NT_STATUS_OK
;
7298 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7299 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
7300 printf("del_fn: failed to rmdir %s\n,", fname
);
7302 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
7303 printf("del_fn: failed to unlink %s\n,", fname
);
7305 return NT_STATUS_OK
;
7310 sees what IOCTLs are supported
7312 bool torture_ioctl_test(int dummy
)
7314 static struct cli_state
*cli
;
7315 uint16_t device
, function
;
7317 const char *fname
= "\\ioctl.dat";
7321 if (!torture_open_connection(&cli
, 0)) {
7325 printf("starting ioctl test\n");
7327 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7329 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7330 if (!NT_STATUS_IS_OK(status
)) {
7331 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
7335 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
7336 printf("ioctl device info: %s\n", nt_errstr(status
));
7338 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
7339 printf("ioctl job info: %s\n", nt_errstr(status
));
7341 for (device
=0;device
<0x100;device
++) {
7342 printf("ioctl test with device = 0x%x\n", device
);
7343 for (function
=0;function
<0x100;function
++) {
7344 uint32_t code
= (device
<<16) | function
;
7346 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
7348 if (NT_STATUS_IS_OK(status
)) {
7349 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
7351 data_blob_free(&blob
);
7356 if (!torture_close_connection(cli
)) {
7365 tries varients of chkpath
7367 bool torture_chkpath_test(int dummy
)
7369 static struct cli_state
*cli
;
7374 if (!torture_open_connection(&cli
, 0)) {
7378 printf("starting chkpath test\n");
7380 /* cleanup from an old run */
7381 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
7382 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7383 cli_rmdir(cli
, "\\chkpath.dir");
7385 status
= cli_mkdir(cli
, "\\chkpath.dir");
7386 if (!NT_STATUS_IS_OK(status
)) {
7387 printf("mkdir1 failed : %s\n", nt_errstr(status
));
7391 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
7392 if (!NT_STATUS_IS_OK(status
)) {
7393 printf("mkdir2 failed : %s\n", nt_errstr(status
));
7397 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
7399 if (!NT_STATUS_IS_OK(status
)) {
7400 printf("open1 failed (%s)\n", nt_errstr(status
));
7403 cli_close(cli
, fnum
);
7405 status
= cli_chkpath(cli
, "\\chkpath.dir");
7406 if (!NT_STATUS_IS_OK(status
)) {
7407 printf("chkpath1 failed: %s\n", nt_errstr(status
));
7411 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
7412 if (!NT_STATUS_IS_OK(status
)) {
7413 printf("chkpath2 failed: %s\n", nt_errstr(status
));
7417 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
7418 if (!NT_STATUS_IS_OK(status
)) {
7419 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
7420 NT_STATUS_NOT_A_DIRECTORY
);
7422 printf("* chkpath on a file should fail\n");
7426 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
7427 if (!NT_STATUS_IS_OK(status
)) {
7428 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
7429 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
7431 printf("* chkpath on a non existent file should fail\n");
7435 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
7436 if (!NT_STATUS_IS_OK(status
)) {
7437 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
7438 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
7440 printf("* chkpath on a non existent component should fail\n");
7444 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
7445 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7446 cli_rmdir(cli
, "\\chkpath.dir");
7448 if (!torture_close_connection(cli
)) {
7455 static bool run_eatest(int dummy
)
7457 static struct cli_state
*cli
;
7458 const char *fname
= "\\eatest.txt";
7459 bool correct
= True
;
7463 struct ea_struct
*ea_list
= NULL
;
7464 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
7467 printf("starting eatest\n");
7469 if (!torture_open_connection(&cli
, 0)) {
7470 talloc_destroy(mem_ctx
);
7474 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7476 status
= cli_ntcreate(cli
, fname
, 0,
7477 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
7478 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
7479 0x4044, 0, &fnum
, NULL
);
7480 if (!NT_STATUS_IS_OK(status
)) {
7481 printf("open failed - %s\n", nt_errstr(status
));
7482 talloc_destroy(mem_ctx
);
7486 for (i
= 0; i
< 10; i
++) {
7487 fstring ea_name
, ea_val
;
7489 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
7490 memset(ea_val
, (char)i
+1, i
+1);
7491 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
7492 if (!NT_STATUS_IS_OK(status
)) {
7493 printf("ea_set of name %s failed - %s\n", ea_name
,
7495 talloc_destroy(mem_ctx
);
7500 cli_close(cli
, fnum
);
7501 for (i
= 0; i
< 10; i
++) {
7502 fstring ea_name
, ea_val
;
7504 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
7505 memset(ea_val
, (char)i
+1, i
+1);
7506 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
7507 if (!NT_STATUS_IS_OK(status
)) {
7508 printf("ea_set of name %s failed - %s\n", ea_name
,
7510 talloc_destroy(mem_ctx
);
7515 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
7516 if (!NT_STATUS_IS_OK(status
)) {
7517 printf("ea_get list failed - %s\n", nt_errstr(status
));
7521 printf("num_eas = %d\n", (int)num_eas
);
7523 if (num_eas
!= 20) {
7524 printf("Should be 20 EA's stored... failing.\n");
7528 for (i
= 0; i
< num_eas
; i
++) {
7529 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
7530 dump_data(0, ea_list
[i
].value
.data
,
7531 ea_list
[i
].value
.length
);
7534 /* Setting EA's to zero length deletes them. Test this */
7535 printf("Now deleting all EA's - case indepenent....\n");
7538 cli_set_ea_path(cli
, fname
, "", "", 0);
7540 for (i
= 0; i
< 20; i
++) {
7542 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
7543 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
7544 if (!NT_STATUS_IS_OK(status
)) {
7545 printf("ea_set of name %s failed - %s\n", ea_name
,
7547 talloc_destroy(mem_ctx
);
7553 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
7554 if (!NT_STATUS_IS_OK(status
)) {
7555 printf("ea_get list failed - %s\n", nt_errstr(status
));
7559 printf("num_eas = %d\n", (int)num_eas
);
7560 for (i
= 0; i
< num_eas
; i
++) {
7561 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
7562 dump_data(0, ea_list
[i
].value
.data
,
7563 ea_list
[i
].value
.length
);
7567 printf("deleting EA's failed.\n");
7571 /* Try and delete a non existent EA. */
7572 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
7573 if (!NT_STATUS_IS_OK(status
)) {
7574 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7579 talloc_destroy(mem_ctx
);
7580 if (!torture_close_connection(cli
)) {
7587 static bool run_dirtest1(int dummy
)
7590 static struct cli_state
*cli
;
7593 bool correct
= True
;
7595 printf("starting directory test\n");
7597 if (!torture_open_connection(&cli
, 0)) {
7601 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7603 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7604 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7605 cli_rmdir(cli
, "\\LISTDIR");
7606 cli_mkdir(cli
, "\\LISTDIR");
7608 /* Create 1000 files and 1000 directories. */
7609 for (i
=0;i
<1000;i
++) {
7611 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
7612 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
7613 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
7614 0, 0, &fnum
, NULL
))) {
7615 fprintf(stderr
,"Failed to open %s\n", fname
);
7618 cli_close(cli
, fnum
);
7620 for (i
=0;i
<1000;i
++) {
7622 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
7623 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
7624 fprintf(stderr
,"Failed to open %s\n", fname
);
7629 /* Now ensure that doing an old list sees both files and directories. */
7631 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7632 printf("num_seen = %d\n", num_seen
);
7633 /* We should see 100 files + 1000 directories + . and .. */
7634 if (num_seen
!= 2002)
7637 /* Ensure if we have the "must have" bits we only see the
7641 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7642 printf("num_seen = %d\n", num_seen
);
7643 if (num_seen
!= 1002)
7647 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7648 printf("num_seen = %d\n", num_seen
);
7649 if (num_seen
!= 1000)
7652 /* Delete everything. */
7653 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7654 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7655 cli_rmdir(cli
, "\\LISTDIR");
7658 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
7659 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
7660 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
7663 if (!torture_close_connection(cli
)) {
7667 printf("finished dirtest1\n");
7672 static bool run_error_map_extract(int dummy
) {
7674 static struct cli_state
*c_dos
;
7675 static struct cli_state
*c_nt
;
7687 /* NT-Error connection */
7689 disable_spnego
= true;
7690 if (!(c_nt
= open_nbt_connection())) {
7691 disable_spnego
= false;
7694 disable_spnego
= false;
7696 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
7699 if (!NT_STATUS_IS_OK(status
)) {
7700 printf("%s rejected the NT-error negprot (%s)\n", host
,
7706 status
= cli_session_setup_anon(c_nt
);
7707 if (!NT_STATUS_IS_OK(status
)) {
7708 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
7712 /* DOS-Error connection */
7714 disable_spnego
= true;
7715 force_dos_errors
= true;
7716 if (!(c_dos
= open_nbt_connection())) {
7717 disable_spnego
= false;
7718 force_dos_errors
= false;
7721 disable_spnego
= false;
7722 force_dos_errors
= false;
7724 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
7726 if (!NT_STATUS_IS_OK(status
)) {
7727 printf("%s rejected the DOS-error negprot (%s)\n", host
,
7729 cli_shutdown(c_dos
);
7733 status
= cli_session_setup_anon(c_dos
);
7734 if (!NT_STATUS_IS_OK(status
)) {
7735 printf("%s rejected the DOS-error initial session setup (%s)\n",
7736 host
, nt_errstr(status
));
7740 c_nt
->map_dos_errors
= false;
7741 c_dos
->map_dos_errors
= false;
7743 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
7744 struct cli_credentials
*user_creds
= NULL
;
7746 fstr_sprintf(user
, "%X", error
);
7748 user_creds
= cli_session_creds_init(talloc_tos(),
7753 false, /* use_kerberos */
7754 false, /* fallback_after_kerberos */
7755 false, /* use_ccache */
7756 false); /* password_is_nt_hash */
7757 if (user_creds
== NULL
) {
7758 printf("cli_session_creds_init(%s) failed\n", user
);
7762 status
= cli_session_setup_creds(c_nt
, user_creds
);
7763 if (NT_STATUS_IS_OK(status
)) {
7764 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7767 /* Case #1: 32-bit NT errors */
7768 if (!NT_STATUS_IS_DOS(status
)) {
7771 printf("/** Dos error on NT connection! (%s) */\n",
7773 nt_status
= NT_STATUS(0xc0000000);
7776 status
= cli_session_setup_creds(c_dos
, user_creds
);
7777 if (NT_STATUS_IS_OK(status
)) {
7778 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7781 /* Case #1: 32-bit NT errors */
7782 if (NT_STATUS_IS_DOS(status
)) {
7783 printf("/** NT error on DOS connection! (%s) */\n",
7785 errnum
= errclass
= 0;
7787 errclass
= NT_STATUS_DOS_CLASS(status
);
7788 errnum
= NT_STATUS_DOS_CODE(status
);
7791 if (NT_STATUS_V(nt_status
) != error
) {
7792 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7793 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
7794 get_nt_error_c_code(talloc_tos(), nt_status
));
7797 printf("\t{%s,\t%s,\t%s},\n",
7798 smb_dos_err_class(errclass
),
7799 smb_dos_err_name(errclass
, errnum
),
7800 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
7802 TALLOC_FREE(user_creds
);
7807 static bool run_sesssetup_bench(int dummy
)
7809 static struct cli_state
*c
;
7810 const char *fname
= "\\file.dat";
7815 if (!torture_open_connection(&c
, 0)) {
7819 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7820 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7821 FILE_DELETE_ON_CLOSE
, 0, &fnum
, NULL
);
7822 if (!NT_STATUS_IS_OK(status
)) {
7823 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7827 for (i
=0; i
<torture_numops
; i
++) {
7828 status
= cli_session_setup_creds(c
, torture_creds
);
7829 if (!NT_STATUS_IS_OK(status
)) {
7830 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7831 __location__
, nt_errstr(status
));
7835 d_printf("\r%d ", (int)cli_state_get_uid(c
));
7837 status
= cli_ulogoff(c
);
7838 if (!NT_STATUS_IS_OK(status
)) {
7839 d_printf("(%s) cli_ulogoff failed: %s\n",
7840 __location__
, nt_errstr(status
));
7848 static bool subst_test(const char *str
, const char *user
, const char *domain
,
7849 uid_t uid
, gid_t gid
, const char *expected
)
7854 subst
= talloc_sub_specified(talloc_tos(), str
, user
, NULL
, domain
, uid
, gid
);
7856 if (strcmp(subst
, expected
) != 0) {
7857 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7858 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
7867 static void chain1_open_completion(struct tevent_req
*req
)
7871 status
= cli_openx_recv(req
, &fnum
);
7874 d_printf("cli_openx_recv returned %s: %d\n",
7876 NT_STATUS_IS_OK(status
) ? fnum
: -1);
7879 static void chain1_write_completion(struct tevent_req
*req
)
7883 status
= cli_write_andx_recv(req
, &written
);
7886 d_printf("cli_write_andx_recv returned %s: %d\n",
7888 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
7891 static void chain1_close_completion(struct tevent_req
*req
)
7894 bool *done
= (bool *)tevent_req_callback_data_void(req
);
7896 status
= cli_close_recv(req
);
7901 d_printf("cli_close returned %s\n", nt_errstr(status
));
7904 static bool run_chain1(int dummy
)
7906 struct cli_state
*cli1
;
7907 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
7908 struct tevent_req
*reqs
[3], *smbreqs
[3];
7910 const char *str
= "foobar";
7913 printf("starting chain1 test\n");
7914 if (!torture_open_connection(&cli1
, 0)) {
7918 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7920 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, "\\test",
7921 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
7922 if (reqs
[0] == NULL
) return false;
7923 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
7926 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
7927 (const uint8_t *)str
, 0, strlen(str
)+1,
7928 smbreqs
, 1, &smbreqs
[1]);
7929 if (reqs
[1] == NULL
) return false;
7930 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
7932 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
7933 if (reqs
[2] == NULL
) return false;
7934 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
7936 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
7937 if (!NT_STATUS_IS_OK(status
)) {
7942 tevent_loop_once(evt
);
7945 torture_close_connection(cli1
);
7949 static void chain2_sesssetup_completion(struct tevent_req
*req
)
7952 status
= cli_session_setup_guest_recv(req
);
7953 d_printf("sesssetup returned %s\n", nt_errstr(status
));
7956 static void chain2_tcon_completion(struct tevent_req
*req
)
7958 bool *done
= (bool *)tevent_req_callback_data_void(req
);
7960 status
= cli_tcon_andx_recv(req
);
7961 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
7965 static bool run_chain2(int dummy
)
7967 struct cli_state
*cli1
;
7968 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
7969 struct tevent_req
*reqs
[2], *smbreqs
[2];
7972 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
7974 printf("starting chain2 test\n");
7975 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
7976 port_to_use
, SMB_SIGNING_DEFAULT
, flags
);
7977 if (!NT_STATUS_IS_OK(status
)) {
7981 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7983 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
7985 if (reqs
[0] == NULL
) return false;
7986 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
7988 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
7989 "?????", NULL
, 0, &smbreqs
[1]);
7990 if (reqs
[1] == NULL
) return false;
7991 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
7993 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
7994 if (!NT_STATUS_IS_OK(status
)) {
7999 tevent_loop_once(evt
);
8002 torture_close_connection(cli1
);
8007 struct torture_createdel_state
{
8008 struct tevent_context
*ev
;
8009 struct cli_state
*cli
;
8012 static void torture_createdel_created(struct tevent_req
*subreq
);
8013 static void torture_createdel_closed(struct tevent_req
*subreq
);
8015 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
8016 struct tevent_context
*ev
,
8017 struct cli_state
*cli
,
8020 struct tevent_req
*req
, *subreq
;
8021 struct torture_createdel_state
*state
;
8023 req
= tevent_req_create(mem_ctx
, &state
,
8024 struct torture_createdel_state
);
8031 subreq
= cli_ntcreate_send(
8032 state
, ev
, cli
, name
, 0,
8033 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
8034 FILE_ATTRIBUTE_NORMAL
,
8035 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8036 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
8038 if (tevent_req_nomem(subreq
, req
)) {
8039 return tevent_req_post(req
, ev
);
8041 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
8045 static void torture_createdel_created(struct tevent_req
*subreq
)
8047 struct tevent_req
*req
= tevent_req_callback_data(
8048 subreq
, struct tevent_req
);
8049 struct torture_createdel_state
*state
= tevent_req_data(
8050 req
, struct torture_createdel_state
);
8054 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
8055 TALLOC_FREE(subreq
);
8056 if (tevent_req_nterror(req
, status
)) {
8057 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8058 nt_errstr(status
)));
8062 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
8063 if (tevent_req_nomem(subreq
, req
)) {
8066 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
8069 static void torture_createdel_closed(struct tevent_req
*subreq
)
8071 struct tevent_req
*req
= tevent_req_callback_data(
8072 subreq
, struct tevent_req
);
8075 status
= cli_close_recv(subreq
);
8076 if (tevent_req_nterror(req
, status
)) {
8077 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
8080 tevent_req_done(req
);
8083 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
8085 return tevent_req_simple_recv_ntstatus(req
);
8088 struct torture_createdels_state
{
8089 struct tevent_context
*ev
;
8090 struct cli_state
*cli
;
8091 const char *base_name
;
8095 struct tevent_req
**reqs
;
8098 static void torture_createdels_done(struct tevent_req
*subreq
);
8100 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
8101 struct tevent_context
*ev
,
8102 struct cli_state
*cli
,
8103 const char *base_name
,
8107 struct tevent_req
*req
;
8108 struct torture_createdels_state
*state
;
8111 req
= tevent_req_create(mem_ctx
, &state
,
8112 struct torture_createdels_state
);
8118 state
->base_name
= talloc_strdup(state
, base_name
);
8119 if (tevent_req_nomem(state
->base_name
, req
)) {
8120 return tevent_req_post(req
, ev
);
8122 state
->num_files
= MAX(num_parallel
, num_files
);
8124 state
->received
= 0;
8126 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
8127 if (tevent_req_nomem(state
->reqs
, req
)) {
8128 return tevent_req_post(req
, ev
);
8131 for (i
=0; i
<num_parallel
; i
++) {
8134 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
8136 if (tevent_req_nomem(name
, req
)) {
8137 return tevent_req_post(req
, ev
);
8139 state
->reqs
[i
] = torture_createdel_send(
8140 state
->reqs
, state
->ev
, state
->cli
, name
);
8141 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
8142 return tevent_req_post(req
, ev
);
8144 name
= talloc_move(state
->reqs
[i
], &name
);
8145 tevent_req_set_callback(state
->reqs
[i
],
8146 torture_createdels_done
, req
);
8152 static void torture_createdels_done(struct tevent_req
*subreq
)
8154 struct tevent_req
*req
= tevent_req_callback_data(
8155 subreq
, struct tevent_req
);
8156 struct torture_createdels_state
*state
= tevent_req_data(
8157 req
, struct torture_createdels_state
);
8158 size_t num_parallel
= talloc_array_length(state
->reqs
);
8163 status
= torture_createdel_recv(subreq
);
8164 if (!NT_STATUS_IS_OK(status
)){
8165 DEBUG(10, ("torture_createdel_recv returned %s\n",
8166 nt_errstr(status
)));
8167 TALLOC_FREE(subreq
);
8168 tevent_req_nterror(req
, status
);
8172 for (i
=0; i
<num_parallel
; i
++) {
8173 if (subreq
== state
->reqs
[i
]) {
8177 if (i
== num_parallel
) {
8178 DEBUG(10, ("received something we did not send\n"));
8179 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
8182 TALLOC_FREE(state
->reqs
[i
]);
8184 if (state
->sent
>= state
->num_files
) {
8185 tevent_req_done(req
);
8189 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
8191 if (tevent_req_nomem(name
, req
)) {
8194 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
8196 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
8199 name
= talloc_move(state
->reqs
[i
], &name
);
8200 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
8204 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
8206 return tevent_req_simple_recv_ntstatus(req
);
8209 struct swallow_notify_state
{
8210 struct tevent_context
*ev
;
8211 struct cli_state
*cli
;
8213 uint32_t completion_filter
;
8215 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
8219 static void swallow_notify_done(struct tevent_req
*subreq
);
8221 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
8222 struct tevent_context
*ev
,
8223 struct cli_state
*cli
,
8225 uint32_t completion_filter
,
8227 bool (*fn
)(uint32_t action
,
8232 struct tevent_req
*req
, *subreq
;
8233 struct swallow_notify_state
*state
;
8235 req
= tevent_req_create(mem_ctx
, &state
,
8236 struct swallow_notify_state
);
8243 state
->completion_filter
= completion_filter
;
8244 state
->recursive
= recursive
;
8248 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
8249 0xffff, state
->completion_filter
,
8251 if (tevent_req_nomem(subreq
, req
)) {
8252 return tevent_req_post(req
, ev
);
8254 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
8258 static void swallow_notify_done(struct tevent_req
*subreq
)
8260 struct tevent_req
*req
= tevent_req_callback_data(
8261 subreq
, struct tevent_req
);
8262 struct swallow_notify_state
*state
= tevent_req_data(
8263 req
, struct swallow_notify_state
);
8265 uint32_t i
, num_changes
;
8266 struct notify_change
*changes
;
8268 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
8269 TALLOC_FREE(subreq
);
8270 if (!NT_STATUS_IS_OK(status
)) {
8271 DEBUG(10, ("cli_notify_recv returned %s\n",
8272 nt_errstr(status
)));
8273 tevent_req_nterror(req
, status
);
8277 for (i
=0; i
<num_changes
; i
++) {
8278 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
8280 TALLOC_FREE(changes
);
8282 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
8283 0xffff, state
->completion_filter
,
8285 if (tevent_req_nomem(subreq
, req
)) {
8288 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
8291 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
8293 if (DEBUGLEVEL
> 5) {
8294 d_printf("%d %s\n", (int)action
, name
);
8299 static void notify_bench_done(struct tevent_req
*req
)
8301 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
8305 static bool run_notify_bench(int dummy
)
8307 const char *dname
= "\\notify-bench";
8308 struct tevent_context
*ev
;
8311 struct tevent_req
*req1
;
8312 struct tevent_req
*req2
= NULL
;
8313 int i
, num_unc_names
;
8314 int num_finished
= 0;
8316 printf("starting notify-bench test\n");
8318 if (use_multishare_conn
) {
8320 unc_list
= file_lines_load(multishare_conn_fname
,
8321 &num_unc_names
, 0, NULL
);
8322 if (!unc_list
|| num_unc_names
<= 0) {
8323 d_printf("Failed to load unc names list from '%s'\n",
8324 multishare_conn_fname
);
8327 TALLOC_FREE(unc_list
);
8332 ev
= samba_tevent_context_init(talloc_tos());
8334 d_printf("tevent_context_init failed\n");
8338 for (i
=0; i
<num_unc_names
; i
++) {
8339 struct cli_state
*cli
;
8342 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8344 if (base_fname
== NULL
) {
8348 if (!torture_open_connection(&cli
, i
)) {
8352 status
= cli_ntcreate(cli
, dname
, 0,
8353 MAXIMUM_ALLOWED_ACCESS
,
8354 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
8356 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
8359 if (!NT_STATUS_IS_OK(status
)) {
8360 d_printf("Could not create %s: %s\n", dname
,
8365 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
8366 FILE_NOTIFY_CHANGE_FILE_NAME
|
8367 FILE_NOTIFY_CHANGE_DIR_NAME
|
8368 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
8369 FILE_NOTIFY_CHANGE_LAST_WRITE
,
8370 false, print_notifies
, NULL
);
8372 d_printf("Could not create notify request\n");
8376 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
8377 base_fname
, 10, torture_numops
);
8379 d_printf("Could not create createdels request\n");
8382 TALLOC_FREE(base_fname
);
8384 tevent_req_set_callback(req2
, notify_bench_done
,
8388 while (num_finished
< num_unc_names
) {
8390 ret
= tevent_loop_once(ev
);
8392 d_printf("tevent_loop_once failed\n");
8397 if (!tevent_req_poll(req2
, ev
)) {
8398 d_printf("tevent_req_poll failed\n");
8401 status
= torture_createdels_recv(req2
);
8402 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
8407 static bool run_mangle1(int dummy
)
8409 struct cli_state
*cli
;
8410 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
8414 time_t change_time
, access_time
, write_time
;
8418 printf("starting mangle1 test\n");
8419 if (!torture_open_connection(&cli
, 0)) {
8423 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8425 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
8426 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8428 if (!NT_STATUS_IS_OK(status
)) {
8429 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8432 cli_close(cli
, fnum
);
8434 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
8435 if (!NT_STATUS_IS_OK(status
)) {
8436 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8440 d_printf("alt_name: %s\n", alt_name
);
8442 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
8443 if (!NT_STATUS_IS_OK(status
)) {
8444 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
8448 cli_close(cli
, fnum
);
8450 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
8451 &write_time
, &size
, &mode
);
8452 if (!NT_STATUS_IS_OK(status
)) {
8453 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
8461 static NTSTATUS
mangle_illegal_list_shortname_fn(const char *mntpoint
,
8462 struct file_info
*f
,
8466 if (f
->short_name
== NULL
) {
8467 return NT_STATUS_OK
;
8470 if (strlen(f
->short_name
) == 0) {
8471 return NT_STATUS_OK
;
8474 printf("unexpected shortname: %s\n", f
->short_name
);
8476 return NT_STATUS_OBJECT_NAME_INVALID
;
8479 static NTSTATUS
mangle_illegal_list_name_fn(const char *mntpoint
,
8480 struct file_info
*f
,
8486 printf("name: %s\n", f
->name
);
8487 fstrcpy(name
, f
->name
);
8488 return NT_STATUS_OK
;
8491 static bool run_mangle_illegal(int dummy
)
8493 struct cli_state
*cli
= NULL
;
8494 struct cli_state
*cli_posix
= NULL
;
8495 const char *fname
= "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8496 const char *illegal_fname
= "MANGLE_ILLEGAL/foo:bar";
8497 char *mangled_path
= NULL
;
8503 printf("starting mangle-illegal test\n");
8505 if (!torture_open_connection(&cli
, 0)) {
8509 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8511 if (!torture_open_connection(&cli_posix
, 0)) {
8515 smbXcli_conn_set_sockopt(cli_posix
->conn
, sockops
);
8517 status
= torture_setup_unix_extensions(cli_posix
);
8518 if (!NT_STATUS_IS_OK(status
)) {
8522 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
8523 status
= cli_mkdir(cli
, "\\MANGLE_ILLEGAL");
8524 if (!NT_STATUS_IS_OK(status
)) {
8525 printf("mkdir1 failed : %s\n", nt_errstr(status
));
8530 * Create a file with illegal NTFS characters and test that we
8531 * get a usable mangled name
8534 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
8535 cli_posix_unlink(cli_posix
, illegal_fname
);
8537 status
= cli_posix_open(cli_posix
, illegal_fname
, O_RDWR
|O_CREAT
|O_EXCL
,
8539 if (!NT_STATUS_IS_OK(status
)) {
8540 printf("POSIX create of %s failed (%s)\n",
8541 illegal_fname
, nt_errstr(status
));
8545 status
= cli_close(cli_posix
, fnum
);
8546 if (!NT_STATUS_IS_OK(status
)) {
8547 printf("close failed (%s)\n", nt_errstr(status
));
8551 status
= cli_list(cli
, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn
, &name
);
8552 if (!NT_STATUS_IS_OK(status
)) {
8553 d_printf("cli_list failed: %s\n", nt_errstr(status
));
8557 mangled_path
= talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name
);
8558 if (mangled_path
== NULL
) {
8562 status
= cli_openx(cli
, mangled_path
, O_RDONLY
, DENY_NONE
, &fnum
);
8563 if (!NT_STATUS_IS_OK(status
)) {
8564 d_printf("cli_openx(%s) failed: %s\n", mangled_path
, nt_errstr(status
));
8565 TALLOC_FREE(mangled_path
);
8568 TALLOC_FREE(mangled_path
);
8569 cli_close(cli
, fnum
);
8571 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
8572 cli_posix_unlink(cli_posix
, illegal_fname
);
8575 * Create a file with a long name and check that we got *no* short name.
8578 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
8579 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8581 if (!NT_STATUS_IS_OK(status
)) {
8582 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8585 cli_close(cli
, fnum
);
8587 status
= cli_list(cli
, fname
, 0, mangle_illegal_list_shortname_fn
, &alt_name
);
8588 if (!NT_STATUS_IS_OK(status
)) {
8589 d_printf("cli_list failed\n");
8593 cli_unlink(cli
, fname
, 0);
8594 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
8596 if (!torture_close_connection(cli_posix
)) {
8600 if (!torture_close_connection(cli
)) {
8607 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
8609 size_t *to_pull
= (size_t *)priv
;
8610 size_t thistime
= *to_pull
;
8612 thistime
= MIN(thistime
, n
);
8613 if (thistime
== 0) {
8617 memset(buf
, 0, thistime
);
8618 *to_pull
-= thistime
;
8622 static bool run_windows_write(int dummy
)
8624 struct cli_state
*cli1
;
8628 const char *fname
= "\\writetest.txt";
8629 struct timeval start_time
;
8634 printf("starting windows_write test\n");
8635 if (!torture_open_connection(&cli1
, 0)) {
8639 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
8640 if (!NT_STATUS_IS_OK(status
)) {
8641 printf("open failed (%s)\n", nt_errstr(status
));
8645 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
8647 start_time
= timeval_current();
8649 for (i
=0; i
<torture_numops
; i
++) {
8651 off_t start
= i
* torture_blocksize
;
8652 size_t to_pull
= torture_blocksize
- 1;
8654 status
= cli_writeall(cli1
, fnum
, 0, &c
,
8655 start
+ torture_blocksize
- 1, 1, NULL
);
8656 if (!NT_STATUS_IS_OK(status
)) {
8657 printf("cli_write failed: %s\n", nt_errstr(status
));
8661 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
8662 null_source
, &to_pull
);
8663 if (!NT_STATUS_IS_OK(status
)) {
8664 printf("cli_push returned: %s\n", nt_errstr(status
));
8669 seconds
= timeval_elapsed(&start_time
);
8670 kbytes
= (double)torture_blocksize
* torture_numops
;
8673 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
8674 (double)seconds
, (int)(kbytes
/seconds
));
8678 cli_close(cli1
, fnum
);
8679 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8680 torture_close_connection(cli1
);
8684 static size_t calc_expected_return(struct cli_state
*cli
, size_t len_requested
)
8686 size_t max_pdu
= 0x1FFFF;
8688 if (cli
->server_posix_capabilities
& CIFS_UNIX_LARGE_READ_CAP
) {
8692 if (smb1cli_conn_signing_is_active(cli
->conn
)) {
8696 if (smb1cli_conn_encryption_on(cli
->conn
)) {
8697 max_pdu
= CLI_BUFFER_SIZE
;
8700 if ((len_requested
& 0xFFFF0000) == 0xFFFF0000) {
8701 len_requested
&= 0xFFFF;
8704 return MIN(len_requested
,
8705 max_pdu
- (MIN_SMB_SIZE
+ VWV(12) + 1 /* padding byte */));
8708 static bool check_read_call(struct cli_state
*cli
,
8711 size_t len_requested
)
8714 struct tevent_req
*subreq
= NULL
;
8715 ssize_t len_read
= 0;
8716 size_t len_expected
= 0;
8717 struct tevent_context
*ev
= NULL
;
8719 ev
= samba_tevent_context_init(talloc_tos());
8724 subreq
= cli_read_andx_send(talloc_tos(),
8731 if (!tevent_req_poll_ntstatus(subreq
, ev
, &status
)) {
8735 status
= cli_read_andx_recv(subreq
, &len_read
, &buf
);
8736 if (!NT_STATUS_IS_OK(status
)) {
8737 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status
));
8741 TALLOC_FREE(subreq
);
8744 len_expected
= calc_expected_return(cli
, len_requested
);
8746 if (len_expected
> 0x10000 && len_read
== 0x10000) {
8747 /* Windows servers only return a max of 0x10000,
8748 doesn't matter if you set CAP_LARGE_READX in
8749 the client sessionsetupX call or not. */
8750 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8751 (unsigned int)len_requested
);
8752 } else if (len_read
!= len_expected
) {
8753 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8754 (unsigned int)len_requested
,
8755 (unsigned int)len_read
,
8756 (unsigned int)len_expected
);
8759 d_printf("Correct read reply.\n");
8765 /* Test large readX variants. */
8766 static bool large_readx_tests(struct cli_state
*cli
,
8770 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8771 if (check_read_call(cli
, fnum
, buf
, 0xFFFF0001) == false) {
8774 /* A read of 0x10000 should return 0x10000 bytes. */
8775 if (check_read_call(cli
, fnum
, buf
, 0x10000) == false) {
8778 /* A read of 0x10000 should return 0x10001 bytes. */
8779 if (check_read_call(cli
, fnum
, buf
, 0x10001) == false) {
8782 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8783 the requested number of bytes. */
8784 if (check_read_call(cli
, fnum
, buf
, 0x1FFFF - (MIN_SMB_SIZE
+ VWV(12))) == false) {
8787 /* A read of 1MB should return 1MB bytes (on Samba). */
8788 if (check_read_call(cli
, fnum
, buf
, 0x100000) == false) {
8792 if (check_read_call(cli
, fnum
, buf
, 0x20001) == false) {
8795 if (check_read_call(cli
, fnum
, buf
, 0x22000001) == false) {
8798 if (check_read_call(cli
, fnum
, buf
, 0xFFFE0001) == false) {
8804 static bool run_large_readx(int dummy
)
8806 uint8_t *buf
= NULL
;
8807 struct cli_state
*cli1
= NULL
;
8808 struct cli_state
*cli2
= NULL
;
8809 bool correct
= false;
8810 const char *fname
= "\\large_readx.dat";
8812 uint16_t fnum1
= UINT16_MAX
;
8813 uint32_t normal_caps
= 0;
8814 size_t file_size
= 20*1024*1024;
8815 TALLOC_CTX
*frame
= talloc_stackframe();
8819 enum smb_signing_setting signing_setting
;
8820 enum protocol_types protocol
;
8824 .signing_setting
= SMB_SIGNING_IF_REQUIRED
,
8825 .protocol
= PROTOCOL_NT1
,
8827 .name
= "NT1 - SIGNING_REQUIRED",
8828 .signing_setting
= SMB_SIGNING_REQUIRED
,
8829 .protocol
= PROTOCOL_NT1
,
8833 printf("starting large_readx test\n");
8835 if (!torture_open_connection(&cli1
, 0)) {
8839 normal_caps
= smb1cli_conn_capabilities(cli1
->conn
);
8841 if (!(normal_caps
& CAP_LARGE_READX
)) {
8842 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8843 (unsigned int)normal_caps
);
8847 /* Create a file of size 4MB. */
8848 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
8849 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8850 0, 0, &fnum1
, NULL
);
8852 if (!NT_STATUS_IS_OK(status
)) {
8853 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8857 /* Write file_size bytes. */
8858 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
8863 status
= cli_writeall(cli1
,
8870 if (!NT_STATUS_IS_OK(status
)) {
8871 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
8875 status
= cli_close(cli1
, fnum1
);
8876 if (!NT_STATUS_IS_OK(status
)) {
8877 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8883 for (i
=0; i
< ARRAY_SIZE(runs
); i
++) {
8884 enum smb_signing_setting saved_signing_setting
= signing_state
;
8885 uint16_t fnum2
= -1;
8888 (runs
[i
].signing_setting
== SMB_SIGNING_REQUIRED
))
8890 d_printf("skip[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
8894 d_printf("run[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
8896 signing_state
= runs
[i
].signing_setting
;
8897 cli2
= open_nbt_connection();
8898 signing_state
= saved_signing_setting
;
8903 status
= smbXcli_negprot(cli2
->conn
,
8907 if (!NT_STATUS_IS_OK(status
)) {
8911 status
= cli_session_setup_creds(cli2
, torture_creds
);
8912 if (!NT_STATUS_IS_OK(status
)) {
8916 status
= cli_tree_connect(cli2
,
8920 if (!NT_STATUS_IS_OK(status
)) {
8924 cli_set_timeout(cli2
, 120000); /* set a really long timeout (2 minutes) */
8926 normal_caps
= smb1cli_conn_capabilities(cli2
->conn
);
8928 if (!(normal_caps
& CAP_LARGE_READX
)) {
8929 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8930 (unsigned int)normal_caps
);
8935 if (force_cli_encryption(cli2
, share
) == false) {
8938 } else if (SERVER_HAS_UNIX_CIFS(cli2
)) {
8939 uint16_t major
, minor
;
8940 uint32_t caplow
, caphigh
;
8942 status
= cli_unix_extensions_version(cli2
,
8945 if (!NT_STATUS_IS_OK(status
)) {
8950 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
,
8951 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
8952 0, 0, &fnum2
, NULL
);
8953 if (!NT_STATUS_IS_OK(status
)) {
8954 d_printf("Second open %s failed: %s\n", fname
, nt_errstr(status
));
8958 /* All reads must return less than file_size bytes. */
8959 if (!large_readx_tests(cli2
, fnum2
, buf
)) {
8963 status
= cli_close(cli2
, fnum2
);
8964 if (!NT_STATUS_IS_OK(status
)) {
8965 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8970 if (!torture_close_connection(cli2
)) {
8977 printf("Success on large_readx test\n");
8982 if (!torture_close_connection(cli2
)) {
8988 if (fnum1
!= UINT16_MAX
) {
8989 status
= cli_close(cli1
, fnum1
);
8990 if (!NT_STATUS_IS_OK(status
)) {
8991 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8996 status
= cli_unlink(cli1
, fname
,
8997 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8998 if (!NT_STATUS_IS_OK(status
)) {
8999 printf("unlink failed (%s)\n", nt_errstr(status
));
9002 if (!torture_close_connection(cli1
)) {
9009 printf("finished large_readx test\n");
9013 static bool run_cli_echo(int dummy
)
9015 struct cli_state
*cli
;
9018 printf("starting cli_echo test\n");
9019 if (!torture_open_connection(&cli
, 0)) {
9022 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9024 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
9026 d_printf("cli_echo returned %s\n", nt_errstr(status
));
9028 torture_close_connection(cli
);
9029 return NT_STATUS_IS_OK(status
);
9032 static bool run_uid_regression_test(int dummy
)
9034 static struct cli_state
*cli
;
9037 bool correct
= True
;
9038 struct smbXcli_tcon
*orig_tcon
= NULL
;
9041 printf("starting uid regression test\n");
9043 if (!torture_open_connection(&cli
, 0)) {
9047 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9049 /* Ok - now save then logoff our current user. */
9050 old_vuid
= cli_state_get_uid(cli
);
9052 status
= cli_ulogoff(cli
);
9053 if (!NT_STATUS_IS_OK(status
)) {
9054 d_printf("(%s) cli_ulogoff failed: %s\n",
9055 __location__
, nt_errstr(status
));
9060 cli_state_set_uid(cli
, old_vuid
);
9062 /* Try an operation. */
9063 status
= cli_mkdir(cli
, "\\uid_reg_test");
9064 if (NT_STATUS_IS_OK(status
)) {
9065 d_printf("(%s) cli_mkdir succeeded\n",
9070 /* Should be bad uid. */
9071 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
9072 NT_STATUS_USER_SESSION_DELETED
)) {
9078 old_cnum
= cli_state_get_tid(cli
);
9079 orig_tcon
= cli_state_save_tcon(cli
);
9080 if (orig_tcon
== NULL
) {
9085 /* Now try a SMBtdis with the invald vuid set to zero. */
9086 cli_state_set_uid(cli
, 0);
9088 /* This should succeed. */
9089 status
= cli_tdis(cli
);
9091 if (NT_STATUS_IS_OK(status
)) {
9092 d_printf("First tdis with invalid vuid should succeed.\n");
9094 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
9096 cli_state_restore_tcon(cli
, orig_tcon
);
9100 cli_state_restore_tcon(cli
, orig_tcon
);
9101 cli_state_set_uid(cli
, old_vuid
);
9102 cli_state_set_tid(cli
, old_cnum
);
9104 /* This should fail. */
9105 status
= cli_tdis(cli
);
9106 if (NT_STATUS_IS_OK(status
)) {
9107 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9111 /* Should be bad tid. */
9112 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
9113 NT_STATUS_NETWORK_NAME_DELETED
)) {
9119 cli_rmdir(cli
, "\\uid_reg_test");
9128 static const char *illegal_chars
= "*\\/?<>|\":";
9129 static char force_shortname_chars
[] = " +,.[];=\177";
9131 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
9132 const char *mask
, void *state
)
9134 struct cli_state
*pcli
= (struct cli_state
*)state
;
9136 NTSTATUS status
= NT_STATUS_OK
;
9138 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
9140 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
9141 return NT_STATUS_OK
;
9143 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
9144 status
= cli_rmdir(pcli
, fname
);
9145 if (!NT_STATUS_IS_OK(status
)) {
9146 printf("del_fn: failed to rmdir %s\n,", fname
);
9149 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9150 if (!NT_STATUS_IS_OK(status
)) {
9151 printf("del_fn: failed to unlink %s\n,", fname
);
9163 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
9164 const char *name
, void *state
)
9166 struct sn_state
*s
= (struct sn_state
*)state
;
9170 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9171 i
, finfo
->name
, finfo
->short_name
);
9174 if (strchr(force_shortname_chars
, i
)) {
9175 if (!finfo
->short_name
) {
9176 /* Shortname not created when it should be. */
9177 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9178 __location__
, finfo
->name
, i
);
9181 } else if (finfo
->short_name
){
9182 /* Shortname created when it should not be. */
9183 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9184 __location__
, finfo
->short_name
, finfo
->name
);
9188 return NT_STATUS_OK
;
9191 static bool run_shortname_test(int dummy
)
9193 static struct cli_state
*cli
;
9194 bool correct
= True
;
9200 printf("starting shortname test\n");
9202 if (!torture_open_connection(&cli
, 0)) {
9206 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9208 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
9209 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
9210 cli_rmdir(cli
, "\\shortname");
9212 status
= cli_mkdir(cli
, "\\shortname");
9213 if (!NT_STATUS_IS_OK(status
)) {
9214 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9215 __location__
, nt_errstr(status
));
9220 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
9224 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
9231 for (i
= 32; i
< 128; i
++) {
9232 uint16_t fnum
= (uint16_t)-1;
9236 if (strchr(illegal_chars
, i
)) {
9241 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
9242 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
9243 FILE_OVERWRITE_IF
, 0, 0, &fnum
, NULL
);
9244 if (!NT_STATUS_IS_OK(status
)) {
9245 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9246 __location__
, fname
, nt_errstr(status
));
9250 cli_close(cli
, fnum
);
9253 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
9254 shortname_list_fn
, &s
);
9255 if (s
.matched
!= 1) {
9256 d_printf("(%s) failed to list %s: %s\n",
9257 __location__
, fname
, nt_errstr(status
));
9262 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9263 if (!NT_STATUS_IS_OK(status
)) {
9264 d_printf("(%s) failed to delete %s: %s\n",
9265 __location__
, fname
, nt_errstr(status
));
9278 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
9279 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
9280 cli_rmdir(cli
, "\\shortname");
9281 torture_close_connection(cli
);
9285 static void pagedsearch_cb(struct tevent_req
*req
)
9288 struct tldap_message
*msg
;
9291 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
9292 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9293 d_printf("tldap_search_paged_recv failed: %s\n",
9294 tldap_rc2string(rc
));
9297 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
9301 if (!tldap_entry_dn(msg
, &dn
)) {
9302 d_printf("tldap_entry_dn failed\n");
9305 d_printf("%s\n", dn
);
9309 static bool run_tldap(int dummy
)
9311 struct tldap_context
*ld
;
9315 struct sockaddr_storage addr
;
9316 struct tevent_context
*ev
;
9317 struct tevent_req
*req
;
9321 if (!resolve_name(host
, &addr
, 0, false)) {
9322 d_printf("could not find host %s\n", host
);
9325 status
= open_socket_out(&addr
, 389, 9999, &fd
);
9326 if (!NT_STATUS_IS_OK(status
)) {
9327 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
9331 ld
= tldap_context_create(talloc_tos(), fd
);
9334 d_printf("tldap_context_create failed\n");
9338 rc
= tldap_fetch_rootdse(ld
);
9339 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9340 d_printf("tldap_fetch_rootdse failed: %s\n",
9341 tldap_errstr(talloc_tos(), ld
, rc
));
9345 basedn
= tldap_talloc_single_attribute(
9346 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
9347 if (basedn
== NULL
) {
9348 d_printf("no defaultNamingContext\n");
9351 d_printf("defaultNamingContext: %s\n", basedn
);
9353 ev
= samba_tevent_context_init(talloc_tos());
9355 d_printf("tevent_context_init failed\n");
9359 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
9360 TLDAP_SCOPE_SUB
, "(objectclass=*)",
9362 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
9364 d_printf("tldap_search_paged_send failed\n");
9367 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
9369 tevent_req_poll(req
, ev
);
9373 /* test search filters against rootDSE */
9374 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9375 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9377 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
9378 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
9379 talloc_tos(), NULL
);
9380 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9381 d_printf("tldap_search with complex filter failed: %s\n",
9382 tldap_errstr(talloc_tos(), ld
, rc
));
9390 /* Torture test to ensure no regression of :
9391 https://bugzilla.samba.org/show_bug.cgi?id=7084
9394 static bool run_dir_createtime(int dummy
)
9396 struct cli_state
*cli
;
9397 const char *dname
= "\\testdir";
9398 const char *fname
= "\\testdir\\testfile";
9400 struct timespec create_time
;
9401 struct timespec create_time1
;
9405 if (!torture_open_connection(&cli
, 0)) {
9409 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9410 cli_rmdir(cli
, dname
);
9412 status
= cli_mkdir(cli
, dname
);
9413 if (!NT_STATUS_IS_OK(status
)) {
9414 printf("mkdir failed: %s\n", nt_errstr(status
));
9418 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
9420 if (!NT_STATUS_IS_OK(status
)) {
9421 printf("cli_qpathinfo2 returned %s\n",
9426 /* Sleep 3 seconds, then create a file. */
9429 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
9431 if (!NT_STATUS_IS_OK(status
)) {
9432 printf("cli_openx failed: %s\n", nt_errstr(status
));
9436 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
9438 if (!NT_STATUS_IS_OK(status
)) {
9439 printf("cli_qpathinfo2 (2) returned %s\n",
9444 if (timespec_compare(&create_time1
, &create_time
)) {
9445 printf("run_dir_createtime: create time was updated (error)\n");
9447 printf("run_dir_createtime: create time was not updated (correct)\n");
9453 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9454 cli_rmdir(cli
, dname
);
9455 if (!torture_close_connection(cli
)) {
9462 static bool run_streamerror(int dummy
)
9464 struct cli_state
*cli
;
9465 const char *dname
= "\\testdir";
9466 const char *streamname
=
9467 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9469 time_t change_time
, access_time
, write_time
;
9471 uint16_t mode
, fnum
;
9474 if (!torture_open_connection(&cli
, 0)) {
9478 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9479 cli_rmdir(cli
, dname
);
9481 status
= cli_mkdir(cli
, dname
);
9482 if (!NT_STATUS_IS_OK(status
)) {
9483 printf("mkdir failed: %s\n", nt_errstr(status
));
9487 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
9488 &write_time
, &size
, &mode
);
9489 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
9490 printf("pathinfo returned %s, expected "
9491 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9496 status
= cli_ntcreate(cli
, streamname
, 0x16,
9497 FILE_READ_DATA
|FILE_READ_EA
|
9498 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
9499 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
9500 FILE_OPEN
, 0, 0, &fnum
, NULL
);
9502 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
9503 printf("ntcreate returned %s, expected "
9504 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9510 cli_rmdir(cli
, dname
);
9514 struct pidtest_state
{
9520 static void pid_echo_done(struct tevent_req
*subreq
);
9522 static struct tevent_req
*pid_echo_send(TALLOC_CTX
*mem_ctx
,
9523 struct tevent_context
*ev
,
9524 struct cli_state
*cli
)
9526 struct tevent_req
*req
, *subreq
;
9527 struct pidtest_state
*state
;
9529 req
= tevent_req_create(mem_ctx
, &state
, struct pidtest_state
);
9534 SSVAL(state
->vwv
, 0, 1);
9535 state
->data
= data_blob_const("hello", 5);
9537 subreq
= smb1cli_req_send(state
,
9542 0, 0, /* *_flags2 */
9544 0xDEADBEEF, /* pid */
9547 ARRAY_SIZE(state
->vwv
), state
->vwv
,
9548 state
->data
.length
, state
->data
.data
);
9550 if (tevent_req_nomem(subreq
, req
)) {
9551 return tevent_req_post(req
, ev
);
9553 tevent_req_set_callback(subreq
, pid_echo_done
, req
);
9557 static void pid_echo_done(struct tevent_req
*subreq
)
9559 struct tevent_req
*req
= tevent_req_callback_data(
9560 subreq
, struct tevent_req
);
9561 struct pidtest_state
*state
= tevent_req_data(
9562 req
, struct pidtest_state
);
9565 uint8_t *bytes
= NULL
;
9566 struct iovec
*recv_iov
= NULL
;
9567 uint8_t *phdr
= NULL
;
9568 uint16_t pidlow
= 0;
9569 uint16_t pidhigh
= 0;
9570 struct smb1cli_req_expected_response expected
[] = {
9572 .status
= NT_STATUS_OK
,
9577 status
= smb1cli_req_recv(subreq
, state
,
9582 NULL
, /* pvwv_offset */
9585 NULL
, /* pbytes_offset */
9587 expected
, ARRAY_SIZE(expected
));
9589 TALLOC_FREE(subreq
);
9591 if (!NT_STATUS_IS_OK(status
)) {
9592 tevent_req_nterror(req
, status
);
9596 if (num_bytes
!= state
->data
.length
) {
9597 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9601 if (memcmp(bytes
, state
->data
.data
, num_bytes
) != 0) {
9602 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9606 /* Check pid low/high == DEADBEEF */
9607 pidlow
= SVAL(phdr
, HDR_PID
);
9608 if (pidlow
!= 0xBEEF){
9609 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9610 (unsigned int)pidlow
);
9611 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9614 pidhigh
= SVAL(phdr
, HDR_PIDHIGH
);
9615 if (pidhigh
!= 0xDEAD){
9616 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9617 (unsigned int)pidhigh
);
9618 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9622 tevent_req_done(req
);
9625 static NTSTATUS
pid_echo_recv(struct tevent_req
*req
)
9627 return tevent_req_simple_recv_ntstatus(req
);
9630 static bool run_pidhigh(int dummy
)
9632 bool success
= false;
9633 struct cli_state
*cli
= NULL
;
9635 struct tevent_context
*ev
= NULL
;
9636 struct tevent_req
*req
= NULL
;
9637 TALLOC_CTX
*frame
= talloc_stackframe();
9639 printf("starting pid high test\n");
9640 if (!torture_open_connection(&cli
, 0)) {
9643 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9645 ev
= samba_tevent_context_init(frame
);
9650 req
= pid_echo_send(frame
, ev
, cli
);
9655 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
9659 status
= pid_echo_recv(req
);
9660 if (NT_STATUS_IS_OK(status
)) {
9661 printf("pid high test ok\n");
9668 torture_close_connection(cli
);
9673 Test Windows open on a bad POSIX symlink.
9675 static bool run_symlink_open_test(int dummy
)
9677 static struct cli_state
*cli
;
9678 const char *fname
= "non_existant_file";
9679 const char *sname
= "dangling_symlink";
9680 uint16_t fnum
= (uint16_t)-1;
9681 bool correct
= false;
9683 TALLOC_CTX
*frame
= NULL
;
9685 frame
= talloc_stackframe();
9687 printf("Starting Windows bad symlink open test\n");
9689 if (!torture_open_connection(&cli
, 0)) {
9694 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9696 status
= torture_setup_unix_extensions(cli
);
9697 if (!NT_STATUS_IS_OK(status
)) {
9702 /* Ensure nothing exists. */
9703 cli_setatr(cli
, fname
, 0, 0);
9704 cli_posix_unlink(cli
, fname
);
9705 cli_setatr(cli
, sname
, 0, 0);
9706 cli_posix_unlink(cli
, sname
);
9708 /* Create a symlink pointing nowhere. */
9709 status
= cli_posix_symlink(cli
, fname
, sname
);
9710 if (!NT_STATUS_IS_OK(status
)) {
9711 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9718 /* Now ensure that a Windows open doesn't hang. */
9719 status
= cli_ntcreate(cli
,
9722 FILE_READ_DATA
|FILE_WRITE_DATA
,
9724 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
9732 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9733 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9734 * we use O_NOFOLLOW on the server or not.
9736 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) ||
9737 NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
))
9741 printf("cli_ntcreate of %s returned %s - should return"
9742 " either (%s) or (%s)\n",
9745 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND
),
9746 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND
));
9754 if (fnum
!= (uint16_t)-1) {
9755 cli_close(cli
, fnum
);
9756 fnum
= (uint16_t)-1;
9759 cli_setatr(cli
, sname
, 0, 0);
9760 cli_posix_unlink(cli
, sname
);
9761 cli_setatr(cli
, fname
, 0, 0);
9762 cli_posix_unlink(cli
, fname
);
9764 if (!torture_close_connection(cli
)) {
9772 static bool run_local_substitute(int dummy
)
9776 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
9777 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9778 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9779 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9780 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
9781 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
9782 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9783 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9785 /* Different captialization rules in sub_basic... */
9787 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9793 static bool run_local_base64(int dummy
)
9798 for (i
=1; i
<2000; i
++) {
9799 DATA_BLOB blob1
, blob2
;
9802 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
9804 generate_random_buffer(blob1
.data
, blob1
.length
);
9806 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
9808 d_fprintf(stderr
, "base64_encode_data_blob failed "
9809 "for %d bytes\n", i
);
9812 blob2
= base64_decode_data_blob(b64
);
9815 if (data_blob_cmp(&blob1
, &blob2
)) {
9816 d_fprintf(stderr
, "data_blob_cmp failed for %d "
9820 TALLOC_FREE(blob1
.data
);
9821 data_blob_free(&blob2
);
9826 static void parse_fn(time_t timeout
, DATA_BLOB blob
, void *private_data
)
9831 static bool run_local_gencache(int dummy
)
9837 struct memcache
*mem
;
9840 mem
= memcache_init(NULL
, 0);
9842 d_printf("%s: memcache_init failed\n", __location__
);
9845 memcache_set_global(mem
);
9847 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
9848 d_printf("%s: gencache_set() failed\n", __location__
);
9852 if (!gencache_get("foo", NULL
, NULL
, NULL
)) {
9853 d_printf("%s: gencache_get() failed\n", __location__
);
9857 for (i
=0; i
<1000000; i
++) {
9858 gencache_parse("foo", parse_fn
, NULL
);
9861 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9862 d_printf("%s: gencache_get() failed\n", __location__
);
9867 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9868 d_printf("%s: gencache_get() failed\n", __location__
);
9872 if (strcmp(val
, "bar") != 0) {
9873 d_printf("%s: gencache_get() returned %s, expected %s\n",
9874 __location__
, val
, "bar");
9881 if (!gencache_del("foo")) {
9882 d_printf("%s: gencache_del() failed\n", __location__
);
9885 if (gencache_del("foo")) {
9886 d_printf("%s: second gencache_del() succeeded\n",
9891 if (gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9892 d_printf("%s: gencache_get() on deleted entry "
9893 "succeeded\n", __location__
);
9897 blob
= data_blob_string_const_null("bar");
9898 tm
= time(NULL
) + 60;
9900 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
9901 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
9905 if (!gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
9906 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
9910 if (strcmp((const char *)blob
.data
, "bar") != 0) {
9911 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9912 __location__
, (const char *)blob
.data
, "bar");
9913 data_blob_free(&blob
);
9917 data_blob_free(&blob
);
9919 if (!gencache_del("foo")) {
9920 d_printf("%s: gencache_del() failed\n", __location__
);
9923 if (gencache_del("foo")) {
9924 d_printf("%s: second gencache_del() succeeded\n",
9929 if (gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
9930 d_printf("%s: gencache_get_data_blob() on deleted entry "
9931 "succeeded\n", __location__
);
9936 blob
.data
= (uint8_t *)&v
;
9937 blob
.length
= sizeof(v
);
9939 if (!gencache_set_data_blob("blob", &blob
, tm
)) {
9940 d_printf("%s: gencache_set_data_blob() failed\n",
9944 if (gencache_get("blob", talloc_tos(), &val
, &tm
)) {
9945 d_printf("%s: gencache_get succeeded\n", __location__
);
9952 static bool rbt_testval(struct db_context
*db
, const char *key
,
9955 struct db_record
*rec
;
9956 TDB_DATA data
= string_tdb_data(value
);
9961 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
9963 d_fprintf(stderr
, "fetch_locked failed\n");
9966 status
= dbwrap_record_store(rec
, data
, 0);
9967 if (!NT_STATUS_IS_OK(status
)) {
9968 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
9973 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
9975 d_fprintf(stderr
, "second fetch_locked failed\n");
9979 dbvalue
= dbwrap_record_get_value(rec
);
9980 if ((dbvalue
.dsize
!= data
.dsize
)
9981 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
9982 d_fprintf(stderr
, "Got wrong data back\n");
9992 static int local_rbtree_traverse_read(struct db_record
*rec
, void *private_data
)
9994 int *count2
= (int *)private_data
;
9999 static int local_rbtree_traverse_delete(struct db_record
*rec
, void *private_data
)
10001 int *count2
= (int *)private_data
;
10003 dbwrap_record_delete(rec
);
10007 static bool run_local_rbtree(int dummy
)
10009 struct db_context
*db
;
10016 db
= db_open_rbt(NULL
);
10019 d_fprintf(stderr
, "db_open_rbt failed\n");
10023 for (i
=0; i
<1000; i
++) {
10026 if (asprintf(&key
, "key%ld", random()) == -1) {
10029 if (asprintf(&value
, "value%ld", random()) == -1) {
10034 if (!rbt_testval(db
, key
, value
)) {
10041 if (asprintf(&value
, "value%ld", random()) == -1) {
10046 if (!rbt_testval(db
, key
, value
)) {
10057 count
= 0; count2
= 0;
10058 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
10060 printf("%s: read1: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10061 if ((count
!= count2
) || (count
!= 1000)) {
10064 count
= 0; count2
= 0;
10065 status
= dbwrap_traverse(db
, local_rbtree_traverse_delete
,
10067 printf("%s: delete: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10068 if ((count
!= count2
) || (count
!= 1000)) {
10071 count
= 0; count2
= 0;
10072 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
10074 printf("%s: read2: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10075 if ((count
!= count2
) || (count
!= 0)) {
10086 local test for character set functions
10088 This is a very simple test for the functionality in convert_string_error()
10090 static bool run_local_convert_string(int dummy
)
10092 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
10093 const char *test_strings
[2] = { "March", "M\303\244rz" };
10097 for (i
=0; i
<2; i
++) {
10098 const char *str
= test_strings
[i
];
10099 int len
= strlen(str
);
10100 size_t converted_size
;
10103 memset(dst
, 'X', sizeof(dst
));
10105 /* first try with real source length */
10106 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
10111 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
10115 if (converted_size
!= len
) {
10116 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
10117 str
, len
, (int)converted_size
);
10121 if (strncmp(str
, dst
, converted_size
) != 0) {
10122 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
10126 if (strlen(str
) != converted_size
) {
10127 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
10128 (int)strlen(str
), (int)converted_size
);
10132 if (dst
[converted_size
] != 'X') {
10133 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
10137 /* now with srclen==-1, this causes the nul to be
10139 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
10144 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
10148 if (converted_size
!= len
+1) {
10149 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
10150 str
, len
, (int)converted_size
);
10154 if (strncmp(str
, dst
, converted_size
) != 0) {
10155 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
10159 if (len
+1 != converted_size
) {
10160 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
10161 len
+1, (int)converted_size
);
10165 if (dst
[converted_size
] != 'X') {
10166 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
10173 TALLOC_FREE(tmp_ctx
);
10176 TALLOC_FREE(tmp_ctx
);
10181 struct talloc_dict_test
{
10185 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
10187 int *count
= (int *)priv
;
10192 static bool run_local_talloc_dict(int dummy
)
10194 struct talloc_dict
*dict
;
10195 struct talloc_dict_test
*t
;
10196 int key
, count
, res
;
10199 dict
= talloc_dict_init(talloc_tos());
10200 if (dict
== NULL
) {
10204 t
= talloc(talloc_tos(), struct talloc_dict_test
);
10211 ok
= talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), &t
);
10217 res
= talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
);
10226 if (count
!= res
) {
10235 static bool run_local_string_to_sid(int dummy
) {
10236 struct dom_sid sid
;
10238 if (string_to_sid(&sid
, "S--1-5-32-545")) {
10239 printf("allowing S--1-5-32-545\n");
10242 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
10243 printf("allowing S-1-5-32-+545\n");
10246 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")) {
10247 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10250 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
10251 printf("allowing S-1-5-32-545-abc\n");
10254 if (string_to_sid(&sid
, "S-300-5-32-545")) {
10255 printf("allowing S-300-5-32-545\n");
10258 if (string_to_sid(&sid
, "S-1-0xfffffffffffffe-32-545")) {
10259 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10262 if (string_to_sid(&sid
, "S-1-0xffffffffffff-5294967297-545")) {
10263 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10266 if (!string_to_sid(&sid
, "S-1-0xfffffffffffe-32-545")) {
10267 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10270 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
10271 printf("could not parse S-1-5-32-545\n");
10274 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
10275 printf("mis-parsed S-1-5-32-545 as %s\n",
10276 sid_string_tos(&sid
));
10282 static bool sid_to_string_test(const char *expected
) {
10285 struct dom_sid sid
;
10287 if (!string_to_sid(&sid
, expected
)) {
10288 printf("could not parse %s\n", expected
);
10292 str
= dom_sid_string(NULL
, &sid
);
10293 if (strcmp(str
, expected
)) {
10294 printf("Comparison failed (%s != %s)\n", str
, expected
);
10301 static bool run_local_sid_to_string(int dummy
) {
10302 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10304 if (!sid_to_string_test("S-1-545"))
10306 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10311 static bool run_local_binary_to_sid(int dummy
) {
10312 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
10313 static const uint8_t good_binary_sid
[] = {
10314 0x1, /* revision number */
10315 15, /* num auths */
10316 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10317 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10318 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10319 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10320 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10321 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10322 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10323 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10324 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10325 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10326 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10327 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10328 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10329 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10330 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10331 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10334 static const uint8_t long_binary_sid
[] = {
10335 0x1, /* revision number */
10336 15, /* num auths */
10337 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10338 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10339 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10340 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10341 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10342 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10343 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10344 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10345 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10346 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10347 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10348 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10349 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10350 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10351 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10352 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10353 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10354 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10355 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10358 static const uint8_t long_binary_sid2
[] = {
10359 0x1, /* revision number */
10360 32, /* num auths */
10361 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10362 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10363 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10364 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10365 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10366 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10367 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10368 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10369 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10370 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10371 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10372 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10373 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10374 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10375 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10376 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10377 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10378 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10379 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10380 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10381 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10382 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10383 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10384 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10385 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10386 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10387 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10388 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10389 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10390 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10391 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10392 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10393 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10396 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
10399 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
10402 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
10408 /* Split a path name into filename and stream name components. Canonicalise
10409 * such that an implicit $DATA token is always explicit.
10411 * The "specification" of this function can be found in the
10412 * run_local_stream_name() function in torture.c, I've tried those
10413 * combinations against a W2k3 server.
10416 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
10417 char **pbase
, char **pstream
)
10420 char *stream
= NULL
;
10421 char *sname
; /* stream name */
10422 const char *stype
; /* stream type */
10424 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
10426 sname
= strchr_m(fname
, ':');
10428 if (sname
== NULL
) {
10429 if (pbase
!= NULL
) {
10430 base
= talloc_strdup(mem_ctx
, fname
);
10431 NT_STATUS_HAVE_NO_MEMORY(base
);
10436 if (pbase
!= NULL
) {
10437 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
10438 NT_STATUS_HAVE_NO_MEMORY(base
);
10443 stype
= strchr_m(sname
, ':');
10445 if (stype
== NULL
) {
10446 sname
= talloc_strdup(mem_ctx
, sname
);
10450 if (strcasecmp_m(stype
, ":$DATA") != 0) {
10452 * If there is an explicit stream type, so far we only
10453 * allow $DATA. Is there anything else allowed? -- vl
10455 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
10457 return NT_STATUS_OBJECT_NAME_INVALID
;
10459 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
10463 if (sname
== NULL
) {
10465 return NT_STATUS_NO_MEMORY
;
10468 if (sname
[0] == '\0') {
10470 * no stream name, so no stream
10475 if (pstream
!= NULL
) {
10476 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
10477 if (stream
== NULL
) {
10478 TALLOC_FREE(sname
);
10480 return NT_STATUS_NO_MEMORY
;
10483 * upper-case the type field
10485 (void)strupper_m(strchr_m(stream
, ':')+1);
10489 if (pbase
!= NULL
) {
10492 if (pstream
!= NULL
) {
10495 return NT_STATUS_OK
;
10498 static bool test_stream_name(const char *fname
, const char *expected_base
,
10499 const char *expected_stream
,
10500 NTSTATUS expected_status
)
10504 char *stream
= NULL
;
10506 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
10507 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
10511 if (!NT_STATUS_IS_OK(status
)) {
10515 if (base
== NULL
) goto error
;
10517 if (strcmp(expected_base
, base
) != 0) goto error
;
10519 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
10520 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
10522 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
10526 TALLOC_FREE(stream
);
10530 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
10531 fname
, expected_base
? expected_base
: "<NULL>",
10532 expected_stream
? expected_stream
: "<NULL>",
10533 nt_errstr(expected_status
));
10534 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
10535 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
10536 nt_errstr(status
));
10538 TALLOC_FREE(stream
);
10542 static bool run_local_stream_name(int dummy
)
10546 ret
&= test_stream_name(
10547 "bla", "bla", NULL
, NT_STATUS_OK
);
10548 ret
&= test_stream_name(
10549 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
10550 ret
&= test_stream_name(
10551 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10552 ret
&= test_stream_name(
10553 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10554 ret
&= test_stream_name(
10555 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10556 ret
&= test_stream_name(
10557 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
10558 ret
&= test_stream_name(
10559 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
10560 ret
&= test_stream_name(
10561 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
10566 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
10568 if (a
.length
!= b
.length
) {
10569 printf("a.length=%d != b.length=%d\n",
10570 (int)a
.length
, (int)b
.length
);
10573 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
10574 printf("a.data and b.data differ\n");
10580 static bool run_local_memcache(int dummy
)
10582 struct memcache
*cache
;
10583 DATA_BLOB k1
, k2
, k3
;
10587 TALLOC_CTX
*mem_ctx
;
10592 size_t size1
, size2
;
10595 mem_ctx
= talloc_init("foo");
10596 if (mem_ctx
== NULL
) {
10600 /* STAT_CACHE TESTS */
10602 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
10604 if (cache
== NULL
) {
10605 printf("memcache_init failed\n");
10609 d1
= data_blob_const("d1", 2);
10610 d3
= data_blob_const("d3", 2);
10612 k1
= data_blob_const("d1", 2);
10613 k2
= data_blob_const("d2", 2);
10614 k3
= data_blob_const("d3", 2);
10616 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
10618 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
10619 printf("could not find k1\n");
10622 if (!data_blob_equal(d1
, v1
)) {
10626 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
10628 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
10629 printf("could not find replaced k1\n");
10632 if (!data_blob_equal(d3
, v3
)) {
10636 TALLOC_FREE(cache
);
10638 /* GETWD_CACHE TESTS */
10639 str1
= talloc_strdup(mem_ctx
, "string1");
10640 if (str1
== NULL
) {
10643 ptr2
= str1
; /* Keep an alias for comparison. */
10645 str2
= talloc_strdup(mem_ctx
, "string2");
10646 if (str2
== NULL
) {
10650 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
10651 if (cache
== NULL
) {
10652 printf("memcache_init failed\n");
10656 memcache_add_talloc(cache
, GETWD_CACHE
, k2
, &str1
);
10657 /* str1 == NULL now. */
10658 ptr1
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
10659 if (ptr1
== NULL
) {
10660 printf("could not find k2\n");
10663 if (ptr1
!= ptr2
) {
10664 printf("fetch of k2 got wrong string\n");
10668 /* Add a blob to ensure k2 gets purged. */
10669 d3
= data_blob_talloc_zero(mem_ctx
, 180);
10670 memcache_add(cache
, STAT_CACHE
, k3
, d3
);
10672 ptr2
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
10673 if (ptr2
!= NULL
) {
10674 printf("Did find k2, should have been purged\n");
10678 TALLOC_FREE(cache
);
10679 TALLOC_FREE(mem_ctx
);
10681 mem_ctx
= talloc_init("foo");
10682 if (mem_ctx
== NULL
) {
10686 cache
= memcache_init(NULL
, 0);
10687 if (cache
== NULL
) {
10691 str1
= talloc_strdup(mem_ctx
, "string1");
10692 if (str1
== NULL
) {
10695 str2
= talloc_strdup(mem_ctx
, "string2");
10696 if (str2
== NULL
) {
10699 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
10700 data_blob_string_const("torture"), &str1
);
10701 size1
= talloc_total_size(cache
);
10703 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
10704 data_blob_string_const("torture"), &str2
);
10705 size2
= talloc_total_size(cache
);
10707 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
10709 if (size2
> size1
) {
10710 printf("memcache leaks memory!\n");
10716 TALLOC_FREE(cache
);
10720 static void wbclient_done(struct tevent_req
*req
)
10723 struct winbindd_response
*wb_resp
;
10724 int *i
= (int *)tevent_req_callback_data_void(req
);
10726 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
10729 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
10732 static bool run_wbclient_multi_ping(int dummy
)
10734 struct tevent_context
*ev
;
10735 struct wb_context
**wb_ctx
;
10736 struct winbindd_request wb_req
;
10737 bool result
= false;
10740 BlockSignals(True
, SIGPIPE
);
10742 ev
= tevent_context_init(talloc_tos());
10747 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
10748 if (wb_ctx
== NULL
) {
10752 ZERO_STRUCT(wb_req
);
10753 wb_req
.cmd
= WINBINDD_PING
;
10755 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
10757 for (i
=0; i
<torture_nprocs
; i
++) {
10758 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
10759 if (wb_ctx
[i
] == NULL
) {
10762 for (j
=0; j
<torture_numops
; j
++) {
10763 struct tevent_req
*req
;
10764 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
10765 (j
% 2) == 0, &wb_req
);
10769 tevent_req_set_callback(req
, wbclient_done
, &i
);
10775 while (i
< torture_nprocs
* torture_numops
) {
10776 tevent_loop_once(ev
);
10785 static void getaddrinfo_finished(struct tevent_req
*req
)
10787 char *name
= (char *)tevent_req_callback_data_void(req
);
10788 struct addrinfo
*ainfo
;
10791 res
= getaddrinfo_recv(req
, &ainfo
);
10793 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
10796 d_printf("gai(%s) succeeded\n", name
);
10797 freeaddrinfo(ainfo
);
10800 static bool run_getaddrinfo_send(int dummy
)
10802 TALLOC_CTX
*frame
= talloc_stackframe();
10803 struct fncall_context
*ctx
;
10804 struct tevent_context
*ev
;
10805 bool result
= false;
10806 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
10807 "www.slashdot.org", "heise.de" };
10808 struct tevent_req
*reqs
[4];
10811 ev
= samba_tevent_context_init(frame
);
10816 ctx
= fncall_context_init(frame
, 4);
10818 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
10819 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
10821 if (reqs
[i
] == NULL
) {
10824 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
10825 discard_const_p(void, names
[i
]));
10828 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
10829 tevent_loop_once(ev
);
10834 TALLOC_FREE(frame
);
10838 static bool dbtrans_inc(struct db_context
*db
)
10840 struct db_record
*rec
;
10846 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
10848 printf(__location__
"fetch_lock failed\n");
10852 value
= dbwrap_record_get_value(rec
);
10854 if (value
.dsize
!= sizeof(uint32_t)) {
10855 printf(__location__
"value.dsize = %d\n",
10860 memcpy(&val
, value
.dptr
, sizeof(val
));
10863 status
= dbwrap_record_store(
10864 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
10865 if (!NT_STATUS_IS_OK(status
)) {
10866 printf(__location__
"store failed: %s\n",
10867 nt_errstr(status
));
10877 static bool run_local_dbtrans(int dummy
)
10879 struct db_context
*db
;
10880 struct db_record
*rec
;
10886 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
10887 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
,
10890 printf("Could not open transtest.db\n");
10894 res
= dbwrap_transaction_start(db
);
10896 printf(__location__
"transaction_start failed\n");
10900 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
10902 printf(__location__
"fetch_lock failed\n");
10906 value
= dbwrap_record_get_value(rec
);
10908 if (value
.dptr
== NULL
) {
10910 status
= dbwrap_record_store(
10911 rec
, make_tdb_data((uint8_t *)&initial
,
10914 if (!NT_STATUS_IS_OK(status
)) {
10915 printf(__location__
"store returned %s\n",
10916 nt_errstr(status
));
10923 res
= dbwrap_transaction_commit(db
);
10925 printf(__location__
"transaction_commit failed\n");
10930 uint32_t val
, val2
;
10933 res
= dbwrap_transaction_start(db
);
10935 printf(__location__
"transaction_start failed\n");
10939 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val
);
10940 if (!NT_STATUS_IS_OK(status
)) {
10941 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
10942 nt_errstr(status
));
10946 for (i
=0; i
<10; i
++) {
10947 if (!dbtrans_inc(db
)) {
10952 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val2
);
10953 if (!NT_STATUS_IS_OK(status
)) {
10954 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
10955 nt_errstr(status
));
10959 if (val2
!= val
+ 10) {
10960 printf(__location__
"val=%d, val2=%d\n",
10961 (int)val
, (int)val2
);
10965 printf("val2=%d\r", val2
);
10967 res
= dbwrap_transaction_commit(db
);
10969 printf(__location__
"transaction_commit failed\n");
10979 * Just a dummy test to be run under a debugger. There's no real way
10980 * to inspect the tevent_select specific function from outside of
10984 static bool run_local_tevent_select(int dummy
)
10986 struct tevent_context
*ev
;
10987 struct tevent_fd
*fd1
, *fd2
;
10988 bool result
= false;
10990 ev
= tevent_context_init_byname(NULL
, "select");
10992 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
10996 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
10998 d_fprintf(stderr
, "tevent_add_fd failed\n");
11001 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
11003 d_fprintf(stderr
, "tevent_add_fd failed\n");
11008 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
11010 d_fprintf(stderr
, "tevent_add_fd failed\n");
11020 static bool run_local_hex_encode_buf(int dummy
)
11026 for (i
=0; i
<sizeof(src
); i
++) {
11029 hex_encode_buf(buf
, src
, sizeof(src
));
11030 if (strcmp(buf
, "0001020304050607") != 0) {
11033 hex_encode_buf(buf
, NULL
, 0);
11034 if (buf
[0] != '\0') {
11040 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
11062 "1001:1111:1111:1000:0:1111:1111:1111",
11071 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
11085 "1001:1111:1111:1000:0:1111:1111:1111"
11088 static bool run_local_remove_duplicate_addrs2(int dummy
)
11090 struct ip_service test_vector
[28];
11093 /* Construct the sockaddr_storage test vector. */
11094 for (i
= 0; i
< 28; i
++) {
11095 struct addrinfo hints
;
11096 struct addrinfo
*res
= NULL
;
11099 memset(&hints
, '\0', sizeof(hints
));
11100 hints
.ai_flags
= AI_NUMERICHOST
;
11101 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
11106 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
11107 remove_duplicate_addrs2_test_strings_vector
[i
]);
11110 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
11111 memcpy(&test_vector
[i
].ss
,
11117 count
= remove_duplicate_addrs2(test_vector
, i
);
11120 fprintf(stderr
, "count wrong (%d) should be 14\n",
11125 for (i
= 0; i
< count
; i
++) {
11126 char addr
[INET6_ADDRSTRLEN
];
11128 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
11130 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
11131 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
11134 remove_duplicate_addrs2_test_strings_result
[i
]);
11139 printf("run_local_remove_duplicate_addrs2: success\n");
11143 static bool run_local_tdb_opener(int dummy
)
11149 t
= tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST
,
11150 O_RDWR
|O_CREAT
, 0755);
11152 perror("tdb_open failed");
11163 static bool run_local_tdb_writer(int dummy
)
11169 t
= tdb_open("test.tdb", 1000, 0, O_RDWR
|O_CREAT
, 0755);
11171 perror("tdb_open failed");
11175 val
.dptr
= (uint8_t *)&v
;
11176 val
.dsize
= sizeof(v
);
11182 ret
= tdb_store(t
, val
, val
, 0);
11184 printf("%s\n", tdb_errorstr(t
));
11189 data
= tdb_fetch(t
, val
);
11190 if (data
.dptr
!= NULL
) {
11191 SAFE_FREE(data
.dptr
);
11197 static bool run_local_canonicalize_path(int dummy
)
11199 const char *src
[] = {
11206 ".././././../../../boo",
11210 const char *dst
[] = {
11223 for (i
= 0; src
[i
] != NULL
; i
++) {
11224 char *d
= canonicalize_absolute_path(talloc_tos(), src
[i
]);
11226 perror("talloc fail\n");
11229 if (strcmp(d
, dst
[i
]) != 0) {
11231 "canonicalize missmatch %s -> %s != %s",
11232 src
[i
], d
, dst
[i
]);
11240 static bool run_ign_bad_negprot(int dummy
)
11242 struct tevent_context
*ev
;
11243 struct tevent_req
*req
;
11244 struct smbXcli_conn
*conn
;
11245 struct sockaddr_storage ss
;
11250 printf("starting ignore bad negprot\n");
11252 ok
= resolve_name(host
, &ss
, 0x20, true);
11254 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
11258 status
= open_socket_out(&ss
, 445, 10000, &fd
);
11259 if (!NT_STATUS_IS_OK(status
)) {
11260 d_fprintf(stderr
, "open_socket_out failed: %s\n",
11261 nt_errstr(status
));
11265 conn
= smbXcli_conn_create(talloc_tos(), fd
, host
, SMB_SIGNING_OFF
, 0,
11267 if (conn
== NULL
) {
11268 d_fprintf(stderr
, "smbXcli_conn_create failed\n");
11272 status
= smbXcli_negprot(conn
, 0, PROTOCOL_CORE
, PROTOCOL_CORE
);
11273 if (NT_STATUS_IS_OK(status
)) {
11274 d_fprintf(stderr
, "smbXcli_negprot succeeded!\n");
11278 ev
= samba_tevent_context_init(talloc_tos());
11280 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
11284 req
= smb1cli_session_setup_nt1_send(
11285 ev
, ev
, conn
, 0, getpid(), NULL
, 65503, 2, 1, 0, "", "",
11286 data_blob_null
, data_blob_null
, 0x40,
11287 "Windows 2000 2195", "Windows 2000 5.0");
11289 d_fprintf(stderr
, "smb1cli_session_setup_nt1_send failed\n");
11293 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
11295 d_fprintf(stderr
, "tevent_req_poll failed\n");
11299 status
= smb1cli_session_setup_nt1_recv(req
, NULL
, NULL
, NULL
, NULL
,
11301 if (!NT_STATUS_EQUAL(status
, NT_STATUS_CONNECTION_RESET
)) {
11302 d_fprintf(stderr
, "smb1cli_session_setup_nt1_recv returned "
11303 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11304 nt_errstr(status
));
11310 printf("starting ignore bad negprot\n");
11315 static double create_procs(bool (*fn
)(int), bool *result
)
11318 volatile pid_t
*child_status
;
11319 volatile bool *child_status_out
;
11322 struct timeval start
;
11326 child_status
= (volatile pid_t
*)anonymous_shared_allocate(sizeof(pid_t
)*torture_nprocs
);
11327 if (!child_status
) {
11328 printf("Failed to setup shared memory\n");
11332 child_status_out
= (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs
);
11333 if (!child_status_out
) {
11334 printf("Failed to setup result status shared memory\n");
11338 for (i
= 0; i
< torture_nprocs
; i
++) {
11339 child_status
[i
] = 0;
11340 child_status_out
[i
] = True
;
11343 start
= timeval_current();
11345 for (i
=0;i
<torture_nprocs
;i
++) {
11348 pid_t mypid
= getpid();
11349 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
11351 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
11354 if (torture_open_connection(¤t_cli
, i
)) break;
11355 if (tries
-- == 0) {
11356 printf("pid %d failed to start\n", (int)getpid());
11362 child_status
[i
] = getpid();
11364 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
11366 child_status_out
[i
] = fn(i
);
11373 for (i
=0;i
<torture_nprocs
;i
++) {
11374 if (child_status
[i
]) synccount
++;
11376 if (synccount
== torture_nprocs
) break;
11378 } while (timeval_elapsed(&start
) < 30);
11380 if (synccount
!= torture_nprocs
) {
11381 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
11383 return timeval_elapsed(&start
);
11386 /* start the client load */
11387 start
= timeval_current();
11389 for (i
=0;i
<torture_nprocs
;i
++) {
11390 child_status
[i
] = 0;
11393 printf("%d clients started\n", torture_nprocs
);
11395 for (i
=0;i
<torture_nprocs
;i
++) {
11396 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
11401 for (i
=0;i
<torture_nprocs
;i
++) {
11402 if (!child_status_out
[i
]) {
11406 return timeval_elapsed(&start
);
11409 #define FLAG_MULTIPROC 1
11415 } torture_ops
[] = {
11416 {"FDPASS", run_fdpasstest
, 0},
11417 {"LOCK1", run_locktest1
, 0},
11418 {"LOCK2", run_locktest2
, 0},
11419 {"LOCK3", run_locktest3
, 0},
11420 {"LOCK4", run_locktest4
, 0},
11421 {"LOCK5", run_locktest5
, 0},
11422 {"LOCK6", run_locktest6
, 0},
11423 {"LOCK7", run_locktest7
, 0},
11424 {"LOCK8", run_locktest8
, 0},
11425 {"LOCK9", run_locktest9
, 0},
11426 {"UNLINK", run_unlinktest
, 0},
11427 {"BROWSE", run_browsetest
, 0},
11428 {"ATTR", run_attrtest
, 0},
11429 {"TRANS2", run_trans2test
, 0},
11430 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
11431 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
11432 {"RANDOMIPC", run_randomipc
, 0},
11433 {"NEGNOWAIT", run_negprot_nowait
, 0},
11434 {"NBENCH", run_nbench
, 0},
11435 {"NBENCH2", run_nbench2
, 0},
11436 {"OPLOCK1", run_oplock1
, 0},
11437 {"OPLOCK2", run_oplock2
, 0},
11438 {"OPLOCK4", run_oplock4
, 0},
11439 {"DIR", run_dirtest
, 0},
11440 {"DIR1", run_dirtest1
, 0},
11441 {"DIR-CREATETIME", run_dir_createtime
, 0},
11442 {"DENY1", torture_denytest1
, 0},
11443 {"DENY2", torture_denytest2
, 0},
11444 {"TCON", run_tcon_test
, 0},
11445 {"TCONDEV", run_tcon_devtype_test
, 0},
11446 {"RW1", run_readwritetest
, 0},
11447 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
11448 {"RW3", run_readwritelarge
, 0},
11449 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
11450 {"OPEN", run_opentest
, 0},
11451 {"POSIX", run_simple_posix_open_test
, 0},
11452 {"POSIX-APPEND", run_posix_append
, 0},
11453 {"POSIX-SYMLINK-ACL", run_acl_symlink_test
, 0},
11454 {"POSIX-SYMLINK-EA", run_ea_symlink_test
, 0},
11455 {"POSIX-STREAM-DELETE", run_posix_stream_delete
, 0},
11456 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test
, 0},
11457 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test
, 0},
11458 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
11459 {"ASYNC-ECHO", run_async_echo
, 0},
11460 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
11461 { "SHORTNAME-TEST", run_shortname_test
, 0},
11462 { "ADDRCHANGE", run_addrchange
, 0},
11464 {"OPENATTR", run_openattrtest
, 0},
11466 {"XCOPY", run_xcopy
, 0},
11467 {"RENAME", run_rename
, 0},
11468 {"RENAME-ACCESS", run_rename_access
, 0},
11469 {"OWNER-RIGHTS", run_owner_rights
, 0},
11470 {"DELETE", run_deletetest
, 0},
11471 {"WILDDELETE", run_wild_deletetest
, 0},
11472 {"DELETE-LN", run_deletetest_ln
, 0},
11473 {"PROPERTIES", run_properties
, 0},
11474 {"MANGLE", torture_mangle
, 0},
11475 {"MANGLE1", run_mangle1
, 0},
11476 {"MANGLE-ILLEGAL", run_mangle_illegal
, 0},
11477 {"W2K", run_w2ktest
, 0},
11478 {"TRANS2SCAN", torture_trans2_scan
, 0},
11479 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
11480 {"UTABLE", torture_utable
, 0},
11481 {"CASETABLE", torture_casetable
, 0},
11482 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
11483 {"PIPE_NUMBER", run_pipe_number
, 0},
11484 {"TCON2", run_tcon2_test
, 0},
11485 {"IOCTL", torture_ioctl_test
, 0},
11486 {"CHKPATH", torture_chkpath_test
, 0},
11487 {"FDSESS", run_fdsesstest
, 0},
11488 { "EATEST", run_eatest
, 0},
11489 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
11490 { "CHAIN1", run_chain1
, 0},
11491 { "CHAIN2", run_chain2
, 0},
11492 { "CHAIN3", run_chain3
, 0},
11493 { "WINDOWS-WRITE", run_windows_write
, 0},
11494 { "LARGE_READX", run_large_readx
, 0},
11495 { "NTTRANS-CREATE", run_nttrans_create
, 0},
11496 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
11497 { "CLI_ECHO", run_cli_echo
, 0},
11498 { "GETADDRINFO", run_getaddrinfo_send
, 0},
11499 { "TLDAP", run_tldap
},
11500 { "STREAMERROR", run_streamerror
},
11501 { "NOTIFY-BENCH", run_notify_bench
},
11502 { "NOTIFY-BENCH2", run_notify_bench2
},
11503 { "NOTIFY-BENCH3", run_notify_bench3
},
11504 { "BAD-NBT-SESSION", run_bad_nbt_session
},
11505 { "IGN-BAD-NEGPROT", run_ign_bad_negprot
},
11506 { "SMB-ANY-CONNECT", run_smb_any_connect
},
11507 { "NOTIFY-ONLINE", run_notify_online
},
11508 { "SMB2-BASIC", run_smb2_basic
},
11509 { "SMB2-NEGPROT", run_smb2_negprot
},
11510 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
11511 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
11512 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
11513 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
11514 { "SMB2-FTRUNCATE", run_smb2_ftruncate
},
11515 { "CLEANUP1", run_cleanup1
},
11516 { "CLEANUP2", run_cleanup2
},
11517 { "CLEANUP3", run_cleanup3
},
11518 { "CLEANUP4", run_cleanup4
},
11519 { "OPLOCK-CANCEL", run_oplock_cancel
},
11520 { "PIDHIGH", run_pidhigh
},
11521 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
11522 { "LOCAL-GENCACHE", run_local_gencache
, 0},
11523 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
11524 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
11525 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2
, 0 },
11526 { "LOCAL-MESSAGING-READ1", run_messaging_read1
, 0 },
11527 { "LOCAL-MESSAGING-READ2", run_messaging_read2
, 0 },
11528 { "LOCAL-MESSAGING-READ3", run_messaging_read3
, 0 },
11529 { "LOCAL-MESSAGING-READ4", run_messaging_read4
, 0 },
11530 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1
, 0 },
11531 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2
, 0 },
11532 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a
, 0 },
11533 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b
, 0 },
11534 { "LOCAL-BASE64", run_local_base64
, 0},
11535 { "LOCAL-RBTREE", run_local_rbtree
, 0},
11536 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
11537 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
11538 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping
, 0},
11539 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
11540 { "LOCAL-sid_to_string", run_local_sid_to_string
, 0},
11541 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
11542 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
11543 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
11544 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
11545 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
11546 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
11547 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
11548 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
11549 { "local-tdb-opener", run_local_tdb_opener
, 0 },
11550 { "local-tdb-writer", run_local_tdb_writer
, 0 },
11551 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb
, 0 },
11552 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool
, 0 },
11553 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent
, 0 },
11554 { "LOCAL-G-LOCK1", run_g_lock1
, 0 },
11555 { "LOCAL-G-LOCK2", run_g_lock2
, 0 },
11556 { "LOCAL-G-LOCK3", run_g_lock3
, 0 },
11557 { "LOCAL-G-LOCK4", run_g_lock4
, 0 },
11558 { "LOCAL-G-LOCK5", run_g_lock5
, 0 },
11559 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path
, 0 },
11560 { "qpathinfo-bufsize", run_qpathinfo_bufsize
, 0 },
11564 * dummy function to satisfy linker dependency
11566 struct tevent_context
*winbind_event_context(void);
11567 struct tevent_context
*winbind_event_context(void)
11572 /****************************************************************************
11573 run a specified test or "ALL"
11574 ****************************************************************************/
11575 static bool run_test(const char *name
)
11578 bool result
= True
;
11579 bool found
= False
;
11582 if (strequal(name
,"ALL")) {
11583 for (i
=0;torture_ops
[i
].name
;i
++) {
11584 run_test(torture_ops
[i
].name
);
11589 for (i
=0;torture_ops
[i
].name
;i
++) {
11590 fstr_sprintf(randomfname
, "\\XX%x",
11591 (unsigned)random());
11593 if (strequal(name
, torture_ops
[i
].name
)) {
11595 printf("Running %s\n", name
);
11596 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
11597 t
= create_procs(torture_ops
[i
].fn
, &result
);
11600 printf("TEST %s FAILED!\n", name
);
11603 struct timeval start
;
11604 start
= timeval_current();
11605 if (!torture_ops
[i
].fn(0)) {
11607 printf("TEST %s FAILED!\n", name
);
11609 t
= timeval_elapsed(&start
);
11611 printf("%s took %g secs\n\n", name
, t
);
11616 printf("Did not find a test named %s\n", name
);
11624 static void usage(void)
11628 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11629 printf("Please use samba4 torture.\n\n");
11631 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11633 printf("\t-d debuglevel\n");
11634 printf("\t-U user%%pass\n");
11635 printf("\t-k use kerberos\n");
11636 printf("\t-N numprocs\n");
11637 printf("\t-n my_netbios_name\n");
11638 printf("\t-W workgroup\n");
11639 printf("\t-o num_operations\n");
11640 printf("\t-O socket_options\n");
11641 printf("\t-m maximum protocol\n");
11642 printf("\t-L use oplocks\n");
11643 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11644 printf("\t-A showall\n");
11645 printf("\t-p port\n");
11646 printf("\t-s seed\n");
11647 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11648 printf("\t-f filename filename to test\n");
11649 printf("\t-e encrypt\n");
11652 printf("tests are:");
11653 for (i
=0;torture_ops
[i
].name
;i
++) {
11654 printf(" %s", torture_ops
[i
].name
);
11658 printf("default test is ALL\n");
11663 /****************************************************************************
11665 ****************************************************************************/
11666 int main(int argc
,char *argv
[])
11672 bool correct
= True
;
11673 TALLOC_CTX
*frame
= talloc_stackframe();
11674 int seed
= time(NULL
);
11676 #ifdef HAVE_SETBUFFER
11677 setbuffer(stdout
, NULL
, 0);
11680 setup_logging("smbtorture", DEBUG_STDOUT
);
11685 if (is_default_dyn_CONFIGFILE()) {
11686 if(getenv("SMB_CONF_PATH")) {
11687 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11690 lp_load_global(get_dyn_CONFIGFILE());
11697 for(p
= argv
[1]; *p
; p
++)
11701 if (strncmp(argv
[1], "//", 2)) {
11705 fstrcpy(host
, &argv
[1][2]);
11706 p
= strchr_m(&host
[2],'/');
11711 fstrcpy(share
, p
+1);
11713 fstrcpy(myname
, get_myname(talloc_tos()));
11715 fprintf(stderr
, "Failed to get my hostname.\n");
11719 if (*username
== 0 && getenv("LOGNAME")) {
11720 fstrcpy(username
,getenv("LOGNAME"));
11726 fstrcpy(workgroup
, lp_workgroup());
11728 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11732 port_to_use
= atoi(optarg
);
11735 seed
= atoi(optarg
);
11738 fstrcpy(workgroup
,optarg
);
11741 lp_set_cmdline("client max protocol", optarg
);
11744 torture_nprocs
= atoi(optarg
);
11747 torture_numops
= atoi(optarg
);
11750 lp_set_cmdline("log level", optarg
);
11756 use_oplocks
= True
;
11759 local_path
= optarg
;
11762 torture_showall
= True
;
11765 fstrcpy(myname
, optarg
);
11768 client_txt
= optarg
;
11775 use_kerberos
= True
;
11777 d_printf("No kerberos support compiled in\n");
11783 fstrcpy(username
,optarg
);
11784 p
= strchr_m(username
,'%');
11787 fstrcpy(password
, p
+1);
11792 fstrcpy(multishare_conn_fname
, optarg
);
11793 use_multishare_conn
= True
;
11796 torture_blocksize
= atoi(optarg
);
11799 test_filename
= SMB_STRDUP(optarg
);
11802 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
11807 d_printf("using seed %d\n", seed
);
11811 if(use_kerberos
&& !gotuser
) gotpass
= True
;
11814 char pwd
[256] = {0};
11817 rc
= samba_getpass("Password:", pwd
, sizeof(pwd
), false, false);
11819 fstrcpy(password
, pwd
);
11824 printf("host=%s share=%s user=%s myname=%s\n",
11825 host
, share
, username
, myname
);
11827 torture_creds
= cli_session_creds_init(frame
,
11833 false, /* fallback_after_kerberos */
11834 false, /* use_ccache */
11835 false); /* password_is_nt_hash */
11836 if (torture_creds
== NULL
) {
11837 d_printf("cli_session_creds_init() failed.\n");
11841 if (argc
== optind
) {
11842 correct
= run_test("ALL");
11844 for (i
=optind
;i
<argc
;i
++) {
11845 if (!run_test(argv
[i
])) {
11851 TALLOC_FREE(frame
);