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 static const char *sockops
="TCP_NODELAY";
53 static int port_to_use
=0;
54 int torture_numops
=100;
55 int torture_blocksize
=1024*1024;
56 static int procnum
; /* records process count number when forking */
57 static struct cli_state
*current_cli
;
58 static fstring randomfname
;
59 static bool use_oplocks
;
60 static bool use_level_II_oplocks
;
61 static const char *client_txt
= "client_oplocks.txt";
62 static bool disable_spnego
;
63 static bool use_kerberos
;
64 static bool force_dos_errors
;
65 static fstring multishare_conn_fname
;
66 static bool use_multishare_conn
= False
;
67 static bool do_encrypt
;
68 static const char *local_path
= NULL
;
69 static enum smb_signing_setting signing_state
= SMB_SIGNING_DEFAULT
;
72 bool torture_showall
= False
;
74 static double create_procs(bool (*fn
)(int), bool *result
);
76 /********************************************************************
77 Ensure a connection is encrypted.
78 ********************************************************************/
80 static bool force_cli_encryption(struct cli_state
*c
,
81 const char *sharename
)
83 uint16_t major
, minor
;
84 uint32_t caplow
, caphigh
;
87 if (!SERVER_HAS_UNIX_CIFS(c
)) {
88 d_printf("Encryption required and "
89 "server that doesn't support "
90 "UNIX extensions - failing connect\n");
94 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
96 if (!NT_STATUS_IS_OK(status
)) {
97 d_printf("Encryption required and "
98 "can't get UNIX CIFS extensions "
99 "version from server: %s\n", nt_errstr(status
));
103 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
104 d_printf("Encryption required and "
105 "share %s doesn't support "
106 "encryption.\n", sharename
);
110 if (c
->use_kerberos
) {
111 status
= cli_gss_smb_encryption_start(c
);
113 status
= cli_raw_ntlm_smb_encryption_start(c
,
119 if (!NT_STATUS_IS_OK(status
)) {
120 d_printf("Encryption required and "
121 "setup failed with error %s.\n",
130 static struct cli_state
*open_nbt_connection(void)
136 if (disable_spnego
) {
137 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
141 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
144 if (use_level_II_oplocks
) {
145 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
149 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
152 if (force_dos_errors
) {
153 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
156 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
157 signing_state
, flags
, &c
);
158 if (!NT_STATUS_IS_OK(status
)) {
159 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
163 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
168 /****************************************************************************
169 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
170 ****************************************************************************/
172 static bool cli_bad_session_request(int fd
,
173 struct nmb_name
*calling
, struct nmb_name
*called
)
182 uint8_t message_type
;
184 struct tevent_context
*ev
;
185 struct tevent_req
*req
;
187 frame
= talloc_stackframe();
189 iov
[0].iov_base
= len_buf
;
190 iov
[0].iov_len
= sizeof(len_buf
);
192 /* put in the destination name */
194 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
196 if (iov
[1].iov_base
== NULL
) {
199 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
200 talloc_get_size(iov
[1].iov_base
));
204 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
206 if (iov
[2].iov_base
== NULL
) {
209 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
210 talloc_get_size(iov
[2].iov_base
));
212 /* Deliberately corrupt the name len (first byte) */
213 *((uint8_t *)iov
[2].iov_base
) = 100;
215 /* send a session request (RFC 1002) */
216 /* setup the packet length
217 * Remove four bytes from the length count, since the length
218 * field in the NBT Session Service header counts the number
219 * of bytes which follow. The cli_send_smb() function knows
220 * about this and accounts for those four bytes.
224 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
225 SCVAL(len_buf
,0,0x81);
227 len
= write_data_iov(fd
, iov
, 3);
232 ev
= samba_tevent_context_init(frame
);
236 req
= read_smb_send(frame
, ev
, fd
);
240 if (!tevent_req_poll(req
, ev
)) {
243 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
250 message_type
= CVAL(inbuf
, 0);
251 if (message_type
!= 0x83) {
252 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
257 if (smb_len(inbuf
) != 1) {
258 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
259 (int)smb_len(inbuf
));
263 error
= CVAL(inbuf
, 4);
265 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
276 /* Insert a NULL at the first separator of the given path and return a pointer
277 * to the remainder of the string.
280 terminate_path_at_separator(char * path
)
288 if ((p
= strchr_m(path
, '/'))) {
293 if ((p
= strchr_m(path
, '\\'))) {
303 parse a //server/share type UNC name
305 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
306 char **hostname
, char **sharename
)
310 *hostname
= *sharename
= NULL
;
312 if (strncmp(unc_name
, "\\\\", 2) &&
313 strncmp(unc_name
, "//", 2)) {
317 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
318 p
= terminate_path_at_separator(*hostname
);
321 *sharename
= talloc_strdup(mem_ctx
, p
);
322 terminate_path_at_separator(*sharename
);
325 if (*hostname
&& *sharename
) {
329 TALLOC_FREE(*hostname
);
330 TALLOC_FREE(*sharename
);
334 static bool torture_open_connection_share(struct cli_state
**c
,
335 const char *hostname
,
336 const char *sharename
)
342 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
344 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
345 if (use_level_II_oplocks
)
346 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
348 status
= cli_full_connection(c
, myname
,
349 hostname
, NULL
, port_to_use
,
352 password
, flags
, signing_state
);
353 if (!NT_STATUS_IS_OK(status
)) {
354 printf("failed to open share connection: //%s/%s port:%d - %s\n",
355 hostname
, sharename
, port_to_use
, nt_errstr(status
));
359 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
362 return force_cli_encryption(*c
,
368 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
370 char **unc_list
= NULL
;
371 int num_unc_names
= 0;
374 if (use_multishare_conn
==True
) {
376 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
377 if (!unc_list
|| num_unc_names
<= 0) {
378 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
382 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
384 printf("Failed to parse UNC name %s\n",
385 unc_list
[conn_index
% num_unc_names
]);
386 TALLOC_FREE(unc_list
);
390 result
= torture_open_connection_share(c
, h
, s
);
392 /* h, s were copied earlier */
393 TALLOC_FREE(unc_list
);
397 return torture_open_connection_share(c
, host
, share
);
400 bool torture_init_connection(struct cli_state
**pcli
)
402 struct cli_state
*cli
;
404 cli
= open_nbt_connection();
413 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16_t *new_vuid
)
415 uint16_t old_vuid
= cli_state_get_uid(cli
);
416 size_t passlen
= strlen(password
);
420 cli_state_set_uid(cli
, 0);
421 status
= cli_session_setup(cli
, username
,
425 ret
= NT_STATUS_IS_OK(status
);
426 *new_vuid
= cli_state_get_uid(cli
);
427 cli_state_set_uid(cli
, old_vuid
);
432 bool torture_close_connection(struct cli_state
*c
)
437 status
= cli_tdis(c
);
438 if (!NT_STATUS_IS_OK(status
)) {
439 printf("tdis failed (%s)\n", nt_errstr(status
));
449 /* check if the server produced the expected dos or nt error code */
450 static bool check_both_error(int line
, NTSTATUS status
,
451 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
453 if (NT_STATUS_IS_DOS(status
)) {
457 /* Check DOS error */
458 cclass
= NT_STATUS_DOS_CLASS(status
);
459 num
= NT_STATUS_DOS_CODE(status
);
461 if (eclass
!= cclass
|| ecode
!= num
) {
462 printf("unexpected error code class=%d code=%d\n",
463 (int)cclass
, (int)num
);
464 printf(" expected %d/%d %s (line=%d)\n",
465 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
470 if (!NT_STATUS_EQUAL(nterr
, status
)) {
471 printf("unexpected error code %s\n",
473 printf(" expected %s (line=%d)\n",
474 nt_errstr(nterr
), line
);
483 /* check if the server produced the expected error code */
484 static bool check_error(int line
, NTSTATUS status
,
485 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
487 if (NT_STATUS_IS_DOS(status
)) {
491 /* Check DOS error */
493 cclass
= NT_STATUS_DOS_CLASS(status
);
494 num
= NT_STATUS_DOS_CODE(status
);
496 if (eclass
!= cclass
|| ecode
!= num
) {
497 printf("unexpected error code class=%d code=%d\n",
498 (int)cclass
, (int)num
);
499 printf(" expected %d/%d %s (line=%d)\n",
500 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
508 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
509 printf("unexpected error code %s\n",
511 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
521 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
525 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
527 while (!NT_STATUS_IS_OK(status
)) {
528 if (!check_both_error(__LINE__
, status
, ERRDOS
,
529 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
533 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
540 static bool rw_torture(struct cli_state
*c
)
542 const char *lockfname
= "\\torture.lck";
546 pid_t pid2
, pid
= getpid();
553 memset(buf
, '\0', sizeof(buf
));
555 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
557 if (!NT_STATUS_IS_OK(status
)) {
558 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
560 if (!NT_STATUS_IS_OK(status
)) {
561 printf("open of %s failed (%s)\n",
562 lockfname
, nt_errstr(status
));
566 for (i
=0;i
<torture_numops
;i
++) {
567 unsigned n
= (unsigned)sys_random()%10;
570 printf("%d\r", i
); fflush(stdout
);
572 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
574 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
578 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
580 if (!NT_STATUS_IS_OK(status
)) {
581 printf("open failed (%s)\n", nt_errstr(status
));
586 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
588 if (!NT_STATUS_IS_OK(status
)) {
589 printf("write failed (%s)\n", nt_errstr(status
));
594 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
595 sizeof(pid
)+(j
*sizeof(buf
)),
597 if (!NT_STATUS_IS_OK(status
)) {
598 printf("write failed (%s)\n",
606 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
608 if (!NT_STATUS_IS_OK(status
)) {
609 printf("read failed (%s)\n", nt_errstr(status
));
611 } else if (nread
!= sizeof(pid
)) {
612 printf("read/write compare failed: "
613 "recv %ld req %ld\n", (unsigned long)nread
,
614 (unsigned long)sizeof(pid
));
619 printf("data corruption!\n");
623 status
= cli_close(c
, fnum
);
624 if (!NT_STATUS_IS_OK(status
)) {
625 printf("close failed (%s)\n", nt_errstr(status
));
629 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
630 if (!NT_STATUS_IS_OK(status
)) {
631 printf("unlink failed (%s)\n", nt_errstr(status
));
635 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
636 if (!NT_STATUS_IS_OK(status
)) {
637 printf("unlock failed (%s)\n", nt_errstr(status
));
643 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
650 static bool run_torture(int dummy
)
652 struct cli_state
*cli
;
657 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
659 ret
= rw_torture(cli
);
661 if (!torture_close_connection(cli
)) {
668 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
670 uint16_t fnum
= (uint16_t)-1;
675 unsigned countprev
= 0;
678 NTSTATUS status
= NT_STATUS_OK
;
681 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32_t))
683 SIVAL(buf
, i
, sys_random());
690 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
691 if (!NT_STATUS_IS_OK(status
)) {
692 printf("unlink failed (%s) (normal, this file should "
693 "not exist)\n", nt_errstr(status
));
696 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
698 if (!NT_STATUS_IS_OK(status
)) {
699 printf("first open read/write of %s failed (%s)\n",
700 lockfname
, nt_errstr(status
));
706 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
708 status
= cli_openx(c
, lockfname
, O_RDONLY
,
710 if (NT_STATUS_IS_OK(status
)) {
715 if (!NT_STATUS_IS_OK(status
)) {
716 printf("second open read-only of %s failed (%s)\n",
717 lockfname
, nt_errstr(status
));
723 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
725 if (count
>= countprev
) {
726 printf("%d %8d\r", i
, count
);
729 countprev
+= (sizeof(buf
) / 20);
734 sent
= ((unsigned)sys_random()%(20))+ 1;
735 if (sent
> sizeof(buf
) - count
)
737 sent
= sizeof(buf
) - count
;
740 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
742 if (!NT_STATUS_IS_OK(status
)) {
743 printf("write failed (%s)\n",
750 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
751 sizeof(buf
)-count
, &sent
);
752 if(!NT_STATUS_IS_OK(status
)) {
753 printf("read failed offset:%d size:%ld (%s)\n",
754 count
, (unsigned long)sizeof(buf
)-count
,
758 } else if (sent
> 0) {
759 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
761 printf("read/write compare failed\n");
762 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
771 status
= cli_close(c
, fnum
);
772 if (!NT_STATUS_IS_OK(status
)) {
773 printf("close failed (%s)\n", nt_errstr(status
));
780 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
782 const char *lockfname
= "\\torture2.lck";
792 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
793 if (!NT_STATUS_IS_OK(status
)) {
794 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
797 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
799 if (!NT_STATUS_IS_OK(status
)) {
800 printf("first open read/write of %s failed (%s)\n",
801 lockfname
, nt_errstr(status
));
805 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
806 if (!NT_STATUS_IS_OK(status
)) {
807 printf("second open read-only of %s failed (%s)\n",
808 lockfname
, nt_errstr(status
));
809 cli_close(c1
, fnum1
);
813 for (i
= 0; i
< torture_numops
; i
++)
815 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
817 printf("%d\r", i
); fflush(stdout
);
820 generate_random_buffer((unsigned char *)buf
, buf_size
);
822 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
824 if (!NT_STATUS_IS_OK(status
)) {
825 printf("write failed (%s)\n", nt_errstr(status
));
830 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
831 if(!NT_STATUS_IS_OK(status
)) {
832 printf("read failed (%s)\n", nt_errstr(status
));
835 } else if (bytes_read
!= buf_size
) {
836 printf("read failed\n");
837 printf("read %ld, expected %ld\n",
838 (unsigned long)bytes_read
,
839 (unsigned long)buf_size
);
844 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
846 printf("read/write compare failed\n");
852 status
= cli_close(c2
, fnum2
);
853 if (!NT_STATUS_IS_OK(status
)) {
854 printf("close failed (%s)\n", nt_errstr(status
));
858 status
= cli_close(c1
, fnum1
);
859 if (!NT_STATUS_IS_OK(status
)) {
860 printf("close failed (%s)\n", nt_errstr(status
));
864 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
865 if (!NT_STATUS_IS_OK(status
)) {
866 printf("unlink failed (%s)\n", nt_errstr(status
));
873 static bool run_readwritetest(int dummy
)
875 struct cli_state
*cli1
, *cli2
;
876 bool test1
, test2
= False
;
878 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
881 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
882 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
884 printf("starting readwritetest\n");
886 test1
= rw_torture2(cli1
, cli2
);
887 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
890 test2
= rw_torture2(cli1
, cli1
);
891 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
894 if (!torture_close_connection(cli1
)) {
898 if (!torture_close_connection(cli2
)) {
902 return (test1
&& test2
);
905 static bool run_readwritemulti(int dummy
)
907 struct cli_state
*cli
;
912 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
914 printf("run_readwritemulti: fname %s\n", randomfname
);
915 test
= rw_torture3(cli
, randomfname
);
917 if (!torture_close_connection(cli
)) {
924 static bool run_readwritelarge_internal(void)
926 static struct cli_state
*cli1
;
928 const char *lockfname
= "\\large.dat";
934 if (!torture_open_connection(&cli1
, 0)) {
937 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
938 memset(buf
,'\0',sizeof(buf
));
940 printf("starting readwritelarge_internal\n");
942 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
944 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
946 if (!NT_STATUS_IS_OK(status
)) {
947 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
951 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
953 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
955 if (!NT_STATUS_IS_OK(status
)) {
956 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
960 if (fsize
== sizeof(buf
))
961 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
962 (unsigned long)fsize
);
964 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
965 (unsigned long)fsize
);
969 status
= cli_close(cli1
, fnum1
);
970 if (!NT_STATUS_IS_OK(status
)) {
971 printf("close failed (%s)\n", nt_errstr(status
));
975 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
976 if (!NT_STATUS_IS_OK(status
)) {
977 printf("unlink failed (%s)\n", nt_errstr(status
));
981 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
983 if (!NT_STATUS_IS_OK(status
)) {
984 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
988 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
990 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
992 if (!NT_STATUS_IS_OK(status
)) {
993 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
997 if (fsize
== sizeof(buf
))
998 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
999 (unsigned long)fsize
);
1001 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1002 (unsigned long)fsize
);
1007 /* ToDo - set allocation. JRA */
1008 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1009 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1012 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1014 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1018 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1021 status
= cli_close(cli1
, fnum1
);
1022 if (!NT_STATUS_IS_OK(status
)) {
1023 printf("close failed (%s)\n", nt_errstr(status
));
1027 if (!torture_close_connection(cli1
)) {
1033 static bool run_readwritelarge(int dummy
)
1035 return run_readwritelarge_internal();
1038 static bool run_readwritelarge_signtest(int dummy
)
1041 signing_state
= SMB_SIGNING_REQUIRED
;
1042 ret
= run_readwritelarge_internal();
1043 signing_state
= SMB_SIGNING_DEFAULT
;
1050 #define ival(s) strtol(s, NULL, 0)
1052 /* run a test that simulates an approximate netbench client load */
1053 static bool run_netbench(int client
)
1055 struct cli_state
*cli
;
1060 const char *params
[20];
1061 bool correct
= True
;
1067 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1071 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1073 f
= fopen(client_txt
, "r");
1080 while (fgets(line
, sizeof(line
)-1, f
)) {
1084 line
[strlen(line
)-1] = 0;
1086 /* printf("[%d] %s\n", line_count, line); */
1088 all_string_sub(line
,"client1", cname
, sizeof(line
));
1090 /* parse the command parameters */
1091 params
[0] = strtok_r(line
, " ", &saveptr
);
1093 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1097 if (i
< 2) continue;
1099 if (!strncmp(params
[0],"SMB", 3)) {
1100 printf("ERROR: You are using a dbench 1 load file\n");
1104 if (!strcmp(params
[0],"NTCreateX")) {
1105 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1107 } else if (!strcmp(params
[0],"Close")) {
1108 nb_close(ival(params
[1]));
1109 } else if (!strcmp(params
[0],"Rename")) {
1110 nb_rename(params
[1], params
[2]);
1111 } else if (!strcmp(params
[0],"Unlink")) {
1112 nb_unlink(params
[1]);
1113 } else if (!strcmp(params
[0],"Deltree")) {
1114 nb_deltree(params
[1]);
1115 } else if (!strcmp(params
[0],"Rmdir")) {
1116 nb_rmdir(params
[1]);
1117 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1118 nb_qpathinfo(params
[1]);
1119 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1120 nb_qfileinfo(ival(params
[1]));
1121 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1122 nb_qfsinfo(ival(params
[1]));
1123 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1124 nb_findfirst(params
[1]);
1125 } else if (!strcmp(params
[0],"WriteX")) {
1126 nb_writex(ival(params
[1]),
1127 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1128 } else if (!strcmp(params
[0],"ReadX")) {
1129 nb_readx(ival(params
[1]),
1130 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1131 } else if (!strcmp(params
[0],"Flush")) {
1132 nb_flush(ival(params
[1]));
1134 printf("Unknown operation %s\n", params
[0]);
1142 if (!torture_close_connection(cli
)) {
1150 /* run a test that simulates an approximate netbench client load */
1151 static bool run_nbench(int dummy
)
1154 bool correct
= True
;
1156 nbio_shmem(torture_nprocs
);
1160 signal(SIGALRM
, nb_alarm
);
1162 t
= create_procs(run_netbench
, &correct
);
1165 printf("\nThroughput %g MB/sec\n",
1166 1.0e-6 * nbio_total() / t
);
1172 This test checks for two things:
1174 1) correct support for retaining locks over a close (ie. the server
1175 must not use posix semantics)
1176 2) support for lock timeouts
1178 static bool run_locktest1(int dummy
)
1180 struct cli_state
*cli1
, *cli2
;
1181 const char *fname
= "\\lockt1.lck";
1182 uint16_t fnum1
, fnum2
, fnum3
;
1184 unsigned lock_timeout
;
1187 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1190 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1191 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1193 printf("starting locktest1\n");
1195 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1197 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1199 if (!NT_STATUS_IS_OK(status
)) {
1200 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1204 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1205 if (!NT_STATUS_IS_OK(status
)) {
1206 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1210 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1211 if (!NT_STATUS_IS_OK(status
)) {
1212 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1216 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1217 if (!NT_STATUS_IS_OK(status
)) {
1218 printf("lock1 failed (%s)\n", nt_errstr(status
));
1222 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1223 if (NT_STATUS_IS_OK(status
)) {
1224 printf("lock2 succeeded! This is a locking bug\n");
1227 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1228 NT_STATUS_LOCK_NOT_GRANTED
)) {
1233 lock_timeout
= (1 + (random() % 20));
1234 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1236 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1237 if (NT_STATUS_IS_OK(status
)) {
1238 printf("lock3 succeeded! This is a locking bug\n");
1241 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1242 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1248 if (ABS(t2
- t1
) < lock_timeout
-1) {
1249 printf("error: This server appears not to support timed lock requests\n");
1252 printf("server slept for %u seconds for a %u second timeout\n",
1253 (unsigned int)(t2
-t1
), lock_timeout
);
1255 status
= cli_close(cli1
, fnum2
);
1256 if (!NT_STATUS_IS_OK(status
)) {
1257 printf("close1 failed (%s)\n", nt_errstr(status
));
1261 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1262 if (NT_STATUS_IS_OK(status
)) {
1263 printf("lock4 succeeded! This is a locking bug\n");
1266 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1267 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1272 status
= cli_close(cli1
, fnum1
);
1273 if (!NT_STATUS_IS_OK(status
)) {
1274 printf("close2 failed (%s)\n", nt_errstr(status
));
1278 status
= cli_close(cli2
, fnum3
);
1279 if (!NT_STATUS_IS_OK(status
)) {
1280 printf("close3 failed (%s)\n", nt_errstr(status
));
1284 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1285 if (!NT_STATUS_IS_OK(status
)) {
1286 printf("unlink failed (%s)\n", nt_errstr(status
));
1291 if (!torture_close_connection(cli1
)) {
1295 if (!torture_close_connection(cli2
)) {
1299 printf("Passed locktest1\n");
1304 this checks to see if a secondary tconx can use open files from an
1307 static bool run_tcon_test(int dummy
)
1309 static struct cli_state
*cli
;
1310 const char *fname
= "\\tcontest.tmp";
1312 uint16_t cnum1
, cnum2
, cnum3
;
1313 uint16_t vuid1
, vuid2
;
1318 memset(buf
, '\0', sizeof(buf
));
1320 if (!torture_open_connection(&cli
, 0)) {
1323 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1325 printf("starting tcontest\n");
1327 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1329 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1330 if (!NT_STATUS_IS_OK(status
)) {
1331 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1335 cnum1
= cli_state_get_tid(cli
);
1336 vuid1
= cli_state_get_uid(cli
);
1338 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1339 if (!NT_STATUS_IS_OK(status
)) {
1340 printf("initial write failed (%s)", nt_errstr(status
));
1344 status
= cli_tree_connect(cli
, share
, "?????",
1345 password
, strlen(password
)+1);
1346 if (!NT_STATUS_IS_OK(status
)) {
1347 printf("%s refused 2nd tree connect (%s)\n", host
,
1353 cnum2
= cli_state_get_tid(cli
);
1354 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1355 vuid2
= cli_state_get_uid(cli
) + 1;
1357 /* try a write with the wrong tid */
1358 cli_state_set_tid(cli
, cnum2
);
1360 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1361 if (NT_STATUS_IS_OK(status
)) {
1362 printf("* server allows write with wrong TID\n");
1365 printf("server fails write with wrong TID : %s\n",
1370 /* try a write with an invalid tid */
1371 cli_state_set_tid(cli
, cnum3
);
1373 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1374 if (NT_STATUS_IS_OK(status
)) {
1375 printf("* server allows write with invalid TID\n");
1378 printf("server fails write with invalid TID : %s\n",
1382 /* try a write with an invalid vuid */
1383 cli_state_set_uid(cli
, vuid2
);
1384 cli_state_set_tid(cli
, cnum1
);
1386 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1387 if (NT_STATUS_IS_OK(status
)) {
1388 printf("* server allows write with invalid VUID\n");
1391 printf("server fails write with invalid VUID : %s\n",
1395 cli_state_set_tid(cli
, cnum1
);
1396 cli_state_set_uid(cli
, vuid1
);
1398 status
= cli_close(cli
, fnum1
);
1399 if (!NT_STATUS_IS_OK(status
)) {
1400 printf("close failed (%s)\n", nt_errstr(status
));
1404 cli_state_set_tid(cli
, cnum2
);
1406 status
= cli_tdis(cli
);
1407 if (!NT_STATUS_IS_OK(status
)) {
1408 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1412 cli_state_set_tid(cli
, cnum1
);
1414 if (!torture_close_connection(cli
)) {
1423 checks for old style tcon support
1425 static bool run_tcon2_test(int dummy
)
1427 static struct cli_state
*cli
;
1428 uint16_t cnum
, max_xmit
;
1432 if (!torture_open_connection(&cli
, 0)) {
1435 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1437 printf("starting tcon2 test\n");
1439 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1443 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1447 if (!NT_STATUS_IS_OK(status
)) {
1448 printf("tcon2 failed : %s\n", nt_errstr(status
));
1450 printf("tcon OK : max_xmit=%d cnum=%d\n",
1451 (int)max_xmit
, (int)cnum
);
1454 if (!torture_close_connection(cli
)) {
1458 printf("Passed tcon2 test\n");
1462 static bool tcon_devtest(struct cli_state
*cli
,
1463 const char *myshare
, const char *devtype
,
1464 const char *return_devtype
,
1465 NTSTATUS expected_error
)
1470 status
= cli_tree_connect(cli
, myshare
, devtype
,
1471 password
, strlen(password
)+1);
1473 if (NT_STATUS_IS_OK(expected_error
)) {
1474 if (NT_STATUS_IS_OK(status
)) {
1475 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1478 printf("tconX to share %s with type %s "
1479 "succeeded but returned the wrong "
1480 "device type (got [%s] but should have got [%s])\n",
1481 myshare
, devtype
, cli
->dev
, return_devtype
);
1485 printf("tconX to share %s with type %s "
1486 "should have succeeded but failed\n",
1492 if (NT_STATUS_IS_OK(status
)) {
1493 printf("tconx to share %s with type %s "
1494 "should have failed but succeeded\n",
1498 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1501 printf("Returned unexpected error\n");
1510 checks for correct tconX support
1512 static bool run_tcon_devtype_test(int dummy
)
1514 static struct cli_state
*cli1
= NULL
;
1519 status
= cli_full_connection(&cli1
, myname
,
1520 host
, NULL
, port_to_use
,
1522 username
, workgroup
,
1523 password
, flags
, signing_state
);
1525 if (!NT_STATUS_IS_OK(status
)) {
1526 printf("could not open connection\n");
1530 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1533 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1536 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1539 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1542 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1545 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1548 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1551 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1554 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1557 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1563 printf("Passed tcondevtest\n");
1570 This test checks that
1572 1) the server supports multiple locking contexts on the one SMB
1573 connection, distinguished by PID.
1575 2) the server correctly fails overlapping locks made by the same PID (this
1576 goes against POSIX behaviour, which is why it is tricky to implement)
1578 3) the server denies unlock requests by an incorrect client PID
1580 static bool run_locktest2(int dummy
)
1582 static struct cli_state
*cli
;
1583 const char *fname
= "\\lockt2.lck";
1584 uint16_t fnum1
, fnum2
, fnum3
;
1585 bool correct
= True
;
1588 if (!torture_open_connection(&cli
, 0)) {
1592 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1594 printf("starting locktest2\n");
1596 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1600 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1601 if (!NT_STATUS_IS_OK(status
)) {
1602 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1606 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1607 if (!NT_STATUS_IS_OK(status
)) {
1608 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1614 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1615 if (!NT_STATUS_IS_OK(status
)) {
1616 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1622 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1623 if (!NT_STATUS_IS_OK(status
)) {
1624 printf("lock1 failed (%s)\n", nt_errstr(status
));
1628 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1629 if (NT_STATUS_IS_OK(status
)) {
1630 printf("WRITE lock1 succeeded! This is a locking bug\n");
1633 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1634 NT_STATUS_LOCK_NOT_GRANTED
)) {
1639 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1640 if (NT_STATUS_IS_OK(status
)) {
1641 printf("WRITE lock2 succeeded! This is a locking bug\n");
1644 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1645 NT_STATUS_LOCK_NOT_GRANTED
)) {
1650 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1651 if (NT_STATUS_IS_OK(status
)) {
1652 printf("READ lock2 succeeded! This is a locking bug\n");
1655 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1656 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1661 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1662 if (!NT_STATUS_IS_OK(status
)) {
1663 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1666 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1667 printf("unlock at 100 succeeded! This is a locking bug\n");
1671 status
= cli_unlock(cli
, fnum1
, 0, 4);
1672 if (NT_STATUS_IS_OK(status
)) {
1673 printf("unlock1 succeeded! This is a locking bug\n");
1676 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1677 NT_STATUS_RANGE_NOT_LOCKED
)) {
1682 status
= cli_unlock(cli
, fnum1
, 0, 8);
1683 if (NT_STATUS_IS_OK(status
)) {
1684 printf("unlock2 succeeded! This is a locking bug\n");
1687 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1688 NT_STATUS_RANGE_NOT_LOCKED
)) {
1693 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1694 if (NT_STATUS_IS_OK(status
)) {
1695 printf("lock3 succeeded! This is a locking bug\n");
1698 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1699 NT_STATUS_LOCK_NOT_GRANTED
)) {
1706 status
= cli_close(cli
, fnum1
);
1707 if (!NT_STATUS_IS_OK(status
)) {
1708 printf("close1 failed (%s)\n", nt_errstr(status
));
1712 status
= cli_close(cli
, fnum2
);
1713 if (!NT_STATUS_IS_OK(status
)) {
1714 printf("close2 failed (%s)\n", nt_errstr(status
));
1718 status
= cli_close(cli
, fnum3
);
1719 if (!NT_STATUS_IS_OK(status
)) {
1720 printf("close3 failed (%s)\n", nt_errstr(status
));
1724 if (!torture_close_connection(cli
)) {
1728 printf("locktest2 finished\n");
1735 This test checks that
1737 1) the server supports the full offset range in lock requests
1739 static bool run_locktest3(int dummy
)
1741 static struct cli_state
*cli1
, *cli2
;
1742 const char *fname
= "\\lockt3.lck";
1743 uint16_t fnum1
, fnum2
;
1746 bool correct
= True
;
1749 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1751 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1754 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1755 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1757 printf("starting locktest3\n");
1759 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1761 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1763 if (!NT_STATUS_IS_OK(status
)) {
1764 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1768 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1769 if (!NT_STATUS_IS_OK(status
)) {
1770 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1774 for (offset
=i
=0;i
<torture_numops
;i
++) {
1777 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1779 printf("lock1 %d failed (%s)\n",
1785 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1786 if (!NT_STATUS_IS_OK(status
)) {
1787 printf("lock2 %d failed (%s)\n",
1794 for (offset
=i
=0;i
<torture_numops
;i
++) {
1797 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1798 if (NT_STATUS_IS_OK(status
)) {
1799 printf("error: lock1 %d succeeded!\n", i
);
1803 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1804 if (NT_STATUS_IS_OK(status
)) {
1805 printf("error: lock2 %d succeeded!\n", i
);
1809 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1810 if (NT_STATUS_IS_OK(status
)) {
1811 printf("error: lock3 %d succeeded!\n", i
);
1815 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1816 if (NT_STATUS_IS_OK(status
)) {
1817 printf("error: lock4 %d succeeded!\n", i
);
1822 for (offset
=i
=0;i
<torture_numops
;i
++) {
1825 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1826 if (!NT_STATUS_IS_OK(status
)) {
1827 printf("unlock1 %d failed (%s)\n",
1833 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1834 if (!NT_STATUS_IS_OK(status
)) {
1835 printf("unlock2 %d failed (%s)\n",
1842 status
= cli_close(cli1
, fnum1
);
1843 if (!NT_STATUS_IS_OK(status
)) {
1844 printf("close1 failed (%s)\n", nt_errstr(status
));
1848 status
= cli_close(cli2
, fnum2
);
1849 if (!NT_STATUS_IS_OK(status
)) {
1850 printf("close2 failed (%s)\n", nt_errstr(status
));
1854 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1855 if (!NT_STATUS_IS_OK(status
)) {
1856 printf("unlink failed (%s)\n", nt_errstr(status
));
1860 if (!torture_close_connection(cli1
)) {
1864 if (!torture_close_connection(cli2
)) {
1868 printf("finished locktest3\n");
1873 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1874 char *buf
, off_t offset
, size_t size
,
1875 size_t *nread
, size_t expect
)
1880 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1882 if(!NT_STATUS_IS_OK(status
)) {
1884 } else if (l_nread
!= expect
) {
1895 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1896 printf("** "); correct = False; \
1900 looks at overlapping locks
1902 static bool run_locktest4(int dummy
)
1904 static struct cli_state
*cli1
, *cli2
;
1905 const char *fname
= "\\lockt4.lck";
1906 uint16_t fnum1
, fnum2
, f
;
1909 bool correct
= True
;
1912 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1916 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1917 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1919 printf("starting locktest4\n");
1921 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1923 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1924 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1926 memset(buf
, 0, sizeof(buf
));
1928 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1930 if (!NT_STATUS_IS_OK(status
)) {
1931 printf("Failed to create file: %s\n", nt_errstr(status
));
1936 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1937 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1938 EXPECTED(ret
, False
);
1939 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1941 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
1942 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
1943 EXPECTED(ret
, True
);
1944 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1946 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
1947 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
1948 EXPECTED(ret
, False
);
1949 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1951 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
1952 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
1953 EXPECTED(ret
, True
);
1954 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1956 ret
= (cli_setpid(cli1
, 1),
1957 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
1958 (cli_setpid(cli1
, 2),
1959 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
1960 EXPECTED(ret
, False
);
1961 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1963 ret
= (cli_setpid(cli1
, 1),
1964 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
1965 (cli_setpid(cli1
, 2),
1966 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
1967 EXPECTED(ret
, True
);
1968 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1970 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
1971 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
1972 EXPECTED(ret
, True
);
1973 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1975 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
1976 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
1977 EXPECTED(ret
, False
);
1978 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1980 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
1981 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
1982 EXPECTED(ret
, False
);
1983 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1985 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
1986 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
1987 EXPECTED(ret
, True
);
1988 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1990 ret
= (cli_setpid(cli1
, 1),
1991 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
1992 (cli_setpid(cli1
, 2),
1993 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
1994 EXPECTED(ret
, False
);
1995 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1997 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
1998 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
1999 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2000 EXPECTED(ret
, False
);
2001 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2004 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2005 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2006 EXPECTED(ret
, False
);
2007 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2009 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2010 ret
= NT_STATUS_IS_OK(status
);
2012 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2014 ret
= NT_STATUS_IS_OK(status
);
2016 EXPECTED(ret
, False
);
2017 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2020 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2021 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2022 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2023 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2024 EXPECTED(ret
, True
);
2025 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2028 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2029 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2030 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2031 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2032 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2034 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2035 EXPECTED(ret
, True
);
2036 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2038 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2039 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2040 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2042 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2043 EXPECTED(ret
, True
);
2044 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2046 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2047 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2048 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2050 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2051 EXPECTED(ret
, True
);
2052 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2054 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2055 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2056 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2057 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2059 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2060 EXPECTED(ret
, True
);
2061 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2063 cli_close(cli1
, fnum1
);
2064 cli_close(cli2
, fnum2
);
2065 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2066 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2067 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2068 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2069 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2070 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2073 cli_close(cli1
, fnum1
);
2074 EXPECTED(ret
, True
);
2075 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2078 cli_close(cli1
, fnum1
);
2079 cli_close(cli2
, fnum2
);
2080 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2081 torture_close_connection(cli1
);
2082 torture_close_connection(cli2
);
2084 printf("finished locktest4\n");
2089 looks at lock upgrade/downgrade.
2091 static bool run_locktest5(int dummy
)
2093 static struct cli_state
*cli1
, *cli2
;
2094 const char *fname
= "\\lockt5.lck";
2095 uint16_t fnum1
, fnum2
, fnum3
;
2098 bool correct
= True
;
2101 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2105 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2106 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2108 printf("starting locktest5\n");
2110 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2112 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2113 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2114 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2116 memset(buf
, 0, sizeof(buf
));
2118 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2120 if (!NT_STATUS_IS_OK(status
)) {
2121 printf("Failed to create file: %s\n", nt_errstr(status
));
2126 /* Check for NT bug... */
2127 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2128 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2129 cli_close(cli1
, fnum1
);
2130 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2131 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2132 ret
= NT_STATUS_IS_OK(status
);
2133 EXPECTED(ret
, True
);
2134 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2135 cli_close(cli1
, fnum1
);
2136 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2137 cli_unlock(cli1
, fnum3
, 0, 1);
2139 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2140 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2141 EXPECTED(ret
, True
);
2142 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2144 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2145 ret
= NT_STATUS_IS_OK(status
);
2146 EXPECTED(ret
, False
);
2148 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2150 /* Unlock the process 2 lock. */
2151 cli_unlock(cli2
, fnum2
, 0, 4);
2153 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2154 ret
= NT_STATUS_IS_OK(status
);
2155 EXPECTED(ret
, False
);
2157 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2159 /* Unlock the process 1 fnum3 lock. */
2160 cli_unlock(cli1
, fnum3
, 0, 4);
2162 /* Stack 2 more locks here. */
2163 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2164 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2166 EXPECTED(ret
, True
);
2167 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2169 /* Unlock the first process lock, then check this was the WRITE lock that was
2172 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2173 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2175 EXPECTED(ret
, True
);
2176 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2178 /* Unlock the process 2 lock. */
2179 cli_unlock(cli2
, fnum2
, 0, 4);
2181 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2183 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2184 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2185 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2187 EXPECTED(ret
, True
);
2188 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2190 /* Ensure the next unlock fails. */
2191 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2192 EXPECTED(ret
, False
);
2193 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2195 /* Ensure connection 2 can get a write lock. */
2196 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2197 ret
= NT_STATUS_IS_OK(status
);
2198 EXPECTED(ret
, True
);
2200 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2204 cli_close(cli1
, fnum1
);
2205 cli_close(cli2
, fnum2
);
2206 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2207 if (!torture_close_connection(cli1
)) {
2210 if (!torture_close_connection(cli2
)) {
2214 printf("finished locktest5\n");
2220 tries the unusual lockingX locktype bits
2222 static bool run_locktest6(int dummy
)
2224 static struct cli_state
*cli
;
2225 const char *fname
[1] = { "\\lock6.txt" };
2230 if (!torture_open_connection(&cli
, 0)) {
2234 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2236 printf("starting locktest6\n");
2239 printf("Testing %s\n", fname
[i
]);
2241 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2243 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2244 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2245 cli_close(cli
, fnum
);
2246 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2248 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2249 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2250 cli_close(cli
, fnum
);
2251 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2253 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2256 torture_close_connection(cli
);
2258 printf("finished locktest6\n");
2262 static bool run_locktest7(int dummy
)
2264 struct cli_state
*cli1
;
2265 const char *fname
= "\\lockt7.lck";
2268 bool correct
= False
;
2272 if (!torture_open_connection(&cli1
, 0)) {
2276 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2278 printf("starting locktest7\n");
2280 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2282 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2284 memset(buf
, 0, sizeof(buf
));
2286 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2288 if (!NT_STATUS_IS_OK(status
)) {
2289 printf("Failed to create file: %s\n", nt_errstr(status
));
2293 cli_setpid(cli1
, 1);
2295 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2296 if (!NT_STATUS_IS_OK(status
)) {
2297 printf("Unable to apply read lock on range 130:4, "
2298 "error was %s\n", nt_errstr(status
));
2301 printf("pid1 successfully locked range 130:4 for READ\n");
2304 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2305 if (!NT_STATUS_IS_OK(status
)) {
2306 printf("pid1 unable to read the range 130:4, error was %s\n",
2309 } else if (nread
!= 4) {
2310 printf("pid1 unable to read the range 130:4, "
2311 "recv %ld req %d\n", (unsigned long)nread
, 4);
2314 printf("pid1 successfully read the range 130:4\n");
2317 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2318 if (!NT_STATUS_IS_OK(status
)) {
2319 printf("pid1 unable to write to the range 130:4, error was "
2320 "%s\n", nt_errstr(status
));
2321 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2322 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2326 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2330 cli_setpid(cli1
, 2);
2332 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2333 if (!NT_STATUS_IS_OK(status
)) {
2334 printf("pid2 unable to read the range 130:4, error was %s\n",
2337 } else if (nread
!= 4) {
2338 printf("pid2 unable to read the range 130:4, "
2339 "recv %ld req %d\n", (unsigned long)nread
, 4);
2342 printf("pid2 successfully read the range 130:4\n");
2345 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2346 if (!NT_STATUS_IS_OK(status
)) {
2347 printf("pid2 unable to write to the range 130:4, error was "
2348 "%s\n", nt_errstr(status
));
2349 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2350 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2354 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2358 cli_setpid(cli1
, 1);
2359 cli_unlock(cli1
, fnum1
, 130, 4);
2361 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2362 if (!NT_STATUS_IS_OK(status
)) {
2363 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2366 printf("pid1 successfully locked range 130:4 for WRITE\n");
2369 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2370 if (!NT_STATUS_IS_OK(status
)) {
2371 printf("pid1 unable to read the range 130:4, error was %s\n",
2374 } else if (nread
!= 4) {
2375 printf("pid1 unable to read the range 130:4, "
2376 "recv %ld req %d\n", (unsigned long)nread
, 4);
2379 printf("pid1 successfully read the range 130:4\n");
2382 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2383 if (!NT_STATUS_IS_OK(status
)) {
2384 printf("pid1 unable to write to the range 130:4, error was "
2385 "%s\n", nt_errstr(status
));
2388 printf("pid1 successfully wrote to the range 130:4\n");
2391 cli_setpid(cli1
, 2);
2393 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2394 if (!NT_STATUS_IS_OK(status
)) {
2395 printf("pid2 unable to read the range 130:4, error was "
2396 "%s\n", nt_errstr(status
));
2397 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2398 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2402 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2403 (unsigned long)nread
);
2407 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2408 if (!NT_STATUS_IS_OK(status
)) {
2409 printf("pid2 unable to write to the range 130:4, error was "
2410 "%s\n", nt_errstr(status
));
2411 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2412 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2416 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2420 cli_unlock(cli1
, fnum1
, 130, 0);
2424 cli_close(cli1
, fnum1
);
2425 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2426 torture_close_connection(cli1
);
2428 printf("finished locktest7\n");
2433 * This demonstrates a problem with our use of GPFS share modes: A file
2434 * descriptor sitting in the pending close queue holding a GPFS share mode
2435 * blocks opening a file another time. Happens with Word 2007 temp files.
2436 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2437 * open is denied with NT_STATUS_SHARING_VIOLATION.
2440 static bool run_locktest8(int dummy
)
2442 struct cli_state
*cli1
;
2443 const char *fname
= "\\lockt8.lck";
2444 uint16_t fnum1
, fnum2
;
2446 bool correct
= False
;
2449 if (!torture_open_connection(&cli1
, 0)) {
2453 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2455 printf("starting locktest8\n");
2457 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2459 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2461 if (!NT_STATUS_IS_OK(status
)) {
2462 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2466 memset(buf
, 0, sizeof(buf
));
2468 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2469 if (!NT_STATUS_IS_OK(status
)) {
2470 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2475 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2476 if (!NT_STATUS_IS_OK(status
)) {
2477 printf("Unable to apply read lock on range 1:1, error was "
2478 "%s\n", nt_errstr(status
));
2482 status
= cli_close(cli1
, fnum1
);
2483 if (!NT_STATUS_IS_OK(status
)) {
2484 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2488 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2489 if (!NT_STATUS_IS_OK(status
)) {
2490 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2498 cli_close(cli1
, fnum1
);
2499 cli_close(cli1
, fnum2
);
2500 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2501 torture_close_connection(cli1
);
2503 printf("finished locktest8\n");
2508 * This test is designed to be run in conjunction with
2509 * external NFS or POSIX locks taken in the filesystem.
2510 * It checks that the smbd server will block until the
2511 * lock is released and then acquire it. JRA.
2514 static bool got_alarm
;
2515 static struct cli_state
*alarm_cli
;
2517 static void alarm_handler(int dummy
)
2522 static void alarm_handler_parent(int dummy
)
2524 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_OK
);
2527 static void do_local_lock(int read_fd
, int write_fd
)
2532 const char *local_pathname
= NULL
;
2535 local_pathname
= talloc_asprintf(talloc_tos(),
2536 "%s/lockt9.lck", local_path
);
2537 if (!local_pathname
) {
2538 printf("child: alloc fail\n");
2542 unlink(local_pathname
);
2543 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2545 printf("child: open of %s failed %s.\n",
2546 local_pathname
, strerror(errno
));
2550 /* Now take a fcntl lock. */
2551 lock
.l_type
= F_WRLCK
;
2552 lock
.l_whence
= SEEK_SET
;
2555 lock
.l_pid
= getpid();
2557 ret
= fcntl(fd
,F_SETLK
,&lock
);
2559 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2560 local_pathname
, strerror(errno
));
2563 printf("child: got lock 0:4 on file %s.\n",
2568 CatchSignal(SIGALRM
, alarm_handler
);
2570 /* Signal the parent. */
2571 if (write(write_fd
, &c
, 1) != 1) {
2572 printf("child: start signal fail %s.\n",
2579 /* Wait for the parent to be ready. */
2580 if (read(read_fd
, &c
, 1) != 1) {
2581 printf("child: reply signal fail %s.\n",
2589 printf("child: released lock 0:4 on file %s.\n",
2595 static bool run_locktest9(int dummy
)
2597 struct cli_state
*cli1
;
2598 const char *fname
= "\\lockt9.lck";
2600 bool correct
= False
;
2601 int pipe_in
[2], pipe_out
[2];
2605 struct timeval start
;
2609 printf("starting locktest9\n");
2611 if (local_path
== NULL
) {
2612 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2616 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2621 if (child_pid
== -1) {
2625 if (child_pid
== 0) {
2627 do_local_lock(pipe_out
[0], pipe_in
[1]);
2637 ret
= read(pipe_in
[0], &c
, 1);
2639 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2644 if (!torture_open_connection(&cli1
, 0)) {
2648 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2650 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
,
2652 if (!NT_STATUS_IS_OK(status
)) {
2653 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2657 /* Ensure the child has the lock. */
2658 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2659 if (NT_STATUS_IS_OK(status
)) {
2660 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2663 d_printf("Child has the lock.\n");
2666 /* Tell the child to wait 5 seconds then exit. */
2667 ret
= write(pipe_out
[1], &c
, 1);
2669 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2674 /* Wait 20 seconds for the lock. */
2676 CatchSignal(SIGALRM
, alarm_handler_parent
);
2679 start
= timeval_current();
2681 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2682 if (!NT_STATUS_IS_OK(status
)) {
2683 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2684 "%s\n", nt_errstr(status
));
2689 seconds
= timeval_elapsed(&start
);
2691 printf("Parent got the lock after %.2f seconds.\n",
2694 status
= cli_close(cli1
, fnum
);
2695 if (!NT_STATUS_IS_OK(status
)) {
2696 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2703 cli_close(cli1
, fnum
);
2704 torture_close_connection(cli1
);
2708 printf("finished locktest9\n");
2713 test whether fnums and tids open on one VC are available on another (a major
2716 static bool run_fdpasstest(int dummy
)
2718 struct cli_state
*cli1
, *cli2
;
2719 const char *fname
= "\\fdpass.tst";
2724 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2727 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2728 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2730 printf("starting fdpasstest\n");
2732 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2734 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2736 if (!NT_STATUS_IS_OK(status
)) {
2737 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2741 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2743 if (!NT_STATUS_IS_OK(status
)) {
2744 printf("write failed (%s)\n", nt_errstr(status
));
2748 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2749 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2750 cli_setpid(cli2
, cli_getpid(cli1
));
2752 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2753 printf("read succeeded! nasty security hole [%s]\n", buf
);
2757 cli_close(cli1
, fnum1
);
2758 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2760 torture_close_connection(cli1
);
2761 torture_close_connection(cli2
);
2763 printf("finished fdpasstest\n");
2767 static bool run_fdsesstest(int dummy
)
2769 struct cli_state
*cli
;
2771 uint16_t saved_vuid
;
2773 uint16_t saved_cnum
;
2774 const char *fname
= "\\fdsess.tst";
2775 const char *fname1
= "\\fdsess1.tst";
2782 if (!torture_open_connection(&cli
, 0))
2784 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2786 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2789 saved_cnum
= cli_state_get_tid(cli
);
2790 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", "", 1)))
2792 new_cnum
= cli_state_get_tid(cli
);
2793 cli_state_set_tid(cli
, saved_cnum
);
2795 printf("starting fdsesstest\n");
2797 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2798 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2800 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2801 if (!NT_STATUS_IS_OK(status
)) {
2802 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2806 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2808 if (!NT_STATUS_IS_OK(status
)) {
2809 printf("write failed (%s)\n", nt_errstr(status
));
2813 saved_vuid
= cli_state_get_uid(cli
);
2814 cli_state_set_uid(cli
, new_vuid
);
2816 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2817 printf("read succeeded with different vuid! "
2818 "nasty security hole [%s]\n", buf
);
2821 /* Try to open a file with different vuid, samba cnum. */
2822 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2823 printf("create with different vuid, same cnum succeeded.\n");
2824 cli_close(cli
, fnum2
);
2825 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2827 printf("create with different vuid, same cnum failed.\n");
2828 printf("This will cause problems with service clients.\n");
2832 cli_state_set_uid(cli
, saved_vuid
);
2834 /* Try with same vuid, different cnum. */
2835 cli_state_set_tid(cli
, new_cnum
);
2837 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2838 printf("read succeeded with different cnum![%s]\n", buf
);
2842 cli_state_set_tid(cli
, saved_cnum
);
2843 cli_close(cli
, fnum1
);
2844 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2846 torture_close_connection(cli
);
2848 printf("finished fdsesstest\n");
2853 This test checks that
2855 1) the server does not allow an unlink on a file that is open
2857 static bool run_unlinktest(int dummy
)
2859 struct cli_state
*cli
;
2860 const char *fname
= "\\unlink.tst";
2862 bool correct
= True
;
2865 if (!torture_open_connection(&cli
, 0)) {
2869 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2871 printf("starting unlink test\n");
2873 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2877 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2878 if (!NT_STATUS_IS_OK(status
)) {
2879 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2883 status
= cli_unlink(cli
, fname
,
2884 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2885 if (NT_STATUS_IS_OK(status
)) {
2886 printf("error: server allowed unlink on an open file\n");
2889 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2890 NT_STATUS_SHARING_VIOLATION
);
2893 cli_close(cli
, fnum
);
2894 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2896 if (!torture_close_connection(cli
)) {
2900 printf("unlink test finished\n");
2907 test how many open files this server supports on the one socket
2909 static bool run_maxfidtest(int dummy
)
2911 struct cli_state
*cli
;
2913 uint16_t fnums
[0x11000];
2916 bool correct
= True
;
2922 printf("failed to connect\n");
2926 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2928 for (i
=0; i
<0x11000; i
++) {
2929 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2930 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2932 if (!NT_STATUS_IS_OK(status
)) {
2933 printf("open of %s failed (%s)\n",
2934 fname
, nt_errstr(status
));
2935 printf("maximum fnum is %d\n", i
);
2943 printf("cleaning up\n");
2945 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2946 cli_close(cli
, fnums
[i
]);
2948 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2949 if (!NT_STATUS_IS_OK(status
)) {
2950 printf("unlink of %s failed (%s)\n",
2951 fname
, nt_errstr(status
));
2958 printf("maxfid test finished\n");
2959 if (!torture_close_connection(cli
)) {
2965 /* generate a random buffer */
2966 static void rand_buf(char *buf
, int len
)
2969 *buf
= (char)sys_random();
2974 /* send smb negprot commands, not reading the response */
2975 static bool run_negprot_nowait(int dummy
)
2977 struct tevent_context
*ev
;
2979 struct cli_state
*cli
;
2980 bool correct
= True
;
2982 printf("starting negprot nowait test\n");
2984 ev
= samba_tevent_context_init(talloc_tos());
2989 if (!(cli
= open_nbt_connection())) {
2994 for (i
=0;i
<50000;i
++) {
2995 struct tevent_req
*req
;
2997 req
= smbXcli_negprot_send(ev
, ev
, cli
->conn
, cli
->timeout
,
2998 PROTOCOL_CORE
, PROTOCOL_NT1
);
3003 if (!tevent_req_poll(req
, ev
)) {
3004 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3012 if (torture_close_connection(cli
)) {
3016 printf("finished negprot nowait test\n");
3021 /* send smb negprot commands, not reading the response */
3022 static bool run_bad_nbt_session(int dummy
)
3024 struct nmb_name called
, calling
;
3025 struct sockaddr_storage ss
;
3030 printf("starting bad nbt session test\n");
3032 make_nmb_name(&calling
, myname
, 0x0);
3033 make_nmb_name(&called
, host
, 0x20);
3035 if (!resolve_name(host
, &ss
, 0x20, true)) {
3036 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3040 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
3041 if (!NT_STATUS_IS_OK(status
)) {
3042 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3047 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3050 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3055 printf("finished bad nbt session test\n");
3059 /* send random IPC commands */
3060 static bool run_randomipc(int dummy
)
3062 char *rparam
= NULL
;
3064 unsigned int rdrcnt
,rprcnt
;
3066 int api
, param_len
, i
;
3067 struct cli_state
*cli
;
3068 bool correct
= True
;
3071 printf("starting random ipc test\n");
3073 if (!torture_open_connection(&cli
, 0)) {
3077 for (i
=0;i
<count
;i
++) {
3078 api
= sys_random() % 500;
3079 param_len
= (sys_random() % 64);
3081 rand_buf(param
, param_len
);
3086 param
, param_len
, 8,
3087 NULL
, 0, CLI_BUFFER_SIZE
,
3091 printf("%d/%d\r", i
,count
);
3094 printf("%d/%d\n", i
, count
);
3096 if (!torture_close_connection(cli
)) {
3103 printf("finished random ipc test\n");
3110 static void browse_callback(const char *sname
, uint32_t stype
,
3111 const char *comment
, void *state
)
3113 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3119 This test checks the browse list code
3122 static bool run_browsetest(int dummy
)
3124 static struct cli_state
*cli
;
3125 bool correct
= True
;
3127 printf("starting browse test\n");
3129 if (!torture_open_connection(&cli
, 0)) {
3133 printf("domain list:\n");
3134 cli_NetServerEnum(cli
, cli
->server_domain
,
3135 SV_TYPE_DOMAIN_ENUM
,
3136 browse_callback
, NULL
);
3138 printf("machine list:\n");
3139 cli_NetServerEnum(cli
, cli
->server_domain
,
3141 browse_callback
, NULL
);
3143 if (!torture_close_connection(cli
)) {
3147 printf("browse test finished\n");
3155 This checks how the getatr calls works
3157 static bool run_attrtest(int dummy
)
3159 struct cli_state
*cli
;
3162 const char *fname
= "\\attrib123456789.tst";
3163 bool correct
= True
;
3166 printf("starting attrib test\n");
3168 if (!torture_open_connection(&cli
, 0)) {
3172 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3173 cli_openx(cli
, fname
,
3174 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3175 cli_close(cli
, fnum
);
3177 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3178 if (!NT_STATUS_IS_OK(status
)) {
3179 printf("getatr failed (%s)\n", nt_errstr(status
));
3183 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3184 printf("ERROR: SMBgetatr bug. time is %s",
3190 t2
= t
-60*60*24; /* 1 day ago */
3192 status
= cli_setatr(cli
, fname
, 0, t2
);
3193 if (!NT_STATUS_IS_OK(status
)) {
3194 printf("setatr failed (%s)\n", nt_errstr(status
));
3198 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3199 if (!NT_STATUS_IS_OK(status
)) {
3200 printf("getatr failed (%s)\n", nt_errstr(status
));
3205 printf("ERROR: getatr/setatr bug. times are\n%s",
3207 printf("%s", ctime(&t2
));
3211 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3213 if (!torture_close_connection(cli
)) {
3217 printf("attrib test finished\n");
3224 This checks a couple of trans2 calls
3226 static bool run_trans2test(int dummy
)
3228 struct cli_state
*cli
;
3231 time_t c_time
, a_time
, m_time
;
3232 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3233 const char *fname
= "\\trans2.tst";
3234 const char *dname
= "\\trans2";
3235 const char *fname2
= "\\trans2\\trans2.tst";
3237 bool correct
= True
;
3241 printf("starting trans2 test\n");
3243 if (!torture_open_connection(&cli
, 0)) {
3247 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3248 if (!NT_STATUS_IS_OK(status
)) {
3249 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3254 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3255 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3256 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3257 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3258 if (!NT_STATUS_IS_OK(status
)) {
3259 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3263 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3264 if (!NT_STATUS_IS_OK(status
)) {
3265 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3268 else if (strcmp(pname
, fname
)) {
3269 printf("qfilename gave different name? [%s] [%s]\n",
3274 cli_close(cli
, fnum
);
3278 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3279 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3281 if (!NT_STATUS_IS_OK(status
)) {
3282 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3285 cli_close(cli
, fnum
);
3287 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3289 if (!NT_STATUS_IS_OK(status
)) {
3290 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3293 time_t t
= time(NULL
);
3295 if (c_time
!= m_time
) {
3296 printf("create time=%s", ctime(&c_time
));
3297 printf("modify time=%s", ctime(&m_time
));
3298 printf("This system appears to have sticky create times\n");
3300 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3301 printf("access time=%s", ctime(&a_time
));
3302 printf("This system appears to set a midnight access time\n");
3306 if (abs(m_time
- t
) > 60*60*24*7) {
3307 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3313 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3314 cli_openx(cli
, fname
,
3315 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3316 cli_close(cli
, fnum
);
3317 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3318 &m_time_ts
, &size
, NULL
, NULL
);
3319 if (!NT_STATUS_IS_OK(status
)) {
3320 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3323 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3324 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3325 printf("This system appears to set a initial 0 write time\n");
3330 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3333 /* check if the server updates the directory modification time
3334 when creating a new file */
3335 status
= cli_mkdir(cli
, dname
);
3336 if (!NT_STATUS_IS_OK(status
)) {
3337 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3341 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3342 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3343 if (!NT_STATUS_IS_OK(status
)) {
3344 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3348 cli_openx(cli
, fname2
,
3349 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3350 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3351 cli_close(cli
, fnum
);
3352 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3353 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3354 if (!NT_STATUS_IS_OK(status
)) {
3355 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3358 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3360 printf("This system does not update directory modification times\n");
3364 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3365 cli_rmdir(cli
, dname
);
3367 if (!torture_close_connection(cli
)) {
3371 printf("trans2 test finished\n");
3377 This checks new W2K calls.
3380 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3382 uint8_t *buf
= NULL
;
3386 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3387 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3388 if (!NT_STATUS_IS_OK(status
)) {
3389 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3392 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3393 dump_data(0, (uint8_t *)buf
, len
);
3400 static bool run_w2ktest(int dummy
)
3402 struct cli_state
*cli
;
3404 const char *fname
= "\\w2ktest\\w2k.tst";
3406 bool correct
= True
;
3408 printf("starting w2k test\n");
3410 if (!torture_open_connection(&cli
, 0)) {
3414 cli_openx(cli
, fname
,
3415 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3417 for (level
= 1004; level
< 1040; level
++) {
3418 new_trans(cli
, fnum
, level
);
3421 cli_close(cli
, fnum
);
3423 if (!torture_close_connection(cli
)) {
3427 printf("w2k test finished\n");
3434 this is a harness for some oplock tests
3436 static bool run_oplock1(int dummy
)
3438 struct cli_state
*cli1
;
3439 const char *fname
= "\\lockt1.lck";
3441 bool correct
= True
;
3444 printf("starting oplock test 1\n");
3446 if (!torture_open_connection(&cli1
, 0)) {
3450 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3452 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3454 cli1
->use_oplocks
= True
;
3456 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3458 if (!NT_STATUS_IS_OK(status
)) {
3459 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3463 cli1
->use_oplocks
= False
;
3465 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3466 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3468 status
= cli_close(cli1
, fnum1
);
3469 if (!NT_STATUS_IS_OK(status
)) {
3470 printf("close2 failed (%s)\n", nt_errstr(status
));
3474 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3475 if (!NT_STATUS_IS_OK(status
)) {
3476 printf("unlink failed (%s)\n", nt_errstr(status
));
3480 if (!torture_close_connection(cli1
)) {
3484 printf("finished oplock test 1\n");
3489 static bool run_oplock2(int dummy
)
3491 struct cli_state
*cli1
, *cli2
;
3492 const char *fname
= "\\lockt2.lck";
3493 uint16_t fnum1
, fnum2
;
3494 int saved_use_oplocks
= use_oplocks
;
3496 bool correct
= True
;
3497 volatile bool *shared_correct
;
3501 shared_correct
= (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3502 *shared_correct
= True
;
3504 use_level_II_oplocks
= True
;
3507 printf("starting oplock test 2\n");
3509 if (!torture_open_connection(&cli1
, 0)) {
3510 use_level_II_oplocks
= False
;
3511 use_oplocks
= saved_use_oplocks
;
3515 if (!torture_open_connection(&cli2
, 1)) {
3516 use_level_II_oplocks
= False
;
3517 use_oplocks
= saved_use_oplocks
;
3521 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3523 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3524 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3526 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3528 if (!NT_STATUS_IS_OK(status
)) {
3529 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3533 /* Don't need the globals any more. */
3534 use_level_II_oplocks
= False
;
3535 use_oplocks
= saved_use_oplocks
;
3539 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3540 if (!NT_STATUS_IS_OK(status
)) {
3541 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3542 *shared_correct
= False
;
3548 status
= cli_close(cli2
, fnum2
);
3549 if (!NT_STATUS_IS_OK(status
)) {
3550 printf("close2 failed (%s)\n", nt_errstr(status
));
3551 *shared_correct
= False
;
3559 /* Ensure cli1 processes the break. Empty file should always return 0
3561 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3562 if (!NT_STATUS_IS_OK(status
)) {
3563 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3565 } else if (nread
!= 0) {
3566 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3567 (unsigned long)nread
, 0);
3571 /* Should now be at level II. */
3572 /* Test if sending a write locks causes a break to none. */
3573 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3574 if (!NT_STATUS_IS_OK(status
)) {
3575 printf("lock failed (%s)\n", nt_errstr(status
));
3579 cli_unlock(cli1
, fnum1
, 0, 4);
3583 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3584 if (!NT_STATUS_IS_OK(status
)) {
3585 printf("lock failed (%s)\n", nt_errstr(status
));
3589 cli_unlock(cli1
, fnum1
, 0, 4);
3593 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3595 status
= cli_close(cli1
, fnum1
);
3596 if (!NT_STATUS_IS_OK(status
)) {
3597 printf("close1 failed (%s)\n", nt_errstr(status
));
3603 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3604 if (!NT_STATUS_IS_OK(status
)) {
3605 printf("unlink failed (%s)\n", nt_errstr(status
));
3609 if (!torture_close_connection(cli1
)) {
3613 if (!*shared_correct
) {
3617 printf("finished oplock test 2\n");
3622 struct oplock4_state
{
3623 struct tevent_context
*ev
;
3624 struct cli_state
*cli
;
3629 static void oplock4_got_break(struct tevent_req
*req
);
3630 static void oplock4_got_open(struct tevent_req
*req
);
3632 static bool run_oplock4(int dummy
)
3634 struct tevent_context
*ev
;
3635 struct cli_state
*cli1
, *cli2
;
3636 struct tevent_req
*oplock_req
, *open_req
;
3637 const char *fname
= "\\lockt4.lck";
3638 const char *fname_ln
= "\\lockt4_ln.lck";
3639 uint16_t fnum1
, fnum2
;
3640 int saved_use_oplocks
= use_oplocks
;
3642 bool correct
= true;
3646 struct oplock4_state
*state
;
3648 printf("starting oplock test 4\n");
3650 if (!torture_open_connection(&cli1
, 0)) {
3651 use_level_II_oplocks
= false;
3652 use_oplocks
= saved_use_oplocks
;
3656 if (!torture_open_connection(&cli2
, 1)) {
3657 use_level_II_oplocks
= false;
3658 use_oplocks
= saved_use_oplocks
;
3662 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3663 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3665 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3666 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3668 /* Create the file. */
3669 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3671 if (!NT_STATUS_IS_OK(status
)) {
3672 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3676 status
= cli_close(cli1
, fnum1
);
3677 if (!NT_STATUS_IS_OK(status
)) {
3678 printf("close1 failed (%s)\n", nt_errstr(status
));
3682 /* Now create a hardlink. */
3683 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3684 if (!NT_STATUS_IS_OK(status
)) {
3685 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3689 /* Prove that opening hardlinks cause deny modes to conflict. */
3690 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3691 if (!NT_STATUS_IS_OK(status
)) {
3692 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3696 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3697 if (NT_STATUS_IS_OK(status
)) {
3698 printf("open of %s succeeded - should fail with sharing violation.\n",
3703 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3704 printf("open of %s should fail with sharing violation. Got %s\n",
3705 fname_ln
, nt_errstr(status
));
3709 status
= cli_close(cli1
, fnum1
);
3710 if (!NT_STATUS_IS_OK(status
)) {
3711 printf("close1 failed (%s)\n", nt_errstr(status
));
3715 cli1
->use_oplocks
= true;
3716 cli2
->use_oplocks
= true;
3718 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3719 if (!NT_STATUS_IS_OK(status
)) {
3720 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3724 ev
= samba_tevent_context_init(talloc_tos());
3726 printf("tevent_context_init failed\n");
3730 state
= talloc(ev
, struct oplock4_state
);
3731 if (state
== NULL
) {
3732 printf("talloc failed\n");
3737 state
->got_break
= &got_break
;
3738 state
->fnum2
= &fnum2
;
3740 oplock_req
= cli_smb_oplock_break_waiter_send(
3741 talloc_tos(), ev
, cli1
);
3742 if (oplock_req
== NULL
) {
3743 printf("cli_smb_oplock_break_waiter_send failed\n");
3746 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3748 open_req
= cli_openx_send(
3749 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3750 if (open_req
== NULL
) {
3751 printf("cli_openx_send failed\n");
3754 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3759 while (!got_break
|| fnum2
== 0xffff) {
3761 ret
= tevent_loop_once(ev
);
3763 printf("tevent_loop_once failed: %s\n",
3769 status
= cli_close(cli2
, fnum2
);
3770 if (!NT_STATUS_IS_OK(status
)) {
3771 printf("close2 failed (%s)\n", nt_errstr(status
));
3775 status
= cli_close(cli1
, fnum1
);
3776 if (!NT_STATUS_IS_OK(status
)) {
3777 printf("close1 failed (%s)\n", nt_errstr(status
));
3781 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3782 if (!NT_STATUS_IS_OK(status
)) {
3783 printf("unlink failed (%s)\n", nt_errstr(status
));
3787 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3788 if (!NT_STATUS_IS_OK(status
)) {
3789 printf("unlink failed (%s)\n", nt_errstr(status
));
3793 if (!torture_close_connection(cli1
)) {
3801 printf("finished oplock test 4\n");
3806 static void oplock4_got_break(struct tevent_req
*req
)
3808 struct oplock4_state
*state
= tevent_req_callback_data(
3809 req
, struct oplock4_state
);
3814 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3816 if (!NT_STATUS_IS_OK(status
)) {
3817 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3821 *state
->got_break
= true;
3823 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3826 printf("cli_oplock_ack_send failed\n");
3831 static void oplock4_got_open(struct tevent_req
*req
)
3833 struct oplock4_state
*state
= tevent_req_callback_data(
3834 req
, struct oplock4_state
);
3837 status
= cli_openx_recv(req
, state
->fnum2
);
3838 if (!NT_STATUS_IS_OK(status
)) {
3839 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
3840 *state
->fnum2
= 0xffff;
3845 Test delete on close semantics.
3847 static bool run_deletetest(int dummy
)
3849 struct cli_state
*cli1
= NULL
;
3850 struct cli_state
*cli2
= NULL
;
3851 const char *fname
= "\\delete.file";
3852 uint16_t fnum1
= (uint16_t)-1;
3853 uint16_t fnum2
= (uint16_t)-1;
3854 bool correct
= false;
3857 printf("starting delete test\n");
3859 if (!torture_open_connection(&cli1
, 0)) {
3863 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3865 /* Test 1 - this should delete the file on close. */
3867 cli_setatr(cli1
, fname
, 0, 0);
3868 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3870 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3871 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3872 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
3873 if (!NT_STATUS_IS_OK(status
)) {
3874 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3878 status
= cli_close(cli1
, fnum1
);
3879 if (!NT_STATUS_IS_OK(status
)) {
3880 printf("[1] close failed (%s)\n", nt_errstr(status
));
3884 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3885 if (NT_STATUS_IS_OK(status
)) {
3886 printf("[1] open of %s succeeded (should fail)\n", fname
);
3890 printf("first delete on close test succeeded.\n");
3892 /* Test 2 - this should delete the file on close. */
3894 cli_setatr(cli1
, fname
, 0, 0);
3895 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3897 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3898 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3899 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3900 if (!NT_STATUS_IS_OK(status
)) {
3901 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3905 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3906 if (!NT_STATUS_IS_OK(status
)) {
3907 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3911 status
= cli_close(cli1
, fnum1
);
3912 if (!NT_STATUS_IS_OK(status
)) {
3913 printf("[2] close failed (%s)\n", nt_errstr(status
));
3917 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3918 if (NT_STATUS_IS_OK(status
)) {
3919 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3920 status
= cli_close(cli1
, fnum1
);
3921 if (!NT_STATUS_IS_OK(status
)) {
3922 printf("[2] close failed (%s)\n", nt_errstr(status
));
3924 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3928 printf("second delete on close test succeeded.\n");
3931 cli_setatr(cli1
, fname
, 0, 0);
3932 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3934 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3935 FILE_ATTRIBUTE_NORMAL
,
3936 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3937 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3938 if (!NT_STATUS_IS_OK(status
)) {
3939 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
3943 /* This should fail with a sharing violation - open for delete is only compatible
3944 with SHARE_DELETE. */
3946 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3947 FILE_ATTRIBUTE_NORMAL
,
3948 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3949 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3950 if (NT_STATUS_IS_OK(status
)) {
3951 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3955 /* This should succeed. */
3956 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3957 FILE_ATTRIBUTE_NORMAL
,
3958 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3959 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3960 if (!NT_STATUS_IS_OK(status
)) {
3961 printf("[3] open - 3 of %s failed (%s)\n", fname
, nt_errstr(status
));
3965 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3966 if (!NT_STATUS_IS_OK(status
)) {
3967 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3971 status
= cli_close(cli1
, fnum1
);
3972 if (!NT_STATUS_IS_OK(status
)) {
3973 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
3977 status
= cli_close(cli1
, fnum2
);
3978 if (!NT_STATUS_IS_OK(status
)) {
3979 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
3983 /* This should fail - file should no longer be there. */
3985 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3986 if (NT_STATUS_IS_OK(status
)) {
3987 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3988 status
= cli_close(cli1
, fnum1
);
3989 if (!NT_STATUS_IS_OK(status
)) {
3990 printf("[3] close failed (%s)\n", nt_errstr(status
));
3992 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3996 printf("third delete on close test succeeded.\n");
3999 cli_setatr(cli1
, fname
, 0, 0);
4000 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4002 status
= cli_ntcreate(cli1
, fname
, 0,
4003 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4004 FILE_ATTRIBUTE_NORMAL
,
4005 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4006 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4007 if (!NT_STATUS_IS_OK(status
)) {
4008 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4012 /* This should succeed. */
4013 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4014 FILE_ATTRIBUTE_NORMAL
,
4015 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4016 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4017 if (!NT_STATUS_IS_OK(status
)) {
4018 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4022 status
= cli_close(cli1
, fnum2
);
4023 if (!NT_STATUS_IS_OK(status
)) {
4024 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4028 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4029 if (!NT_STATUS_IS_OK(status
)) {
4030 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4034 /* This should fail - no more opens once delete on close set. */
4035 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4036 FILE_ATTRIBUTE_NORMAL
,
4037 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4038 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4039 if (NT_STATUS_IS_OK(status
)) {
4040 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4044 status
= cli_close(cli1
, fnum1
);
4045 if (!NT_STATUS_IS_OK(status
)) {
4046 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4050 printf("fourth delete on close test succeeded.\n");
4053 cli_setatr(cli1
, fname
, 0, 0);
4054 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4056 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4057 if (!NT_STATUS_IS_OK(status
)) {
4058 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4062 /* This should fail - only allowed on NT opens with DELETE access. */
4064 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4065 if (NT_STATUS_IS_OK(status
)) {
4066 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4070 status
= cli_close(cli1
, fnum1
);
4071 if (!NT_STATUS_IS_OK(status
)) {
4072 printf("[5] close failed (%s)\n", nt_errstr(status
));
4076 printf("fifth delete on close test succeeded.\n");
4079 cli_setatr(cli1
, fname
, 0, 0);
4080 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4082 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4083 FILE_ATTRIBUTE_NORMAL
,
4084 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4085 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4086 if (!NT_STATUS_IS_OK(status
)) {
4087 printf("[6] open of %s failed (%s)\n", fname
,
4092 /* This should fail - only allowed on NT opens with DELETE access. */
4094 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4095 if (NT_STATUS_IS_OK(status
)) {
4096 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4100 status
= cli_close(cli1
, fnum1
);
4101 if (!NT_STATUS_IS_OK(status
)) {
4102 printf("[6] close failed (%s)\n", nt_errstr(status
));
4106 printf("sixth delete on close test succeeded.\n");
4109 cli_setatr(cli1
, fname
, 0, 0);
4110 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4112 status
= cli_ntcreate(cli1
, fname
, 0,
4113 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4114 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4115 0, 0, &fnum1
, NULL
);
4116 if (!NT_STATUS_IS_OK(status
)) {
4117 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4121 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4122 if (!NT_STATUS_IS_OK(status
)) {
4123 printf("[7] setting delete_on_close on file failed !\n");
4127 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4128 if (!NT_STATUS_IS_OK(status
)) {
4129 printf("[7] unsetting delete_on_close on file failed !\n");
4133 status
= cli_close(cli1
, fnum1
);
4134 if (!NT_STATUS_IS_OK(status
)) {
4135 printf("[7] close - 1 failed (%s)\n", nt_errstr(status
));
4139 /* This next open should succeed - we reset the flag. */
4140 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4141 if (!NT_STATUS_IS_OK(status
)) {
4142 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4146 status
= cli_close(cli1
, fnum1
);
4147 if (!NT_STATUS_IS_OK(status
)) {
4148 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4152 printf("seventh delete on close test succeeded.\n");
4155 cli_setatr(cli1
, fname
, 0, 0);
4156 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4158 if (!torture_open_connection(&cli2
, 1)) {
4159 printf("[8] failed to open second connection.\n");
4163 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4165 status
= cli_ntcreate(cli1
, fname
, 0,
4166 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4167 FILE_ATTRIBUTE_NORMAL
,
4168 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4169 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4170 if (!NT_STATUS_IS_OK(status
)) {
4171 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4175 status
= cli_ntcreate(cli2
, fname
, 0,
4176 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4177 FILE_ATTRIBUTE_NORMAL
,
4178 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4179 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4180 if (!NT_STATUS_IS_OK(status
)) {
4181 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4185 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4186 if (!NT_STATUS_IS_OK(status
)) {
4187 printf("[8] setting delete_on_close on file failed !\n");
4191 status
= cli_close(cli1
, fnum1
);
4192 if (!NT_STATUS_IS_OK(status
)) {
4193 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4197 status
= cli_close(cli2
, fnum2
);
4198 if (!NT_STATUS_IS_OK(status
)) {
4199 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4203 /* This should fail.. */
4204 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4205 if (NT_STATUS_IS_OK(status
)) {
4206 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4210 printf("eighth delete on close test succeeded.\n");
4214 /* This should fail - we need to set DELETE_ACCESS. */
4215 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4216 FILE_ATTRIBUTE_NORMAL
,
4219 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4220 if (NT_STATUS_IS_OK(status
)) {
4221 printf("[9] open of %s succeeded should have failed!\n", fname
);
4225 printf("ninth delete on close test succeeded.\n");
4229 status
= cli_ntcreate(cli1
, fname
, 0,
4230 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4231 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4232 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4234 if (!NT_STATUS_IS_OK(status
)) {
4235 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4239 /* This should delete the file. */
4240 status
= cli_close(cli1
, fnum1
);
4241 if (!NT_STATUS_IS_OK(status
)) {
4242 printf("[10] close failed (%s)\n", nt_errstr(status
));
4246 /* This should fail.. */
4247 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4248 if (NT_STATUS_IS_OK(status
)) {
4249 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4253 printf("tenth delete on close test succeeded.\n");
4257 cli_setatr(cli1
, fname
, 0, 0);
4258 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4260 /* Can we open a read-only file with delete access? */
4262 /* Create a readonly file. */
4263 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4264 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4265 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4266 if (!NT_STATUS_IS_OK(status
)) {
4267 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4271 status
= cli_close(cli1
, fnum1
);
4272 if (!NT_STATUS_IS_OK(status
)) {
4273 printf("[11] close failed (%s)\n", nt_errstr(status
));
4277 /* Now try open for delete access. */
4278 status
= cli_ntcreate(cli1
, fname
, 0,
4279 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4281 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4282 FILE_OPEN
, 0, 0, &fnum1
, NULL
);
4283 if (!NT_STATUS_IS_OK(status
)) {
4284 printf("[11] open of %s failed: %s\n", fname
, nt_errstr(status
));
4288 cli_close(cli1
, fnum1
);
4290 printf("eleventh delete on close test succeeded.\n");
4294 * like test 4 but with initial delete on close
4297 cli_setatr(cli1
, fname
, 0, 0);
4298 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4300 status
= cli_ntcreate(cli1
, fname
, 0,
4301 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4302 FILE_ATTRIBUTE_NORMAL
,
4303 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4305 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4306 if (!NT_STATUS_IS_OK(status
)) {
4307 printf("[12] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4311 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4312 FILE_ATTRIBUTE_NORMAL
,
4313 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4314 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4315 if (!NT_STATUS_IS_OK(status
)) {
4316 printf("[12] open 2 of %s failed(%s).\n", fname
, nt_errstr(status
));
4320 status
= cli_close(cli1
, fnum2
);
4321 if (!NT_STATUS_IS_OK(status
)) {
4322 printf("[12] close 1 failed (%s)\n", nt_errstr(status
));
4326 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4327 if (!NT_STATUS_IS_OK(status
)) {
4328 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4332 /* This should fail - no more opens once delete on close set. */
4333 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4334 FILE_ATTRIBUTE_NORMAL
,
4335 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4336 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4337 if (NT_STATUS_IS_OK(status
)) {
4338 printf("[12] open 3 of %s succeeded - should fail).\n", fname
);
4342 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4343 if (!NT_STATUS_IS_OK(status
)) {
4344 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status
));
4348 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4349 FILE_ATTRIBUTE_NORMAL
,
4350 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4351 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4352 if (!NT_STATUS_IS_OK(status
)) {
4353 printf("[12] open 4 of %s failed (%s)\n", fname
, nt_errstr(status
));
4357 status
= cli_close(cli1
, fnum2
);
4358 if (!NT_STATUS_IS_OK(status
)) {
4359 printf("[12] close 2 failed (%s)\n", nt_errstr(status
));
4363 status
= cli_close(cli1
, fnum1
);
4364 if (!NT_STATUS_IS_OK(status
)) {
4365 printf("[12] close 3 failed (%s)\n", nt_errstr(status
));
4370 * setting delete on close on the handle does
4371 * not unset the initial delete on close...
4373 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4374 FILE_ATTRIBUTE_NORMAL
,
4375 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4376 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4377 if (NT_STATUS_IS_OK(status
)) {
4378 printf("[12] open 5 of %s succeeded - should fail).\n", fname
);
4380 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4381 printf("ntcreate returned %s, expected "
4382 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4387 printf("twelfth delete on close test succeeded.\n");
4390 printf("finished delete test\n");
4395 /* FIXME: This will crash if we aborted before cli2 got
4396 * intialized, because these functions don't handle
4397 * uninitialized connections. */
4399 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4400 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4401 cli_setatr(cli1
, fname
, 0, 0);
4402 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4404 if (cli1
&& !torture_close_connection(cli1
)) {
4407 if (cli2
&& !torture_close_connection(cli2
)) {
4415 Test wildcard delete.
4417 static bool run_wild_deletetest(int dummy
)
4419 struct cli_state
*cli
= NULL
;
4420 const char *dname
= "\\WTEST";
4421 const char *fname
= "\\WTEST\\A";
4422 const char *wunlink_name
= "\\WTEST\\*";
4423 uint16_t fnum1
= (uint16_t)-1;
4424 bool correct
= false;
4427 printf("starting wildcard delete test\n");
4429 if (!torture_open_connection(&cli
, 0)) {
4433 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4435 cli_unlink(cli
, fname
, 0);
4436 cli_rmdir(cli
, dname
);
4437 status
= cli_mkdir(cli
, dname
);
4438 if (!NT_STATUS_IS_OK(status
)) {
4439 printf("mkdir of %s failed %s!\n", dname
, nt_errstr(status
));
4442 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDONLY
, DENY_NONE
, &fnum1
);
4443 if (!NT_STATUS_IS_OK(status
)) {
4444 printf("open of %s failed %s!\n", fname
, nt_errstr(status
));
4447 status
= cli_close(cli
, fnum1
);
4451 * Note the unlink attribute-type of zero. This should
4452 * map into FILE_ATTRIBUTE_NORMAL at the server even
4453 * on a wildcard delete.
4456 status
= cli_unlink(cli
, wunlink_name
, 0);
4457 if (!NT_STATUS_IS_OK(status
)) {
4458 printf("unlink of %s failed %s!\n",
4459 wunlink_name
, nt_errstr(status
));
4463 printf("finished wildcard delete test\n");
4469 if (fnum1
!= (uint16_t)-1) cli_close(cli
, fnum1
);
4470 cli_unlink(cli
, fname
, 0);
4471 cli_rmdir(cli
, dname
);
4473 if (cli
&& !torture_close_connection(cli
)) {
4479 static bool run_deletetest_ln(int dummy
)
4481 struct cli_state
*cli
;
4482 const char *fname
= "\\delete1";
4483 const char *fname_ln
= "\\delete1_ln";
4487 bool correct
= true;
4490 printf("starting deletetest-ln\n");
4492 if (!torture_open_connection(&cli
, 0)) {
4496 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4497 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4499 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4501 /* Create the file. */
4502 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4503 if (!NT_STATUS_IS_OK(status
)) {
4504 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4508 status
= cli_close(cli
, fnum
);
4509 if (!NT_STATUS_IS_OK(status
)) {
4510 printf("close1 failed (%s)\n", nt_errstr(status
));
4514 /* Now create a hardlink. */
4515 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4516 if (!NT_STATUS_IS_OK(status
)) {
4517 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4521 /* Open the original file. */
4522 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4523 FILE_ATTRIBUTE_NORMAL
,
4524 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4525 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4526 if (!NT_STATUS_IS_OK(status
)) {
4527 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4531 /* Unlink the hard link path. */
4532 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4533 FILE_ATTRIBUTE_NORMAL
,
4534 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4535 FILE_OPEN_IF
, 0, 0, &fnum1
, NULL
);
4536 if (!NT_STATUS_IS_OK(status
)) {
4537 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4540 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4541 if (!NT_STATUS_IS_OK(status
)) {
4542 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4543 __location__
, fname_ln
, nt_errstr(status
));
4547 status
= cli_close(cli
, fnum1
);
4548 if (!NT_STATUS_IS_OK(status
)) {
4549 printf("close %s failed (%s)\n",
4550 fname_ln
, nt_errstr(status
));
4554 status
= cli_close(cli
, fnum
);
4555 if (!NT_STATUS_IS_OK(status
)) {
4556 printf("close %s failed (%s)\n",
4557 fname
, nt_errstr(status
));
4561 /* Ensure the original file is still there. */
4562 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4563 if (!NT_STATUS_IS_OK(status
)) {
4564 printf("%s getatr on file %s failed (%s)\n",
4571 /* Ensure the link path is gone. */
4572 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4573 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4574 printf("%s, getatr for file %s returned wrong error code %s "
4575 "- should have been deleted\n",
4577 fname_ln
, nt_errstr(status
));
4581 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4582 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4584 if (!torture_close_connection(cli
)) {
4588 printf("finished deletetest-ln\n");
4594 print out server properties
4596 static bool run_properties(int dummy
)
4598 struct cli_state
*cli
;
4599 bool correct
= True
;
4601 printf("starting properties test\n");
4605 if (!torture_open_connection(&cli
, 0)) {
4609 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4611 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
4613 if (!torture_close_connection(cli
)) {
4622 /* FIRST_DESIRED_ACCESS 0xf019f */
4623 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4624 FILE_READ_EA| /* 0xf */ \
4625 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4626 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4627 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4628 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4629 /* SECOND_DESIRED_ACCESS 0xe0080 */
4630 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4631 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4632 WRITE_OWNER_ACCESS /* 0xe0000 */
4635 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4636 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4638 WRITE_OWNER_ACCESS /* */
4642 Test ntcreate calls made by xcopy
4644 static bool run_xcopy(int dummy
)
4646 static struct cli_state
*cli1
;
4647 const char *fname
= "\\test.txt";
4648 bool correct
= True
;
4649 uint16_t fnum1
, fnum2
;
4652 printf("starting xcopy test\n");
4654 if (!torture_open_connection(&cli1
, 0)) {
4658 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4659 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4660 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
, NULL
);
4661 if (!NT_STATUS_IS_OK(status
)) {
4662 printf("First open failed - %s\n", nt_errstr(status
));
4666 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4667 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4668 FILE_OPEN
, 0x200000, 0, &fnum2
, NULL
);
4669 if (!NT_STATUS_IS_OK(status
)) {
4670 printf("second open failed - %s\n", nt_errstr(status
));
4674 if (!torture_close_connection(cli1
)) {
4682 Test rename on files open with share delete and no share delete.
4684 static bool run_rename(int dummy
)
4686 static struct cli_state
*cli1
;
4687 const char *fname
= "\\test.txt";
4688 const char *fname1
= "\\test1.txt";
4689 bool correct
= True
;
4694 printf("starting rename test\n");
4696 if (!torture_open_connection(&cli1
, 0)) {
4700 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4701 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4703 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4704 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4705 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4706 if (!NT_STATUS_IS_OK(status
)) {
4707 printf("First open failed - %s\n", nt_errstr(status
));
4711 status
= cli_rename(cli1
, fname
, fname1
);
4712 if (!NT_STATUS_IS_OK(status
)) {
4713 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4715 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4719 status
= cli_close(cli1
, fnum1
);
4720 if (!NT_STATUS_IS_OK(status
)) {
4721 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4725 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4726 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4727 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4729 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4731 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4733 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4734 if (!NT_STATUS_IS_OK(status
)) {
4735 printf("Second open failed - %s\n", nt_errstr(status
));
4739 status
= cli_rename(cli1
, fname
, fname1
);
4740 if (!NT_STATUS_IS_OK(status
)) {
4741 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4744 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4747 status
= cli_close(cli1
, fnum1
);
4748 if (!NT_STATUS_IS_OK(status
)) {
4749 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4753 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4754 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4756 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4757 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4758 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4759 if (!NT_STATUS_IS_OK(status
)) {
4760 printf("Third open failed - %s\n", nt_errstr(status
));
4769 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4770 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
, NULL
))) {
4771 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4774 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4775 printf("[8] setting delete_on_close on file failed !\n");
4779 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4780 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4786 status
= cli_rename(cli1
, fname
, fname1
);
4787 if (!NT_STATUS_IS_OK(status
)) {
4788 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4791 printf("Third rename succeeded (SHARE_NONE)\n");
4794 status
= cli_close(cli1
, fnum1
);
4795 if (!NT_STATUS_IS_OK(status
)) {
4796 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4800 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4801 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4805 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4806 FILE_ATTRIBUTE_NORMAL
,
4807 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4808 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4809 if (!NT_STATUS_IS_OK(status
)) {
4810 printf("Fourth open failed - %s\n", nt_errstr(status
));
4814 status
= cli_rename(cli1
, fname
, fname1
);
4815 if (!NT_STATUS_IS_OK(status
)) {
4816 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4818 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4822 status
= cli_close(cli1
, fnum1
);
4823 if (!NT_STATUS_IS_OK(status
)) {
4824 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4828 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4829 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4833 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4834 FILE_ATTRIBUTE_NORMAL
,
4835 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4836 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4837 if (!NT_STATUS_IS_OK(status
)) {
4838 printf("Fifth open failed - %s\n", nt_errstr(status
));
4842 status
= cli_rename(cli1
, fname
, fname1
);
4843 if (!NT_STATUS_IS_OK(status
)) {
4844 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4847 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4851 * Now check if the first name still exists ...
4854 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4855 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4857 printf("Opening original file after rename of open file fails: %s\n",
4861 printf("Opening original file after rename of open file works ...\n");
4862 (void)cli_close(cli1, fnum2);
4866 status
= cli_close(cli1
, fnum1
);
4867 if (!NT_STATUS_IS_OK(status
)) {
4868 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4872 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4873 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4874 if (!NT_STATUS_IS_OK(status
)) {
4875 printf("getatr on file %s failed - %s ! \n",
4876 fname1
, nt_errstr(status
));
4879 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4880 printf("Renamed file %s has wrong attr 0x%x "
4881 "(should be 0x%x)\n",
4884 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4887 printf("Renamed file %s has archive bit set\n", fname1
);
4891 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4892 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4894 if (!torture_close_connection(cli1
)) {
4901 static bool run_pipe_number(int dummy
)
4903 struct cli_state
*cli1
;
4904 const char *pipe_name
= "\\SPOOLSS";
4909 printf("starting pipenumber test\n");
4910 if (!torture_open_connection(&cli1
, 0)) {
4914 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4916 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4917 FILE_ATTRIBUTE_NORMAL
,
4918 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4919 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4920 if (!NT_STATUS_IS_OK(status
)) {
4921 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4925 printf("\r%6d", num_pipes
);
4928 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4929 torture_close_connection(cli1
);
4934 Test open mode returns on read-only files.
4936 static bool run_opentest(int dummy
)
4938 static struct cli_state
*cli1
;
4939 static struct cli_state
*cli2
;
4940 const char *fname
= "\\readonly.file";
4941 uint16_t fnum1
, fnum2
;
4944 bool correct
= True
;
4948 printf("starting open test\n");
4950 if (!torture_open_connection(&cli1
, 0)) {
4954 cli_setatr(cli1
, fname
, 0, 0);
4955 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4957 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4959 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4960 if (!NT_STATUS_IS_OK(status
)) {
4961 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4965 status
= cli_close(cli1
, fnum1
);
4966 if (!NT_STATUS_IS_OK(status
)) {
4967 printf("close2 failed (%s)\n", nt_errstr(status
));
4971 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4972 if (!NT_STATUS_IS_OK(status
)) {
4973 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4977 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4978 if (!NT_STATUS_IS_OK(status
)) {
4979 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4983 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4984 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4986 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
4987 NT_STATUS_ACCESS_DENIED
)) {
4988 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4991 printf("finished open test 1\n");
4993 cli_close(cli1
, fnum1
);
4995 /* Now try not readonly and ensure ERRbadshare is returned. */
4997 cli_setatr(cli1
, fname
, 0, 0);
4999 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
5000 if (!NT_STATUS_IS_OK(status
)) {
5001 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5005 /* This will fail - but the error should be ERRshare. */
5006 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
5008 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
5009 NT_STATUS_SHARING_VIOLATION
)) {
5010 printf("correct error code ERRDOS/ERRbadshare returned\n");
5013 status
= cli_close(cli1
, fnum1
);
5014 if (!NT_STATUS_IS_OK(status
)) {
5015 printf("close2 failed (%s)\n", nt_errstr(status
));
5019 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5021 printf("finished open test 2\n");
5023 /* Test truncate open disposition on file opened for read. */
5024 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
5025 if (!NT_STATUS_IS_OK(status
)) {
5026 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
5030 /* write 20 bytes. */
5032 memset(buf
, '\0', 20);
5034 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
5035 if (!NT_STATUS_IS_OK(status
)) {
5036 printf("write failed (%s)\n", nt_errstr(status
));
5040 status
= cli_close(cli1
, fnum1
);
5041 if (!NT_STATUS_IS_OK(status
)) {
5042 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
5046 /* Ensure size == 20. */
5047 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5048 if (!NT_STATUS_IS_OK(status
)) {
5049 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5054 printf("(3) file size != 20\n");
5058 /* Now test if we can truncate a file opened for readonly. */
5059 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
5060 if (!NT_STATUS_IS_OK(status
)) {
5061 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
5065 status
= cli_close(cli1
, fnum1
);
5066 if (!NT_STATUS_IS_OK(status
)) {
5067 printf("close2 failed (%s)\n", nt_errstr(status
));
5071 /* Ensure size == 0. */
5072 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5073 if (!NT_STATUS_IS_OK(status
)) {
5074 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5079 printf("(3) file size != 0\n");
5082 printf("finished open test 3\n");
5084 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5086 printf("Do ctemp tests\n");
5087 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
5088 if (!NT_STATUS_IS_OK(status
)) {
5089 printf("ctemp failed (%s)\n", nt_errstr(status
));
5093 printf("ctemp gave path %s\n", tmp_path
);
5094 status
= cli_close(cli1
, fnum1
);
5095 if (!NT_STATUS_IS_OK(status
)) {
5096 printf("close of temp failed (%s)\n", nt_errstr(status
));
5099 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5100 if (!NT_STATUS_IS_OK(status
)) {
5101 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5104 /* Test the non-io opens... */
5106 if (!torture_open_connection(&cli2
, 1)) {
5110 cli_setatr(cli2
, fname
, 0, 0);
5111 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5113 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
5115 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5116 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5117 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5118 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5119 if (!NT_STATUS_IS_OK(status
)) {
5120 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5124 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5125 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5126 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5127 if (!NT_STATUS_IS_OK(status
)) {
5128 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5132 status
= cli_close(cli1
, fnum1
);
5133 if (!NT_STATUS_IS_OK(status
)) {
5134 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5138 status
= cli_close(cli2
, fnum2
);
5139 if (!NT_STATUS_IS_OK(status
)) {
5140 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5144 printf("non-io open test #1 passed.\n");
5146 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5148 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5150 status
= cli_ntcreate(cli1
, fname
, 0,
5151 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5152 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5153 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5154 if (!NT_STATUS_IS_OK(status
)) {
5155 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5159 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5160 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5161 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5162 if (!NT_STATUS_IS_OK(status
)) {
5163 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5167 status
= cli_close(cli1
, fnum1
);
5168 if (!NT_STATUS_IS_OK(status
)) {
5169 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5173 status
= cli_close(cli2
, fnum2
);
5174 if (!NT_STATUS_IS_OK(status
)) {
5175 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5179 printf("non-io open test #2 passed.\n");
5181 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5183 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5185 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5186 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5187 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5188 if (!NT_STATUS_IS_OK(status
)) {
5189 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5193 status
= cli_ntcreate(cli2
, fname
, 0,
5194 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5195 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5196 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5197 if (!NT_STATUS_IS_OK(status
)) {
5198 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5202 status
= cli_close(cli1
, fnum1
);
5203 if (!NT_STATUS_IS_OK(status
)) {
5204 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5208 status
= cli_close(cli2
, fnum2
);
5209 if (!NT_STATUS_IS_OK(status
)) {
5210 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5214 printf("non-io open test #3 passed.\n");
5216 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5218 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5220 status
= cli_ntcreate(cli1
, fname
, 0,
5221 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5222 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5223 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5224 if (!NT_STATUS_IS_OK(status
)) {
5225 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5229 status
= cli_ntcreate(cli2
, fname
, 0,
5230 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5231 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5232 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5233 if (NT_STATUS_IS_OK(status
)) {
5234 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5238 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5240 status
= cli_close(cli1
, fnum1
);
5241 if (!NT_STATUS_IS_OK(status
)) {
5242 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5246 printf("non-io open test #4 passed.\n");
5248 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5250 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5252 status
= cli_ntcreate(cli1
, fname
, 0,
5253 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5254 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5255 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5256 if (!NT_STATUS_IS_OK(status
)) {
5257 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5261 status
= cli_ntcreate(cli2
, fname
, 0,
5262 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5263 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5264 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5265 if (!NT_STATUS_IS_OK(status
)) {
5266 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5270 status
= cli_close(cli1
, fnum1
);
5271 if (!NT_STATUS_IS_OK(status
)) {
5272 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5276 status
= cli_close(cli2
, fnum2
);
5277 if (!NT_STATUS_IS_OK(status
)) {
5278 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5282 printf("non-io open test #5 passed.\n");
5284 printf("TEST #6 testing 1 non-io open, one io open\n");
5286 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5288 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5289 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5290 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5291 if (!NT_STATUS_IS_OK(status
)) {
5292 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5296 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5297 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5298 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5299 if (!NT_STATUS_IS_OK(status
)) {
5300 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5304 status
= cli_close(cli1
, fnum1
);
5305 if (!NT_STATUS_IS_OK(status
)) {
5306 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5310 status
= cli_close(cli2
, fnum2
);
5311 if (!NT_STATUS_IS_OK(status
)) {
5312 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5316 printf("non-io open test #6 passed.\n");
5318 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5320 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5322 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5323 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5324 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5325 if (!NT_STATUS_IS_OK(status
)) {
5326 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5330 status
= cli_ntcreate(cli2
, fname
, 0,
5331 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5332 FILE_ATTRIBUTE_NORMAL
,
5333 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5334 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5335 if (NT_STATUS_IS_OK(status
)) {
5336 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5340 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5342 status
= cli_close(cli1
, fnum1
);
5343 if (!NT_STATUS_IS_OK(status
)) {
5344 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5348 printf("non-io open test #7 passed.\n");
5350 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5352 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5353 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5354 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5355 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5356 if (!NT_STATUS_IS_OK(status
)) {
5357 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5362 /* Write to ensure we have to update the file time. */
5363 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5365 if (!NT_STATUS_IS_OK(status
)) {
5366 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5371 status
= cli_close(cli1
, fnum1
);
5372 if (!NT_STATUS_IS_OK(status
)) {
5373 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5379 if (!torture_close_connection(cli1
)) {
5382 if (!torture_close_connection(cli2
)) {
5389 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5391 uint16_t major
, minor
;
5392 uint32_t caplow
, caphigh
;
5395 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5396 printf("Server doesn't support UNIX CIFS extensions.\n");
5397 return NT_STATUS_NOT_SUPPORTED
;
5400 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5402 if (!NT_STATUS_IS_OK(status
)) {
5403 printf("Server didn't return UNIX CIFS extensions: %s\n",
5408 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5410 if (!NT_STATUS_IS_OK(status
)) {
5411 printf("Server doesn't support setting UNIX CIFS extensions: "
5412 "%s.\n", nt_errstr(status
));
5416 return NT_STATUS_OK
;
5420 Test POSIX open /mkdir calls.
5422 static bool run_simple_posix_open_test(int dummy
)
5424 static struct cli_state
*cli1
;
5425 const char *fname
= "posix:file";
5426 const char *hname
= "posix:hlink";
5427 const char *sname
= "posix:symlink";
5428 const char *dname
= "posix:dir";
5431 uint16_t fnum1
= (uint16_t)-1;
5432 SMB_STRUCT_STAT sbuf
;
5433 bool correct
= false;
5436 const char *fname_windows
= "windows_file";
5437 uint16_t fnum2
= (uint16_t)-1;
5439 printf("Starting simple POSIX open test\n");
5441 if (!torture_open_connection(&cli1
, 0)) {
5445 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5447 status
= torture_setup_unix_extensions(cli1
);
5448 if (!NT_STATUS_IS_OK(status
)) {
5452 cli_setatr(cli1
, fname
, 0, 0);
5453 cli_posix_unlink(cli1
, fname
);
5454 cli_setatr(cli1
, dname
, 0, 0);
5455 cli_posix_rmdir(cli1
, dname
);
5456 cli_setatr(cli1
, hname
, 0, 0);
5457 cli_posix_unlink(cli1
, hname
);
5458 cli_setatr(cli1
, sname
, 0, 0);
5459 cli_posix_unlink(cli1
, sname
);
5460 cli_setatr(cli1
, fname_windows
, 0, 0);
5461 cli_posix_unlink(cli1
, fname_windows
);
5463 /* Create a directory. */
5464 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5465 if (!NT_STATUS_IS_OK(status
)) {
5466 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5470 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5472 if (!NT_STATUS_IS_OK(status
)) {
5473 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5477 /* Test ftruncate - set file size. */
5478 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5479 if (!NT_STATUS_IS_OK(status
)) {
5480 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5484 /* Ensure st_size == 1000 */
5485 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5486 if (!NT_STATUS_IS_OK(status
)) {
5487 printf("stat failed (%s)\n", nt_errstr(status
));
5491 if (sbuf
.st_ex_size
!= 1000) {
5492 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5496 /* Ensure st_mode == 0600 */
5497 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
5498 printf("posix_open - bad permissions 0%o != 0600\n",
5499 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5503 /* Test ftruncate - set file size back to zero. */
5504 status
= cli_ftruncate(cli1
, fnum1
, 0);
5505 if (!NT_STATUS_IS_OK(status
)) {
5506 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5510 status
= cli_close(cli1
, fnum1
);
5511 if (!NT_STATUS_IS_OK(status
)) {
5512 printf("close failed (%s)\n", nt_errstr(status
));
5516 /* Now open the file again for read only. */
5517 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5518 if (!NT_STATUS_IS_OK(status
)) {
5519 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5523 /* Now unlink while open. */
5524 status
= cli_posix_unlink(cli1
, fname
);
5525 if (!NT_STATUS_IS_OK(status
)) {
5526 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5530 status
= cli_close(cli1
, fnum1
);
5531 if (!NT_STATUS_IS_OK(status
)) {
5532 printf("close(2) failed (%s)\n", nt_errstr(status
));
5536 /* Ensure the file has gone. */
5537 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5538 if (NT_STATUS_IS_OK(status
)) {
5539 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5543 /* Create again to test open with O_TRUNC. */
5544 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5545 if (!NT_STATUS_IS_OK(status
)) {
5546 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5550 /* Test ftruncate - set file size. */
5551 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5552 if (!NT_STATUS_IS_OK(status
)) {
5553 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5557 /* Ensure st_size == 1000 */
5558 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5559 if (!NT_STATUS_IS_OK(status
)) {
5560 printf("stat failed (%s)\n", nt_errstr(status
));
5564 if (sbuf
.st_ex_size
!= 1000) {
5565 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5569 status
= cli_close(cli1
, fnum1
);
5570 if (!NT_STATUS_IS_OK(status
)) {
5571 printf("close(2) failed (%s)\n", nt_errstr(status
));
5575 /* Re-open with O_TRUNC. */
5576 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5577 if (!NT_STATUS_IS_OK(status
)) {
5578 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5582 /* Ensure st_size == 0 */
5583 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5584 if (!NT_STATUS_IS_OK(status
)) {
5585 printf("stat failed (%s)\n", nt_errstr(status
));
5589 if (sbuf
.st_ex_size
!= 0) {
5590 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5594 status
= cli_close(cli1
, fnum1
);
5595 if (!NT_STATUS_IS_OK(status
)) {
5596 printf("close failed (%s)\n", nt_errstr(status
));
5600 status
= cli_posix_unlink(cli1
, fname
);
5601 if (!NT_STATUS_IS_OK(status
)) {
5602 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5606 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5607 if (!NT_STATUS_IS_OK(status
)) {
5608 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5609 dname
, nt_errstr(status
));
5613 cli_close(cli1
, fnum1
);
5615 /* What happens when we try and POSIX open a directory for write ? */
5616 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5617 if (NT_STATUS_IS_OK(status
)) {
5618 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5621 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5622 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5627 /* Create the file. */
5628 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5630 if (!NT_STATUS_IS_OK(status
)) {
5631 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5635 /* Write some data into it. */
5636 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5638 if (!NT_STATUS_IS_OK(status
)) {
5639 printf("cli_write failed: %s\n", nt_errstr(status
));
5643 cli_close(cli1
, fnum1
);
5645 /* Now create a hardlink. */
5646 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5647 if (!NT_STATUS_IS_OK(status
)) {
5648 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5652 /* Now create a symlink. */
5653 status
= cli_posix_symlink(cli1
, fname
, sname
);
5654 if (!NT_STATUS_IS_OK(status
)) {
5655 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5659 /* Open the hardlink for read. */
5660 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5661 if (!NT_STATUS_IS_OK(status
)) {
5662 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5666 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5667 if (!NT_STATUS_IS_OK(status
)) {
5668 printf("POSIX read of %s failed (%s)\n", hname
,
5671 } else if (nread
!= 10) {
5672 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5673 hname
, (unsigned long)nread
, 10);
5677 if (memcmp(buf
, "TEST DATA\n", 10)) {
5678 printf("invalid data read from hardlink\n");
5682 /* Do a POSIX lock/unlock. */
5683 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5684 if (!NT_STATUS_IS_OK(status
)) {
5685 printf("POSIX lock failed %s\n", nt_errstr(status
));
5689 /* Punch a hole in the locked area. */
5690 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5691 if (!NT_STATUS_IS_OK(status
)) {
5692 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5696 cli_close(cli1
, fnum1
);
5698 /* Open the symlink for read - this should fail. A POSIX
5699 client should not be doing opens on a symlink. */
5700 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5701 if (NT_STATUS_IS_OK(status
)) {
5702 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5705 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5706 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5707 printf("POSIX open of %s should have failed "
5708 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5709 "failed with %s instead.\n",
5710 sname
, nt_errstr(status
));
5715 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5716 if (!NT_STATUS_IS_OK(status
)) {
5717 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5721 if (strcmp(namebuf
, fname
) != 0) {
5722 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5723 sname
, fname
, namebuf
);
5727 status
= cli_posix_rmdir(cli1
, dname
);
5728 if (!NT_STATUS_IS_OK(status
)) {
5729 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5733 /* Check directory opens with a specific permission. */
5734 status
= cli_posix_mkdir(cli1
, dname
, 0700);
5735 if (!NT_STATUS_IS_OK(status
)) {
5736 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5740 /* Ensure st_mode == 0700 */
5741 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
5742 if (!NT_STATUS_IS_OK(status
)) {
5743 printf("stat failed (%s)\n", nt_errstr(status
));
5747 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
5748 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5749 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5754 * Now create a Windows file, and attempt a POSIX unlink.
5755 * This should fail with a sharing violation but due to:
5757 * [Bug 9571] Unlink after open causes smbd to panic
5759 * ensure we've fixed the lock ordering violation.
5762 status
= cli_ntcreate(cli1
, fname_windows
, 0,
5763 FILE_READ_DATA
|FILE_WRITE_DATA
, 0,
5764 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5766 0x0, 0x0, &fnum2
, NULL
);
5767 if (!NT_STATUS_IS_OK(status
)) {
5768 printf("Windows create of %s failed (%s)\n", fname_windows
,
5773 /* Now try posix_unlink. */
5774 status
= cli_posix_unlink(cli1
, fname_windows
);
5775 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
5776 printf("POSIX unlink of %s should fail "
5777 "with NT_STATUS_SHARING_VIOLATION "
5778 "got %s instead !\n",
5784 cli_close(cli1
, fnum2
);
5786 printf("Simple POSIX open test passed\n");
5791 if (fnum1
!= (uint16_t)-1) {
5792 cli_close(cli1
, fnum1
);
5793 fnum1
= (uint16_t)-1;
5796 if (fnum2
!= (uint16_t)-1) {
5797 cli_close(cli1
, fnum2
);
5798 fnum2
= (uint16_t)-1;
5801 cli_setatr(cli1
, sname
, 0, 0);
5802 cli_posix_unlink(cli1
, sname
);
5803 cli_setatr(cli1
, hname
, 0, 0);
5804 cli_posix_unlink(cli1
, hname
);
5805 cli_setatr(cli1
, fname
, 0, 0);
5806 cli_posix_unlink(cli1
, fname
);
5807 cli_setatr(cli1
, dname
, 0, 0);
5808 cli_posix_rmdir(cli1
, dname
);
5809 cli_setatr(cli1
, fname_windows
, 0, 0);
5810 cli_posix_unlink(cli1
, fname_windows
);
5812 if (!torture_close_connection(cli1
)) {
5820 Test POSIX and Windows ACLs are rejected on symlinks.
5822 static bool run_acl_symlink_test(int dummy
)
5824 static struct cli_state
*cli
;
5825 const char *fname
= "posix_file";
5826 const char *sname
= "posix_symlink";
5827 uint16_t fnum
= (uint16_t)-1;
5828 bool correct
= false;
5830 char *posix_acl
= NULL
;
5831 size_t posix_acl_len
= 0;
5832 char *posix_acl_sym
= NULL
;
5833 size_t posix_acl_len_sym
= 0;
5834 struct security_descriptor
*sd
= NULL
;
5835 struct security_descriptor
*sd_sym
= NULL
;
5836 TALLOC_CTX
*frame
= NULL
;
5838 frame
= talloc_stackframe();
5840 printf("Starting acl symlink test\n");
5842 if (!torture_open_connection(&cli
, 0)) {
5847 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5849 status
= torture_setup_unix_extensions(cli
);
5850 if (!NT_STATUS_IS_OK(status
)) {
5855 cli_setatr(cli
, fname
, 0, 0);
5856 cli_posix_unlink(cli
, fname
);
5857 cli_setatr(cli
, sname
, 0, 0);
5858 cli_posix_unlink(cli
, sname
);
5860 status
= cli_ntcreate(cli
,
5863 READ_CONTROL_ACCESS
,
5865 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5872 if (!NT_STATUS_IS_OK(status
)) {
5873 printf("cli_ntcreate of %s failed (%s)\n",
5879 /* Get the Windows ACL on the file. */
5880 status
= cli_query_secdesc(cli
,
5884 if (!NT_STATUS_IS_OK(status
)) {
5885 printf("cli_query_secdesc failed (%s)\n",
5890 /* Get the POSIX ACL on the file. */
5891 status
= cli_posix_getacl(cli
,
5897 if (!NT_STATUS_IS_OK(status
)) {
5898 printf("cli_posix_getacl failed (%s)\n",
5903 status
= cli_close(cli
, fnum
);
5904 if (!NT_STATUS_IS_OK(status
)) {
5905 printf("close failed (%s)\n", nt_errstr(status
));
5908 fnum
= (uint16_t)-1;
5910 /* Now create a symlink. */
5911 status
= cli_posix_symlink(cli
, fname
, sname
);
5912 if (!NT_STATUS_IS_OK(status
)) {
5913 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
5920 /* Open a handle on the symlink. */
5921 status
= cli_ntcreate(cli
,
5924 READ_CONTROL_ACCESS
|SEC_STD_WRITE_DAC
,
5926 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5933 if (!NT_STATUS_IS_OK(status
)) {
5934 printf("cli_posix_open of %s failed (%s)\n",
5940 /* Get the Windows ACL on the symlink handle. Should fail */
5941 status
= cli_query_secdesc(cli
,
5946 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5947 printf("cli_query_secdesc on a symlink gave %s. "
5948 "Should be NT_STATUS_ACCESS_DENIED.\n",
5953 /* Get the POSIX ACL on the symlink pathname. Should fail. */
5954 status
= cli_posix_getacl(cli
,
5960 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5961 printf("cli_posix_getacl on a symlink gave %s. "
5962 "Should be NT_STATUS_ACCESS_DENIED.\n",
5967 /* Set the Windows ACL on the symlink handle. Should fail */
5968 status
= cli_set_security_descriptor(cli
,
5973 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5974 printf("cli_query_secdesc on a symlink gave %s. "
5975 "Should be NT_STATUS_ACCESS_DENIED.\n",
5980 /* Set the POSIX ACL on the symlink pathname. Should fail. */
5981 status
= cli_posix_setacl(cli
,
5986 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5987 printf("cli_posix_getacl on a symlink gave %s. "
5988 "Should be NT_STATUS_ACCESS_DENIED.\n",
5993 printf("ACL symlink test passed\n");
5998 if (fnum
!= (uint16_t)-1) {
5999 cli_close(cli
, fnum
);
6000 fnum
= (uint16_t)-1;
6003 cli_setatr(cli
, sname
, 0, 0);
6004 cli_posix_unlink(cli
, sname
);
6005 cli_setatr(cli
, fname
, 0, 0);
6006 cli_posix_unlink(cli
, fname
);
6008 if (!torture_close_connection(cli
)) {
6017 Test POSIX can delete a file containing streams.
6019 static bool run_posix_stream_delete(int dummy
)
6021 struct cli_state
*cli1
= NULL
;
6022 struct cli_state
*cli2
= NULL
;
6023 const char *fname
= "streamfile";
6024 const char *stream_fname
= "streamfile:Zone.Identifier:$DATA";
6025 uint16_t fnum1
= (uint16_t)-1;
6026 bool correct
= false;
6028 TALLOC_CTX
*frame
= NULL
;
6030 frame
= talloc_stackframe();
6032 printf("Starting POSIX stream delete test\n");
6034 if (!torture_open_connection(&cli1
, 0) ||
6035 !torture_open_connection(&cli2
, 1)) {
6040 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6041 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
6043 status
= torture_setup_unix_extensions(cli2
);
6044 if (!NT_STATUS_IS_OK(status
)) {
6048 cli_setatr(cli1
, fname
, 0, 0);
6049 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6051 /* Create the file. */
6052 status
= cli_ntcreate(cli1
,
6055 READ_CONTROL_ACCESS
,
6057 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6064 if (!NT_STATUS_IS_OK(status
)) {
6065 printf("cli_ntcreate of %s failed (%s)\n",
6071 status
= cli_close(cli1
, fnum1
);
6072 if (!NT_STATUS_IS_OK(status
)) {
6073 printf("cli_close of %s failed (%s)\n",
6078 fnum1
= (uint16_t)-1;
6080 /* Now create the stream. */
6081 status
= cli_ntcreate(cli1
,
6086 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6093 if (!NT_STATUS_IS_OK(status
)) {
6094 printf("cli_ntcreate of %s failed (%s)\n",
6100 /* Leave the stream handle open... */
6102 /* POSIX unlink should fail. */
6103 status
= cli_posix_unlink(cli2
, fname
);
6104 if (NT_STATUS_IS_OK(status
)) {
6105 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6110 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6111 printf("cli_posix_unlink of %s failed with (%s) "
6112 "should have been NT_STATUS_SHARING_VIOLATION\n",
6118 /* Close the stream handle. */
6119 status
= cli_close(cli1
, fnum1
);
6120 if (!NT_STATUS_IS_OK(status
)) {
6121 printf("cli_close of %s failed (%s)\n",
6126 fnum1
= (uint16_t)-1;
6128 /* POSIX unlink after stream handle closed should succeed. */
6129 status
= cli_posix_unlink(cli2
, fname
);
6130 if (!NT_STATUS_IS_OK(status
)) {
6131 printf("cli_posix_unlink of %s failed (%s)\n",
6137 printf("POSIX stream delete test passed\n");
6142 if (fnum1
!= (uint16_t)-1) {
6143 cli_close(cli1
, fnum1
);
6144 fnum1
= (uint16_t)-1;
6147 cli_setatr(cli1
, fname
, 0, 0);
6148 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6150 if (!torture_close_connection(cli1
)) {
6153 if (!torture_close_connection(cli2
)) {
6162 Test setting EA's are rejected on symlinks.
6164 static bool run_ea_symlink_test(int dummy
)
6166 static struct cli_state
*cli
;
6167 const char *fname
= "posix_file_ea";
6168 const char *sname
= "posix_symlink_ea";
6169 const char *ea_name
= "testea_name";
6170 const char *ea_value
= "testea_value";
6171 uint16_t fnum
= (uint16_t)-1;
6172 bool correct
= false;
6175 struct ea_struct
*eas
= NULL
;
6176 TALLOC_CTX
*frame
= NULL
;
6178 frame
= talloc_stackframe();
6180 printf("Starting EA symlink test\n");
6182 if (!torture_open_connection(&cli
, 0)) {
6187 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6189 status
= torture_setup_unix_extensions(cli
);
6190 if (!NT_STATUS_IS_OK(status
)) {
6195 cli_setatr(cli
, fname
, 0, 0);
6196 cli_posix_unlink(cli
, fname
);
6197 cli_setatr(cli
, sname
, 0, 0);
6198 cli_posix_unlink(cli
, sname
);
6200 status
= cli_ntcreate(cli
,
6203 READ_CONTROL_ACCESS
,
6205 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6212 if (!NT_STATUS_IS_OK(status
)) {
6213 printf("cli_ntcreate of %s failed (%s)\n",
6219 status
= cli_close(cli
, fnum
);
6220 if (!NT_STATUS_IS_OK(status
)) {
6221 printf("close failed (%s)\n",
6225 fnum
= (uint16_t)-1;
6227 /* Set an EA on the path. */
6228 status
= cli_set_ea_path(cli
,
6232 strlen(ea_value
)+1);
6234 if (!NT_STATUS_IS_OK(status
)) {
6235 printf("cli_set_ea_path failed (%s)\n",
6240 /* Now create a symlink. */
6241 status
= cli_posix_symlink(cli
, fname
, sname
);
6242 if (!NT_STATUS_IS_OK(status
)) {
6243 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6250 /* Get the EA list on the path. Should return value set. */
6251 status
= cli_get_ea_list_path(cli
,
6257 if (!NT_STATUS_IS_OK(status
)) {
6258 printf("cli_get_ea_list_path failed (%s)\n",
6263 /* Ensure the EA we set is there. */
6264 for (i
=0; i
<num_eas
; i
++) {
6265 if (strcmp(eas
[i
].name
, ea_name
) == 0 &&
6266 eas
[i
].value
.length
== strlen(ea_value
)+1 &&
6267 memcmp(eas
[i
].value
.data
,
6269 eas
[i
].value
.length
) == 0) {
6275 printf("Didn't find EA on pathname %s\n",
6283 /* Get the EA list on the symlink. Should return empty list. */
6284 status
= cli_get_ea_list_path(cli
,
6290 if (!NT_STATUS_IS_OK(status
)) {
6291 printf("cli_get_ea_list_path failed (%s)\n",
6297 printf("cli_get_ea_list_path failed (%s)\n",
6302 /* Set an EA on the symlink. Should fail. */
6303 status
= cli_set_ea_path(cli
,
6307 strlen(ea_value
)+1);
6309 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6310 printf("cli_set_ea_path on a symlink gave %s. "
6311 "Should be NT_STATUS_ACCESS_DENIED.\n",
6316 printf("EA symlink test passed\n");
6321 if (fnum
!= (uint16_t)-1) {
6322 cli_close(cli
, fnum
);
6323 fnum
= (uint16_t)-1;
6326 cli_setatr(cli
, sname
, 0, 0);
6327 cli_posix_unlink(cli
, sname
);
6328 cli_setatr(cli
, fname
, 0, 0);
6329 cli_posix_unlink(cli
, fname
);
6331 if (!torture_close_connection(cli
)) {
6340 Test POSIX locks are OFD-locks.
6342 static bool run_posix_ofd_lock_test(int dummy
)
6344 static struct cli_state
*cli
;
6345 const char *fname
= "posix_file";
6346 uint16_t fnum1
= (uint16_t)-1;
6347 uint16_t fnum2
= (uint16_t)-1;
6348 bool correct
= false;
6350 TALLOC_CTX
*frame
= NULL
;
6352 frame
= talloc_stackframe();
6354 printf("Starting POSIX ofd-lock test\n");
6356 if (!torture_open_connection(&cli
, 0)) {
6361 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6363 status
= torture_setup_unix_extensions(cli
);
6364 if (!NT_STATUS_IS_OK(status
)) {
6369 cli_setatr(cli
, fname
, 0, 0);
6370 cli_posix_unlink(cli
, fname
);
6372 /* Open the file twice. */
6373 status
= cli_posix_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6375 if (!NT_STATUS_IS_OK(status
)) {
6376 printf("First POSIX open of %s failed\n", fname
);
6380 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum2
);
6381 if (!NT_STATUS_IS_OK(status
)) {
6382 printf("First POSIX open of %s failed\n", fname
);
6386 /* Set a 0-50 lock on fnum1. */
6387 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
6388 if (!NT_STATUS_IS_OK(status
)) {
6389 printf("POSIX lock (1) failed %s\n", nt_errstr(status
));
6393 /* Set a 60-100 lock on fnum2. */
6394 status
= cli_posix_lock(cli
, fnum2
, 60, 100, false, WRITE_LOCK
);
6395 if (!NT_STATUS_IS_OK(status
)) {
6396 printf("POSIX lock (2) failed %s\n", nt_errstr(status
));
6400 /* close fnum1 - 0-50 lock should go away. */
6401 status
= cli_close(cli
, fnum1
);
6402 if (!NT_STATUS_IS_OK(status
)) {
6403 printf("close failed (%s)\n",
6407 fnum1
= (uint16_t)-1;
6409 /* Change the lock context. */
6410 cli_setpid(cli
, cli_getpid(cli
) + 1);
6412 /* Re-open fnum1. */
6413 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum1
);
6414 if (!NT_STATUS_IS_OK(status
)) {
6415 printf("Third POSIX open of %s failed\n", fname
);
6419 /* 60-100 lock should still be there. */
6420 status
= cli_posix_lock(cli
, fnum1
, 60, 100, false, WRITE_LOCK
);
6421 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
6422 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status
));
6426 /* 0-50 lock should be gone. */
6427 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
6428 if (!NT_STATUS_IS_OK(status
)) {
6429 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status
));
6433 printf("POSIX OFD lock test passed\n");
6438 if (fnum1
!= (uint16_t)-1) {
6439 cli_close(cli
, fnum1
);
6440 fnum1
= (uint16_t)-1;
6442 if (fnum2
!= (uint16_t)-1) {
6443 cli_close(cli
, fnum2
);
6444 fnum2
= (uint16_t)-1;
6447 cli_setatr(cli
, fname
, 0, 0);
6448 cli_posix_unlink(cli
, fname
);
6450 if (!torture_close_connection(cli
)) {
6458 static uint32_t open_attrs_table
[] = {
6459 FILE_ATTRIBUTE_NORMAL
,
6460 FILE_ATTRIBUTE_ARCHIVE
,
6461 FILE_ATTRIBUTE_READONLY
,
6462 FILE_ATTRIBUTE_HIDDEN
,
6463 FILE_ATTRIBUTE_SYSTEM
,
6465 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
6466 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
6467 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
6468 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
6469 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
6470 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
6472 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
6473 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
6474 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
6475 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
6478 struct trunc_open_results
{
6481 uint32_t trunc_attr
;
6482 uint32_t result_attr
;
6485 static struct trunc_open_results attr_results
[] = {
6486 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
6487 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
6488 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
6489 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
6490 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
6491 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
6492 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6493 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6494 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
6495 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6496 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6497 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
6498 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6499 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6500 { 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
},
6501 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6502 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6503 { 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
},
6504 { 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
},
6505 { 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
},
6506 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6507 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
6508 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
6509 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6510 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
6511 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
6514 static bool run_openattrtest(int dummy
)
6516 static struct cli_state
*cli1
;
6517 const char *fname
= "\\openattr.file";
6519 bool correct
= True
;
6521 unsigned int i
, j
, k
, l
;
6524 printf("starting open attr test\n");
6526 if (!torture_open_connection(&cli1
, 0)) {
6530 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6532 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32_t); i
++) {
6533 cli_setatr(cli1
, fname
, 0, 0);
6534 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6536 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
6537 open_attrs_table
[i
], FILE_SHARE_NONE
,
6538 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6539 if (!NT_STATUS_IS_OK(status
)) {
6540 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
6544 status
= cli_close(cli1
, fnum1
);
6545 if (!NT_STATUS_IS_OK(status
)) {
6546 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
6550 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32_t); j
++) {
6551 status
= cli_ntcreate(cli1
, fname
, 0,
6552 FILE_READ_DATA
|FILE_WRITE_DATA
,
6553 open_attrs_table
[j
],
6554 FILE_SHARE_NONE
, FILE_OVERWRITE
,
6555 0, 0, &fnum1
, NULL
);
6556 if (!NT_STATUS_IS_OK(status
)) {
6557 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
6558 if (attr_results
[l
].num
== k
) {
6559 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
6560 k
, open_attrs_table
[i
],
6561 open_attrs_table
[j
],
6562 fname
, NT_STATUS_V(status
), nt_errstr(status
));
6567 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6568 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
6569 k
, open_attrs_table
[i
], open_attrs_table
[j
],
6574 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
6580 status
= cli_close(cli1
, fnum1
);
6581 if (!NT_STATUS_IS_OK(status
)) {
6582 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
6586 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
6587 if (!NT_STATUS_IS_OK(status
)) {
6588 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
6593 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
6594 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
6597 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
6598 if (attr_results
[l
].num
== k
) {
6599 if (attr
!= attr_results
[l
].result_attr
||
6600 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
6601 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
6602 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
6603 open_attrs_table
[i
],
6604 open_attrs_table
[j
],
6606 attr_results
[l
].result_attr
);
6616 cli_setatr(cli1
, fname
, 0, 0);
6617 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6619 printf("open attr test %s.\n", correct
? "passed" : "failed");
6621 if (!torture_close_connection(cli1
)) {
6627 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
6628 const char *name
, void *state
)
6630 int *matched
= (int *)state
;
6631 if (matched
!= NULL
) {
6634 return NT_STATUS_OK
;
6638 test directory listing speed
6640 static bool run_dirtest(int dummy
)
6643 static struct cli_state
*cli
;
6645 struct timeval core_start
;
6646 bool correct
= True
;
6649 printf("starting directory test\n");
6651 if (!torture_open_connection(&cli
, 0)) {
6655 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6658 for (i
=0;i
<torture_numops
;i
++) {
6660 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
6661 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
6662 fprintf(stderr
,"Failed to open %s\n", fname
);
6665 cli_close(cli
, fnum
);
6668 core_start
= timeval_current();
6671 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
6672 printf("Matched %d\n", matched
);
6675 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
6676 printf("Matched %d\n", matched
);
6679 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
6680 printf("Matched %d\n", matched
);
6682 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
6685 for (i
=0;i
<torture_numops
;i
++) {
6687 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
6688 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6691 if (!torture_close_connection(cli
)) {
6695 printf("finished dirtest\n");
6700 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
6703 struct cli_state
*pcli
= (struct cli_state
*)state
;
6705 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
6707 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6708 return NT_STATUS_OK
;
6710 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
6711 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
6712 printf("del_fn: failed to rmdir %s\n,", fname
);
6714 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
6715 printf("del_fn: failed to unlink %s\n,", fname
);
6717 return NT_STATUS_OK
;
6722 sees what IOCTLs are supported
6724 bool torture_ioctl_test(int dummy
)
6726 static struct cli_state
*cli
;
6727 uint16_t device
, function
;
6729 const char *fname
= "\\ioctl.dat";
6733 if (!torture_open_connection(&cli
, 0)) {
6737 printf("starting ioctl test\n");
6739 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6741 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6742 if (!NT_STATUS_IS_OK(status
)) {
6743 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
6747 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
6748 printf("ioctl device info: %s\n", nt_errstr(status
));
6750 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
6751 printf("ioctl job info: %s\n", nt_errstr(status
));
6753 for (device
=0;device
<0x100;device
++) {
6754 printf("ioctl test with device = 0x%x\n", device
);
6755 for (function
=0;function
<0x100;function
++) {
6756 uint32_t code
= (device
<<16) | function
;
6758 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
6760 if (NT_STATUS_IS_OK(status
)) {
6761 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
6763 data_blob_free(&blob
);
6768 if (!torture_close_connection(cli
)) {
6777 tries varients of chkpath
6779 bool torture_chkpath_test(int dummy
)
6781 static struct cli_state
*cli
;
6786 if (!torture_open_connection(&cli
, 0)) {
6790 printf("starting chkpath test\n");
6792 /* cleanup from an old run */
6793 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6794 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6795 cli_rmdir(cli
, "\\chkpath.dir");
6797 status
= cli_mkdir(cli
, "\\chkpath.dir");
6798 if (!NT_STATUS_IS_OK(status
)) {
6799 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6803 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6804 if (!NT_STATUS_IS_OK(status
)) {
6805 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6809 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6811 if (!NT_STATUS_IS_OK(status
)) {
6812 printf("open1 failed (%s)\n", nt_errstr(status
));
6815 cli_close(cli
, fnum
);
6817 status
= cli_chkpath(cli
, "\\chkpath.dir");
6818 if (!NT_STATUS_IS_OK(status
)) {
6819 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6823 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6824 if (!NT_STATUS_IS_OK(status
)) {
6825 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6829 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6830 if (!NT_STATUS_IS_OK(status
)) {
6831 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6832 NT_STATUS_NOT_A_DIRECTORY
);
6834 printf("* chkpath on a file should fail\n");
6838 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6839 if (!NT_STATUS_IS_OK(status
)) {
6840 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6841 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6843 printf("* chkpath on a non existent file should fail\n");
6847 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6848 if (!NT_STATUS_IS_OK(status
)) {
6849 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6850 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6852 printf("* chkpath on a non existent component should fail\n");
6856 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6857 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6858 cli_rmdir(cli
, "\\chkpath.dir");
6860 if (!torture_close_connection(cli
)) {
6867 static bool run_eatest(int dummy
)
6869 static struct cli_state
*cli
;
6870 const char *fname
= "\\eatest.txt";
6871 bool correct
= True
;
6875 struct ea_struct
*ea_list
= NULL
;
6876 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6879 printf("starting eatest\n");
6881 if (!torture_open_connection(&cli
, 0)) {
6882 talloc_destroy(mem_ctx
);
6886 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6888 status
= cli_ntcreate(cli
, fname
, 0,
6889 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6890 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6891 0x4044, 0, &fnum
, NULL
);
6892 if (!NT_STATUS_IS_OK(status
)) {
6893 printf("open failed - %s\n", nt_errstr(status
));
6894 talloc_destroy(mem_ctx
);
6898 for (i
= 0; i
< 10; i
++) {
6899 fstring ea_name
, ea_val
;
6901 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6902 memset(ea_val
, (char)i
+1, i
+1);
6903 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6904 if (!NT_STATUS_IS_OK(status
)) {
6905 printf("ea_set of name %s failed - %s\n", ea_name
,
6907 talloc_destroy(mem_ctx
);
6912 cli_close(cli
, fnum
);
6913 for (i
= 0; i
< 10; i
++) {
6914 fstring ea_name
, ea_val
;
6916 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6917 memset(ea_val
, (char)i
+1, i
+1);
6918 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6919 if (!NT_STATUS_IS_OK(status
)) {
6920 printf("ea_set of name %s failed - %s\n", ea_name
,
6922 talloc_destroy(mem_ctx
);
6927 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6928 if (!NT_STATUS_IS_OK(status
)) {
6929 printf("ea_get list failed - %s\n", nt_errstr(status
));
6933 printf("num_eas = %d\n", (int)num_eas
);
6935 if (num_eas
!= 20) {
6936 printf("Should be 20 EA's stored... failing.\n");
6940 for (i
= 0; i
< num_eas
; i
++) {
6941 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6942 dump_data(0, ea_list
[i
].value
.data
,
6943 ea_list
[i
].value
.length
);
6946 /* Setting EA's to zero length deletes them. Test this */
6947 printf("Now deleting all EA's - case indepenent....\n");
6950 cli_set_ea_path(cli
, fname
, "", "", 0);
6952 for (i
= 0; i
< 20; i
++) {
6954 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6955 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6956 if (!NT_STATUS_IS_OK(status
)) {
6957 printf("ea_set of name %s failed - %s\n", ea_name
,
6959 talloc_destroy(mem_ctx
);
6965 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6966 if (!NT_STATUS_IS_OK(status
)) {
6967 printf("ea_get list failed - %s\n", nt_errstr(status
));
6971 printf("num_eas = %d\n", (int)num_eas
);
6972 for (i
= 0; i
< num_eas
; i
++) {
6973 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6974 dump_data(0, ea_list
[i
].value
.data
,
6975 ea_list
[i
].value
.length
);
6979 printf("deleting EA's failed.\n");
6983 /* Try and delete a non existent EA. */
6984 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6985 if (!NT_STATUS_IS_OK(status
)) {
6986 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6991 talloc_destroy(mem_ctx
);
6992 if (!torture_close_connection(cli
)) {
6999 static bool run_dirtest1(int dummy
)
7002 static struct cli_state
*cli
;
7005 bool correct
= True
;
7007 printf("starting directory test\n");
7009 if (!torture_open_connection(&cli
, 0)) {
7013 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7015 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7016 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7017 cli_rmdir(cli
, "\\LISTDIR");
7018 cli_mkdir(cli
, "\\LISTDIR");
7020 /* Create 1000 files and 1000 directories. */
7021 for (i
=0;i
<1000;i
++) {
7023 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
7024 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
7025 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
7026 0, 0, &fnum
, NULL
))) {
7027 fprintf(stderr
,"Failed to open %s\n", fname
);
7030 cli_close(cli
, fnum
);
7032 for (i
=0;i
<1000;i
++) {
7034 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
7035 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
7036 fprintf(stderr
,"Failed to open %s\n", fname
);
7041 /* Now ensure that doing an old list sees both files and directories. */
7043 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7044 printf("num_seen = %d\n", num_seen
);
7045 /* We should see 100 files + 1000 directories + . and .. */
7046 if (num_seen
!= 2002)
7049 /* Ensure if we have the "must have" bits we only see the
7053 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7054 printf("num_seen = %d\n", num_seen
);
7055 if (num_seen
!= 1002)
7059 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7060 printf("num_seen = %d\n", num_seen
);
7061 if (num_seen
!= 1000)
7064 /* Delete everything. */
7065 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7066 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7067 cli_rmdir(cli
, "\\LISTDIR");
7070 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
7071 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
7072 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
7075 if (!torture_close_connection(cli
)) {
7079 printf("finished dirtest1\n");
7084 static bool run_error_map_extract(int dummy
) {
7086 static struct cli_state
*c_dos
;
7087 static struct cli_state
*c_nt
;
7099 /* NT-Error connection */
7101 disable_spnego
= true;
7102 if (!(c_nt
= open_nbt_connection())) {
7103 disable_spnego
= false;
7106 disable_spnego
= false;
7108 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
7111 if (!NT_STATUS_IS_OK(status
)) {
7112 printf("%s rejected the NT-error negprot (%s)\n", host
,
7118 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
7119 if (!NT_STATUS_IS_OK(status
)) {
7120 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
7124 /* DOS-Error connection */
7126 disable_spnego
= true;
7127 force_dos_errors
= true;
7128 if (!(c_dos
= open_nbt_connection())) {
7129 disable_spnego
= false;
7130 force_dos_errors
= false;
7133 disable_spnego
= false;
7134 force_dos_errors
= false;
7136 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
7138 if (!NT_STATUS_IS_OK(status
)) {
7139 printf("%s rejected the DOS-error negprot (%s)\n", host
,
7141 cli_shutdown(c_dos
);
7145 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
7146 if (!NT_STATUS_IS_OK(status
)) {
7147 printf("%s rejected the DOS-error initial session setup (%s)\n",
7148 host
, nt_errstr(status
));
7152 c_nt
->map_dos_errors
= false;
7153 c_dos
->map_dos_errors
= false;
7155 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
7156 fstr_sprintf(user
, "%X", error
);
7158 status
= cli_session_setup(c_nt
, user
,
7159 password
, strlen(password
),
7160 password
, strlen(password
),
7162 if (NT_STATUS_IS_OK(status
)) {
7163 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7166 /* Case #1: 32-bit NT errors */
7167 if (!NT_STATUS_IS_DOS(status
)) {
7170 printf("/** Dos error on NT connection! (%s) */\n",
7172 nt_status
= NT_STATUS(0xc0000000);
7175 status
= cli_session_setup(c_dos
, user
,
7176 password
, strlen(password
),
7177 password
, strlen(password
),
7179 if (NT_STATUS_IS_OK(status
)) {
7180 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7183 /* Case #1: 32-bit NT errors */
7184 if (NT_STATUS_IS_DOS(status
)) {
7185 printf("/** NT error on DOS connection! (%s) */\n",
7187 errnum
= errclass
= 0;
7189 errclass
= NT_STATUS_DOS_CLASS(status
);
7190 errnum
= NT_STATUS_DOS_CODE(status
);
7193 if (NT_STATUS_V(nt_status
) != error
) {
7194 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7195 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
7196 get_nt_error_c_code(talloc_tos(), nt_status
));
7199 printf("\t{%s,\t%s,\t%s},\n",
7200 smb_dos_err_class(errclass
),
7201 smb_dos_err_name(errclass
, errnum
),
7202 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
7207 static bool run_sesssetup_bench(int dummy
)
7209 static struct cli_state
*c
;
7210 const char *fname
= "\\file.dat";
7215 if (!torture_open_connection(&c
, 0)) {
7219 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7220 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7221 FILE_DELETE_ON_CLOSE
, 0, &fnum
, NULL
);
7222 if (!NT_STATUS_IS_OK(status
)) {
7223 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7227 for (i
=0; i
<torture_numops
; i
++) {
7228 status
= cli_session_setup(
7230 password
, strlen(password
),
7231 password
, strlen(password
),
7233 if (!NT_STATUS_IS_OK(status
)) {
7234 d_printf("(%s) cli_session_setup failed: %s\n",
7235 __location__
, nt_errstr(status
));
7239 d_printf("\r%d ", (int)cli_state_get_uid(c
));
7241 status
= cli_ulogoff(c
);
7242 if (!NT_STATUS_IS_OK(status
)) {
7243 d_printf("(%s) cli_ulogoff failed: %s\n",
7244 __location__
, nt_errstr(status
));
7252 static bool subst_test(const char *str
, const char *user
, const char *domain
,
7253 uid_t uid
, gid_t gid
, const char *expected
)
7258 subst
= talloc_sub_specified(talloc_tos(), str
, user
, NULL
, domain
, uid
, gid
);
7260 if (strcmp(subst
, expected
) != 0) {
7261 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7262 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
7271 static void chain1_open_completion(struct tevent_req
*req
)
7275 status
= cli_openx_recv(req
, &fnum
);
7278 d_printf("cli_openx_recv returned %s: %d\n",
7280 NT_STATUS_IS_OK(status
) ? fnum
: -1);
7283 static void chain1_write_completion(struct tevent_req
*req
)
7287 status
= cli_write_andx_recv(req
, &written
);
7290 d_printf("cli_write_andx_recv returned %s: %d\n",
7292 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
7295 static void chain1_close_completion(struct tevent_req
*req
)
7298 bool *done
= (bool *)tevent_req_callback_data_void(req
);
7300 status
= cli_close_recv(req
);
7305 d_printf("cli_close returned %s\n", nt_errstr(status
));
7308 static bool run_chain1(int dummy
)
7310 struct cli_state
*cli1
;
7311 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
7312 struct tevent_req
*reqs
[3], *smbreqs
[3];
7314 const char *str
= "foobar";
7317 printf("starting chain1 test\n");
7318 if (!torture_open_connection(&cli1
, 0)) {
7322 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7324 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, "\\test",
7325 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
7326 if (reqs
[0] == NULL
) return false;
7327 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
7330 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
7331 (const uint8_t *)str
, 0, strlen(str
)+1,
7332 smbreqs
, 1, &smbreqs
[1]);
7333 if (reqs
[1] == NULL
) return false;
7334 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
7336 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
7337 if (reqs
[2] == NULL
) return false;
7338 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
7340 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
7341 if (!NT_STATUS_IS_OK(status
)) {
7346 tevent_loop_once(evt
);
7349 torture_close_connection(cli1
);
7353 static void chain2_sesssetup_completion(struct tevent_req
*req
)
7356 status
= cli_session_setup_guest_recv(req
);
7357 d_printf("sesssetup returned %s\n", nt_errstr(status
));
7360 static void chain2_tcon_completion(struct tevent_req
*req
)
7362 bool *done
= (bool *)tevent_req_callback_data_void(req
);
7364 status
= cli_tcon_andx_recv(req
);
7365 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
7369 static bool run_chain2(int dummy
)
7371 struct cli_state
*cli1
;
7372 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
7373 struct tevent_req
*reqs
[2], *smbreqs
[2];
7377 printf("starting chain2 test\n");
7378 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
7379 port_to_use
, SMB_SIGNING_DEFAULT
, 0);
7380 if (!NT_STATUS_IS_OK(status
)) {
7384 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7386 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
7388 if (reqs
[0] == NULL
) return false;
7389 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
7391 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
7392 "?????", NULL
, 0, &smbreqs
[1]);
7393 if (reqs
[1] == NULL
) return false;
7394 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
7396 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
7397 if (!NT_STATUS_IS_OK(status
)) {
7402 tevent_loop_once(evt
);
7405 torture_close_connection(cli1
);
7410 struct torture_createdel_state
{
7411 struct tevent_context
*ev
;
7412 struct cli_state
*cli
;
7415 static void torture_createdel_created(struct tevent_req
*subreq
);
7416 static void torture_createdel_closed(struct tevent_req
*subreq
);
7418 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
7419 struct tevent_context
*ev
,
7420 struct cli_state
*cli
,
7423 struct tevent_req
*req
, *subreq
;
7424 struct torture_createdel_state
*state
;
7426 req
= tevent_req_create(mem_ctx
, &state
,
7427 struct torture_createdel_state
);
7434 subreq
= cli_ntcreate_send(
7435 state
, ev
, cli
, name
, 0,
7436 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
7437 FILE_ATTRIBUTE_NORMAL
,
7438 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
7439 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
7441 if (tevent_req_nomem(subreq
, req
)) {
7442 return tevent_req_post(req
, ev
);
7444 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
7448 static void torture_createdel_created(struct tevent_req
*subreq
)
7450 struct tevent_req
*req
= tevent_req_callback_data(
7451 subreq
, struct tevent_req
);
7452 struct torture_createdel_state
*state
= tevent_req_data(
7453 req
, struct torture_createdel_state
);
7457 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
7458 TALLOC_FREE(subreq
);
7459 if (tevent_req_nterror(req
, status
)) {
7460 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
7461 nt_errstr(status
)));
7465 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
7466 if (tevent_req_nomem(subreq
, req
)) {
7469 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
7472 static void torture_createdel_closed(struct tevent_req
*subreq
)
7474 struct tevent_req
*req
= tevent_req_callback_data(
7475 subreq
, struct tevent_req
);
7478 status
= cli_close_recv(subreq
);
7479 if (tevent_req_nterror(req
, status
)) {
7480 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
7483 tevent_req_done(req
);
7486 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
7488 return tevent_req_simple_recv_ntstatus(req
);
7491 struct torture_createdels_state
{
7492 struct tevent_context
*ev
;
7493 struct cli_state
*cli
;
7494 const char *base_name
;
7498 struct tevent_req
**reqs
;
7501 static void torture_createdels_done(struct tevent_req
*subreq
);
7503 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
7504 struct tevent_context
*ev
,
7505 struct cli_state
*cli
,
7506 const char *base_name
,
7510 struct tevent_req
*req
;
7511 struct torture_createdels_state
*state
;
7514 req
= tevent_req_create(mem_ctx
, &state
,
7515 struct torture_createdels_state
);
7521 state
->base_name
= talloc_strdup(state
, base_name
);
7522 if (tevent_req_nomem(state
->base_name
, req
)) {
7523 return tevent_req_post(req
, ev
);
7525 state
->num_files
= MAX(num_parallel
, num_files
);
7527 state
->received
= 0;
7529 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
7530 if (tevent_req_nomem(state
->reqs
, req
)) {
7531 return tevent_req_post(req
, ev
);
7534 for (i
=0; i
<num_parallel
; i
++) {
7537 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
7539 if (tevent_req_nomem(name
, req
)) {
7540 return tevent_req_post(req
, ev
);
7542 state
->reqs
[i
] = torture_createdel_send(
7543 state
->reqs
, state
->ev
, state
->cli
, name
);
7544 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
7545 return tevent_req_post(req
, ev
);
7547 name
= talloc_move(state
->reqs
[i
], &name
);
7548 tevent_req_set_callback(state
->reqs
[i
],
7549 torture_createdels_done
, req
);
7555 static void torture_createdels_done(struct tevent_req
*subreq
)
7557 struct tevent_req
*req
= tevent_req_callback_data(
7558 subreq
, struct tevent_req
);
7559 struct torture_createdels_state
*state
= tevent_req_data(
7560 req
, struct torture_createdels_state
);
7561 size_t num_parallel
= talloc_array_length(state
->reqs
);
7566 status
= torture_createdel_recv(subreq
);
7567 if (!NT_STATUS_IS_OK(status
)){
7568 DEBUG(10, ("torture_createdel_recv returned %s\n",
7569 nt_errstr(status
)));
7570 TALLOC_FREE(subreq
);
7571 tevent_req_nterror(req
, status
);
7575 for (i
=0; i
<num_parallel
; i
++) {
7576 if (subreq
== state
->reqs
[i
]) {
7580 if (i
== num_parallel
) {
7581 DEBUG(10, ("received something we did not send\n"));
7582 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
7585 TALLOC_FREE(state
->reqs
[i
]);
7587 if (state
->sent
>= state
->num_files
) {
7588 tevent_req_done(req
);
7592 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
7594 if (tevent_req_nomem(name
, req
)) {
7597 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
7599 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
7602 name
= talloc_move(state
->reqs
[i
], &name
);
7603 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
7607 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
7609 return tevent_req_simple_recv_ntstatus(req
);
7612 struct swallow_notify_state
{
7613 struct tevent_context
*ev
;
7614 struct cli_state
*cli
;
7616 uint32_t completion_filter
;
7618 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
7622 static void swallow_notify_done(struct tevent_req
*subreq
);
7624 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
7625 struct tevent_context
*ev
,
7626 struct cli_state
*cli
,
7628 uint32_t completion_filter
,
7630 bool (*fn
)(uint32_t action
,
7635 struct tevent_req
*req
, *subreq
;
7636 struct swallow_notify_state
*state
;
7638 req
= tevent_req_create(mem_ctx
, &state
,
7639 struct swallow_notify_state
);
7646 state
->completion_filter
= completion_filter
;
7647 state
->recursive
= recursive
;
7651 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
7652 0xffff, state
->completion_filter
,
7654 if (tevent_req_nomem(subreq
, req
)) {
7655 return tevent_req_post(req
, ev
);
7657 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
7661 static void swallow_notify_done(struct tevent_req
*subreq
)
7663 struct tevent_req
*req
= tevent_req_callback_data(
7664 subreq
, struct tevent_req
);
7665 struct swallow_notify_state
*state
= tevent_req_data(
7666 req
, struct swallow_notify_state
);
7668 uint32_t i
, num_changes
;
7669 struct notify_change
*changes
;
7671 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
7672 TALLOC_FREE(subreq
);
7673 if (!NT_STATUS_IS_OK(status
)) {
7674 DEBUG(10, ("cli_notify_recv returned %s\n",
7675 nt_errstr(status
)));
7676 tevent_req_nterror(req
, status
);
7680 for (i
=0; i
<num_changes
; i
++) {
7681 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
7683 TALLOC_FREE(changes
);
7685 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
7686 0xffff, state
->completion_filter
,
7688 if (tevent_req_nomem(subreq
, req
)) {
7691 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
7694 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
7696 if (DEBUGLEVEL
> 5) {
7697 d_printf("%d %s\n", (int)action
, name
);
7702 static void notify_bench_done(struct tevent_req
*req
)
7704 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
7708 static bool run_notify_bench(int dummy
)
7710 const char *dname
= "\\notify-bench";
7711 struct tevent_context
*ev
;
7714 struct tevent_req
*req1
;
7715 struct tevent_req
*req2
= NULL
;
7716 int i
, num_unc_names
;
7717 int num_finished
= 0;
7719 printf("starting notify-bench test\n");
7721 if (use_multishare_conn
) {
7723 unc_list
= file_lines_load(multishare_conn_fname
,
7724 &num_unc_names
, 0, NULL
);
7725 if (!unc_list
|| num_unc_names
<= 0) {
7726 d_printf("Failed to load unc names list from '%s'\n",
7727 multishare_conn_fname
);
7730 TALLOC_FREE(unc_list
);
7735 ev
= samba_tevent_context_init(talloc_tos());
7737 d_printf("tevent_context_init failed\n");
7741 for (i
=0; i
<num_unc_names
; i
++) {
7742 struct cli_state
*cli
;
7745 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
7747 if (base_fname
== NULL
) {
7751 if (!torture_open_connection(&cli
, i
)) {
7755 status
= cli_ntcreate(cli
, dname
, 0,
7756 MAXIMUM_ALLOWED_ACCESS
,
7757 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7759 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
7762 if (!NT_STATUS_IS_OK(status
)) {
7763 d_printf("Could not create %s: %s\n", dname
,
7768 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
7769 FILE_NOTIFY_CHANGE_FILE_NAME
|
7770 FILE_NOTIFY_CHANGE_DIR_NAME
|
7771 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
7772 FILE_NOTIFY_CHANGE_LAST_WRITE
,
7773 false, print_notifies
, NULL
);
7775 d_printf("Could not create notify request\n");
7779 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
7780 base_fname
, 10, torture_numops
);
7782 d_printf("Could not create createdels request\n");
7785 TALLOC_FREE(base_fname
);
7787 tevent_req_set_callback(req2
, notify_bench_done
,
7791 while (num_finished
< num_unc_names
) {
7793 ret
= tevent_loop_once(ev
);
7795 d_printf("tevent_loop_once failed\n");
7800 if (!tevent_req_poll(req2
, ev
)) {
7801 d_printf("tevent_req_poll failed\n");
7804 status
= torture_createdels_recv(req2
);
7805 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7810 static bool run_mangle1(int dummy
)
7812 struct cli_state
*cli
;
7813 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7817 time_t change_time
, access_time
, write_time
;
7821 printf("starting mangle1 test\n");
7822 if (!torture_open_connection(&cli
, 0)) {
7826 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7828 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7829 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7831 if (!NT_STATUS_IS_OK(status
)) {
7832 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7835 cli_close(cli
, fnum
);
7837 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7838 if (!NT_STATUS_IS_OK(status
)) {
7839 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7843 d_printf("alt_name: %s\n", alt_name
);
7845 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7846 if (!NT_STATUS_IS_OK(status
)) {
7847 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
7851 cli_close(cli
, fnum
);
7853 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7854 &write_time
, &size
, &mode
);
7855 if (!NT_STATUS_IS_OK(status
)) {
7856 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7864 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7866 size_t *to_pull
= (size_t *)priv
;
7867 size_t thistime
= *to_pull
;
7869 thistime
= MIN(thistime
, n
);
7870 if (thistime
== 0) {
7874 memset(buf
, 0, thistime
);
7875 *to_pull
-= thistime
;
7879 static bool run_windows_write(int dummy
)
7881 struct cli_state
*cli1
;
7885 const char *fname
= "\\writetest.txt";
7886 struct timeval start_time
;
7891 printf("starting windows_write test\n");
7892 if (!torture_open_connection(&cli1
, 0)) {
7896 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7897 if (!NT_STATUS_IS_OK(status
)) {
7898 printf("open failed (%s)\n", nt_errstr(status
));
7902 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7904 start_time
= timeval_current();
7906 for (i
=0; i
<torture_numops
; i
++) {
7908 off_t start
= i
* torture_blocksize
;
7909 size_t to_pull
= torture_blocksize
- 1;
7911 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7912 start
+ torture_blocksize
- 1, 1, NULL
);
7913 if (!NT_STATUS_IS_OK(status
)) {
7914 printf("cli_write failed: %s\n", nt_errstr(status
));
7918 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7919 null_source
, &to_pull
);
7920 if (!NT_STATUS_IS_OK(status
)) {
7921 printf("cli_push returned: %s\n", nt_errstr(status
));
7926 seconds
= timeval_elapsed(&start_time
);
7927 kbytes
= (double)torture_blocksize
* torture_numops
;
7930 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7931 (double)seconds
, (int)(kbytes
/seconds
));
7935 cli_close(cli1
, fnum
);
7936 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7937 torture_close_connection(cli1
);
7941 static size_t calc_expected_return(struct cli_state
*cli
, size_t len_requested
)
7943 size_t max_pdu
= 0x1FFFF;
7945 if (cli
->server_posix_capabilities
& CIFS_UNIX_LARGE_READ_CAP
) {
7949 if (smb1cli_conn_signing_is_active(cli
->conn
)) {
7953 if (smb1cli_conn_encryption_on(cli
->conn
)) {
7954 max_pdu
= CLI_BUFFER_SIZE
;
7957 if ((len_requested
& 0xFFFF0000) == 0xFFFF0000) {
7958 len_requested
&= 0xFFFF;
7961 return MIN(len_requested
,
7962 max_pdu
- (MIN_SMB_SIZE
+ VWV(12) + 1 /* padding byte */));
7965 static bool check_read_call(struct cli_state
*cli
,
7968 size_t len_requested
)
7971 struct tevent_req
*subreq
= NULL
;
7972 ssize_t len_read
= 0;
7973 size_t len_expected
= 0;
7974 struct tevent_context
*ev
= NULL
;
7976 ev
= samba_tevent_context_init(talloc_tos());
7981 subreq
= cli_read_andx_send(talloc_tos(),
7988 if (!tevent_req_poll_ntstatus(subreq
, ev
, &status
)) {
7992 status
= cli_read_andx_recv(subreq
, &len_read
, &buf
);
7993 if (!NT_STATUS_IS_OK(status
)) {
7994 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status
));
7998 TALLOC_FREE(subreq
);
8001 len_expected
= calc_expected_return(cli
, len_requested
);
8003 if (len_expected
> 0x10000 && len_read
== 0x10000) {
8004 /* Windows servers only return a max of 0x10000,
8005 doesn't matter if you set CAP_LARGE_READX in
8006 the client sessionsetupX call or not. */
8007 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8008 (unsigned int)len_requested
);
8009 } else if (len_read
!= len_expected
) {
8010 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8011 (unsigned int)len_requested
,
8012 (unsigned int)len_read
,
8013 (unsigned int)len_expected
);
8016 d_printf("Correct read reply.\n");
8022 /* Test large readX variants. */
8023 static bool large_readx_tests(struct cli_state
*cli
,
8027 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8028 if (check_read_call(cli
, fnum
, buf
, 0xFFFF0001) == false) {
8031 /* A read of 0x10000 should return 0x10000 bytes. */
8032 if (check_read_call(cli
, fnum
, buf
, 0x10000) == false) {
8035 /* A read of 0x10000 should return 0x10001 bytes. */
8036 if (check_read_call(cli
, fnum
, buf
, 0x10001) == false) {
8039 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8040 the requested number of bytes. */
8041 if (check_read_call(cli
, fnum
, buf
, 0x1FFFF - (MIN_SMB_SIZE
+ VWV(12))) == false) {
8044 /* A read of 1MB should return 1MB bytes (on Samba). */
8045 if (check_read_call(cli
, fnum
, buf
, 0x100000) == false) {
8049 if (check_read_call(cli
, fnum
, buf
, 0x20001) == false) {
8052 if (check_read_call(cli
, fnum
, buf
, 0x22000001) == false) {
8055 if (check_read_call(cli
, fnum
, buf
, 0xFFFE0001) == false) {
8061 static bool run_large_readx(int dummy
)
8063 uint8_t *buf
= NULL
;
8064 struct cli_state
*cli1
= NULL
;
8065 struct cli_state
*cli2
= NULL
;
8066 bool correct
= false;
8067 const char *fname
= "\\large_readx.dat";
8069 uint16_t fnum1
= UINT16_MAX
;
8070 uint32_t normal_caps
= 0;
8071 size_t file_size
= 20*1024*1024;
8072 TALLOC_CTX
*frame
= talloc_stackframe();
8076 enum smb_signing_setting signing_setting
;
8077 enum protocol_types protocol
;
8081 .signing_setting
= SMB_SIGNING_IF_REQUIRED
,
8082 .protocol
= PROTOCOL_NT1
,
8084 .name
= "NT1 - SIGNING_REQUIRED",
8085 .signing_setting
= SMB_SIGNING_REQUIRED
,
8086 .protocol
= PROTOCOL_NT1
,
8090 printf("starting large_readx test\n");
8092 if (!torture_open_connection(&cli1
, 0)) {
8096 normal_caps
= smb1cli_conn_capabilities(cli1
->conn
);
8098 if (!(normal_caps
& CAP_LARGE_READX
)) {
8099 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8100 (unsigned int)normal_caps
);
8104 /* Create a file of size 4MB. */
8105 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
8106 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8107 0, 0, &fnum1
, NULL
);
8109 if (!NT_STATUS_IS_OK(status
)) {
8110 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8114 /* Write file_size bytes. */
8115 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
8120 status
= cli_writeall(cli1
,
8127 if (!NT_STATUS_IS_OK(status
)) {
8128 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
8132 status
= cli_close(cli1
, fnum1
);
8133 if (!NT_STATUS_IS_OK(status
)) {
8134 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8140 for (i
=0; i
< ARRAY_SIZE(runs
); i
++) {
8141 enum smb_signing_setting saved_signing_setting
= signing_state
;
8142 uint16_t fnum2
= -1;
8145 (runs
[i
].signing_setting
== SMB_SIGNING_REQUIRED
))
8147 d_printf("skip[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
8151 d_printf("run[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
8153 signing_state
= runs
[i
].signing_setting
;
8154 cli2
= open_nbt_connection();
8155 signing_state
= saved_signing_setting
;
8160 status
= smbXcli_negprot(cli2
->conn
,
8164 if (!NT_STATUS_IS_OK(status
)) {
8168 status
= cli_session_setup(cli2
,
8175 if (!NT_STATUS_IS_OK(status
)) {
8179 status
= cli_tree_connect(cli2
,
8183 strlen(password
)+1);
8184 if (!NT_STATUS_IS_OK(status
)) {
8188 cli_set_timeout(cli2
, 120000); /* set a really long timeout (2 minutes) */
8190 normal_caps
= smb1cli_conn_capabilities(cli2
->conn
);
8192 if (!(normal_caps
& CAP_LARGE_READX
)) {
8193 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8194 (unsigned int)normal_caps
);
8199 if (force_cli_encryption(cli2
, share
) == false) {
8202 } else if (SERVER_HAS_UNIX_CIFS(cli2
)) {
8203 uint16_t major
, minor
;
8204 uint32_t caplow
, caphigh
;
8206 status
= cli_unix_extensions_version(cli2
,
8209 if (!NT_STATUS_IS_OK(status
)) {
8214 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
,
8215 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
8216 0, 0, &fnum2
, NULL
);
8217 if (!NT_STATUS_IS_OK(status
)) {
8218 d_printf("Second open %s failed: %s\n", fname
, nt_errstr(status
));
8222 /* All reads must return less than file_size bytes. */
8223 if (!large_readx_tests(cli2
, fnum2
, buf
)) {
8227 status
= cli_close(cli2
, fnum2
);
8228 if (!NT_STATUS_IS_OK(status
)) {
8229 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8234 if (!torture_close_connection(cli2
)) {
8241 printf("Success on large_readx test\n");
8246 if (!torture_close_connection(cli2
)) {
8252 if (fnum1
!= UINT16_MAX
) {
8253 status
= cli_close(cli1
, fnum1
);
8254 if (!NT_STATUS_IS_OK(status
)) {
8255 d_printf("cli_close failed: %s\n", nt_errstr(status
));
8260 status
= cli_unlink(cli1
, fname
,
8261 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8262 if (!NT_STATUS_IS_OK(status
)) {
8263 printf("unlink failed (%s)\n", nt_errstr(status
));
8266 if (!torture_close_connection(cli1
)) {
8273 printf("finished large_readx test\n");
8277 static bool run_cli_echo(int dummy
)
8279 struct cli_state
*cli
;
8282 printf("starting cli_echo test\n");
8283 if (!torture_open_connection(&cli
, 0)) {
8286 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8288 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
8290 d_printf("cli_echo returned %s\n", nt_errstr(status
));
8292 torture_close_connection(cli
);
8293 return NT_STATUS_IS_OK(status
);
8296 static bool run_uid_regression_test(int dummy
)
8298 static struct cli_state
*cli
;
8301 bool correct
= True
;
8304 printf("starting uid regression test\n");
8306 if (!torture_open_connection(&cli
, 0)) {
8310 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8312 /* Ok - now save then logoff our current user. */
8313 old_vuid
= cli_state_get_uid(cli
);
8315 status
= cli_ulogoff(cli
);
8316 if (!NT_STATUS_IS_OK(status
)) {
8317 d_printf("(%s) cli_ulogoff failed: %s\n",
8318 __location__
, nt_errstr(status
));
8323 cli_state_set_uid(cli
, old_vuid
);
8325 /* Try an operation. */
8326 status
= cli_mkdir(cli
, "\\uid_reg_test");
8327 if (NT_STATUS_IS_OK(status
)) {
8328 d_printf("(%s) cli_mkdir succeeded\n",
8333 /* Should be bad uid. */
8334 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
8335 NT_STATUS_USER_SESSION_DELETED
)) {
8341 old_cnum
= cli_state_get_tid(cli
);
8343 /* Now try a SMBtdis with the invald vuid set to zero. */
8344 cli_state_set_uid(cli
, 0);
8346 /* This should succeed. */
8347 status
= cli_tdis(cli
);
8349 if (NT_STATUS_IS_OK(status
)) {
8350 d_printf("First tdis with invalid vuid should succeed.\n");
8352 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
8357 cli_state_set_uid(cli
, old_vuid
);
8358 cli_state_set_tid(cli
, old_cnum
);
8360 /* This should fail. */
8361 status
= cli_tdis(cli
);
8362 if (NT_STATUS_IS_OK(status
)) {
8363 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
8367 /* Should be bad tid. */
8368 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
8369 NT_STATUS_NETWORK_NAME_DELETED
)) {
8375 cli_rmdir(cli
, "\\uid_reg_test");
8384 static const char *illegal_chars
= "*\\/?<>|\":";
8385 static char force_shortname_chars
[] = " +,.[];=\177";
8387 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
8388 const char *mask
, void *state
)
8390 struct cli_state
*pcli
= (struct cli_state
*)state
;
8392 NTSTATUS status
= NT_STATUS_OK
;
8394 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
8396 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
8397 return NT_STATUS_OK
;
8399 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
8400 status
= cli_rmdir(pcli
, fname
);
8401 if (!NT_STATUS_IS_OK(status
)) {
8402 printf("del_fn: failed to rmdir %s\n,", fname
);
8405 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8406 if (!NT_STATUS_IS_OK(status
)) {
8407 printf("del_fn: failed to unlink %s\n,", fname
);
8419 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
8420 const char *name
, void *state
)
8422 struct sn_state
*s
= (struct sn_state
*)state
;
8426 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
8427 i
, finfo
->name
, finfo
->short_name
);
8430 if (strchr(force_shortname_chars
, i
)) {
8431 if (!finfo
->short_name
) {
8432 /* Shortname not created when it should be. */
8433 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
8434 __location__
, finfo
->name
, i
);
8437 } else if (finfo
->short_name
){
8438 /* Shortname created when it should not be. */
8439 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
8440 __location__
, finfo
->short_name
, finfo
->name
);
8444 return NT_STATUS_OK
;
8447 static bool run_shortname_test(int dummy
)
8449 static struct cli_state
*cli
;
8450 bool correct
= True
;
8456 printf("starting shortname test\n");
8458 if (!torture_open_connection(&cli
, 0)) {
8462 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8464 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
8465 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
8466 cli_rmdir(cli
, "\\shortname");
8468 status
= cli_mkdir(cli
, "\\shortname");
8469 if (!NT_STATUS_IS_OK(status
)) {
8470 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
8471 __location__
, nt_errstr(status
));
8476 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
8480 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
8487 for (i
= 32; i
< 128; i
++) {
8488 uint16_t fnum
= (uint16_t)-1;
8492 if (strchr(illegal_chars
, i
)) {
8497 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
8498 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
8499 FILE_OVERWRITE_IF
, 0, 0, &fnum
, NULL
);
8500 if (!NT_STATUS_IS_OK(status
)) {
8501 d_printf("(%s) cli_nt_create of %s failed: %s\n",
8502 __location__
, fname
, nt_errstr(status
));
8506 cli_close(cli
, fnum
);
8509 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
8510 shortname_list_fn
, &s
);
8511 if (s
.matched
!= 1) {
8512 d_printf("(%s) failed to list %s: %s\n",
8513 __location__
, fname
, nt_errstr(status
));
8518 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8519 if (!NT_STATUS_IS_OK(status
)) {
8520 d_printf("(%s) failed to delete %s: %s\n",
8521 __location__
, fname
, nt_errstr(status
));
8534 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
8535 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
8536 cli_rmdir(cli
, "\\shortname");
8537 torture_close_connection(cli
);
8541 static void pagedsearch_cb(struct tevent_req
*req
)
8544 struct tldap_message
*msg
;
8547 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
8548 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
8549 d_printf("tldap_search_paged_recv failed: %s\n",
8550 tldap_rc2string(rc
));
8553 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
8557 if (!tldap_entry_dn(msg
, &dn
)) {
8558 d_printf("tldap_entry_dn failed\n");
8561 d_printf("%s\n", dn
);
8565 static bool run_tldap(int dummy
)
8567 struct tldap_context
*ld
;
8571 struct sockaddr_storage addr
;
8572 struct tevent_context
*ev
;
8573 struct tevent_req
*req
;
8577 if (!resolve_name(host
, &addr
, 0, false)) {
8578 d_printf("could not find host %s\n", host
);
8581 status
= open_socket_out(&addr
, 389, 9999, &fd
);
8582 if (!NT_STATUS_IS_OK(status
)) {
8583 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
8587 ld
= tldap_context_create(talloc_tos(), fd
);
8590 d_printf("tldap_context_create failed\n");
8594 rc
= tldap_fetch_rootdse(ld
);
8595 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
8596 d_printf("tldap_fetch_rootdse failed: %s\n",
8597 tldap_errstr(talloc_tos(), ld
, rc
));
8601 basedn
= tldap_talloc_single_attribute(
8602 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
8603 if (basedn
== NULL
) {
8604 d_printf("no defaultNamingContext\n");
8607 d_printf("defaultNamingContext: %s\n", basedn
);
8609 ev
= samba_tevent_context_init(talloc_tos());
8611 d_printf("tevent_context_init failed\n");
8615 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
8616 TLDAP_SCOPE_SUB
, "(objectclass=*)",
8618 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
8620 d_printf("tldap_search_paged_send failed\n");
8623 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
8625 tevent_req_poll(req
, ev
);
8629 /* test search filters against rootDSE */
8630 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
8631 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
8633 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
8634 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
8635 talloc_tos(), NULL
);
8636 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
8637 d_printf("tldap_search with complex filter failed: %s\n",
8638 tldap_errstr(talloc_tos(), ld
, rc
));
8646 /* Torture test to ensure no regression of :
8647 https://bugzilla.samba.org/show_bug.cgi?id=7084
8650 static bool run_dir_createtime(int dummy
)
8652 struct cli_state
*cli
;
8653 const char *dname
= "\\testdir";
8654 const char *fname
= "\\testdir\\testfile";
8656 struct timespec create_time
;
8657 struct timespec create_time1
;
8661 if (!torture_open_connection(&cli
, 0)) {
8665 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8666 cli_rmdir(cli
, dname
);
8668 status
= cli_mkdir(cli
, dname
);
8669 if (!NT_STATUS_IS_OK(status
)) {
8670 printf("mkdir failed: %s\n", nt_errstr(status
));
8674 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
8676 if (!NT_STATUS_IS_OK(status
)) {
8677 printf("cli_qpathinfo2 returned %s\n",
8682 /* Sleep 3 seconds, then create a file. */
8685 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
8687 if (!NT_STATUS_IS_OK(status
)) {
8688 printf("cli_openx failed: %s\n", nt_errstr(status
));
8692 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
8694 if (!NT_STATUS_IS_OK(status
)) {
8695 printf("cli_qpathinfo2 (2) returned %s\n",
8700 if (timespec_compare(&create_time1
, &create_time
)) {
8701 printf("run_dir_createtime: create time was updated (error)\n");
8703 printf("run_dir_createtime: create time was not updated (correct)\n");
8709 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8710 cli_rmdir(cli
, dname
);
8711 if (!torture_close_connection(cli
)) {
8718 static bool run_streamerror(int dummy
)
8720 struct cli_state
*cli
;
8721 const char *dname
= "\\testdir";
8722 const char *streamname
=
8723 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
8725 time_t change_time
, access_time
, write_time
;
8727 uint16_t mode
, fnum
;
8730 if (!torture_open_connection(&cli
, 0)) {
8734 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8735 cli_rmdir(cli
, dname
);
8737 status
= cli_mkdir(cli
, dname
);
8738 if (!NT_STATUS_IS_OK(status
)) {
8739 printf("mkdir failed: %s\n", nt_errstr(status
));
8743 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
8744 &write_time
, &size
, &mode
);
8745 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
8746 printf("pathinfo returned %s, expected "
8747 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8752 status
= cli_ntcreate(cli
, streamname
, 0x16,
8753 FILE_READ_DATA
|FILE_READ_EA
|
8754 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
8755 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
8756 FILE_OPEN
, 0, 0, &fnum
, NULL
);
8758 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
8759 printf("ntcreate returned %s, expected "
8760 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8766 cli_rmdir(cli
, dname
);
8770 struct pidtest_state
{
8776 static void pid_echo_done(struct tevent_req
*subreq
);
8778 static struct tevent_req
*pid_echo_send(TALLOC_CTX
*mem_ctx
,
8779 struct tevent_context
*ev
,
8780 struct cli_state
*cli
)
8782 struct tevent_req
*req
, *subreq
;
8783 struct pidtest_state
*state
;
8785 req
= tevent_req_create(mem_ctx
, &state
, struct pidtest_state
);
8790 SSVAL(state
->vwv
, 0, 1);
8791 state
->data
= data_blob_const("hello", 5);
8793 subreq
= smb1cli_req_send(state
,
8798 0, 0, /* *_flags2 */
8800 0xDEADBEEF, /* pid */
8803 ARRAY_SIZE(state
->vwv
), state
->vwv
,
8804 state
->data
.length
, state
->data
.data
);
8806 if (tevent_req_nomem(subreq
, req
)) {
8807 return tevent_req_post(req
, ev
);
8809 tevent_req_set_callback(subreq
, pid_echo_done
, req
);
8813 static void pid_echo_done(struct tevent_req
*subreq
)
8815 struct tevent_req
*req
= tevent_req_callback_data(
8816 subreq
, struct tevent_req
);
8817 struct pidtest_state
*state
= tevent_req_data(
8818 req
, struct pidtest_state
);
8821 uint8_t *bytes
= NULL
;
8822 struct iovec
*recv_iov
= NULL
;
8823 uint8_t *phdr
= NULL
;
8824 uint16_t pidlow
= 0;
8825 uint16_t pidhigh
= 0;
8826 struct smb1cli_req_expected_response expected
[] = {
8828 .status
= NT_STATUS_OK
,
8833 status
= smb1cli_req_recv(subreq
, state
,
8838 NULL
, /* pvwv_offset */
8841 NULL
, /* pbytes_offset */
8843 expected
, ARRAY_SIZE(expected
));
8845 TALLOC_FREE(subreq
);
8847 if (!NT_STATUS_IS_OK(status
)) {
8848 tevent_req_nterror(req
, status
);
8852 if (num_bytes
!= state
->data
.length
) {
8853 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
8857 if (memcmp(bytes
, state
->data
.data
, num_bytes
) != 0) {
8858 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
8862 /* Check pid low/high == DEADBEEF */
8863 pidlow
= SVAL(phdr
, HDR_PID
);
8864 if (pidlow
!= 0xBEEF){
8865 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
8866 (unsigned int)pidlow
);
8867 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
8870 pidhigh
= SVAL(phdr
, HDR_PIDHIGH
);
8871 if (pidhigh
!= 0xDEAD){
8872 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
8873 (unsigned int)pidhigh
);
8874 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
8878 tevent_req_done(req
);
8881 static NTSTATUS
pid_echo_recv(struct tevent_req
*req
)
8883 return tevent_req_simple_recv_ntstatus(req
);
8886 static bool run_pidhigh(int dummy
)
8888 bool success
= false;
8889 struct cli_state
*cli
= NULL
;
8891 struct tevent_context
*ev
= NULL
;
8892 struct tevent_req
*req
= NULL
;
8893 TALLOC_CTX
*frame
= talloc_stackframe();
8895 printf("starting pid high test\n");
8896 if (!torture_open_connection(&cli
, 0)) {
8899 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8901 ev
= samba_tevent_context_init(frame
);
8906 req
= pid_echo_send(frame
, ev
, cli
);
8911 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
8915 status
= pid_echo_recv(req
);
8916 if (NT_STATUS_IS_OK(status
)) {
8917 printf("pid high test ok\n");
8924 torture_close_connection(cli
);
8928 static bool run_local_substitute(int dummy
)
8932 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
8933 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
8934 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
8935 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
8936 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
8937 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
8938 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
8939 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
8941 /* Different captialization rules in sub_basic... */
8943 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
8949 static bool run_local_base64(int dummy
)
8954 for (i
=1; i
<2000; i
++) {
8955 DATA_BLOB blob1
, blob2
;
8958 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
8960 generate_random_buffer(blob1
.data
, blob1
.length
);
8962 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
8964 d_fprintf(stderr
, "base64_encode_data_blob failed "
8965 "for %d bytes\n", i
);
8968 blob2
= base64_decode_data_blob(b64
);
8971 if (data_blob_cmp(&blob1
, &blob2
)) {
8972 d_fprintf(stderr
, "data_blob_cmp failed for %d "
8976 TALLOC_FREE(blob1
.data
);
8977 data_blob_free(&blob2
);
8982 static void parse_fn(time_t timeout
, DATA_BLOB blob
, void *private_data
)
8987 static bool run_local_gencache(int dummy
)
8993 struct memcache
*mem
;
8996 mem
= memcache_init(NULL
, 0);
8998 d_printf("%s: memcache_init failed\n", __location__
);
9001 memcache_set_global(mem
);
9003 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
9004 d_printf("%s: gencache_set() failed\n", __location__
);
9008 if (!gencache_get("foo", NULL
, NULL
, NULL
)) {
9009 d_printf("%s: gencache_get() failed\n", __location__
);
9013 for (i
=0; i
<1000000; i
++) {
9014 gencache_parse("foo", parse_fn
, NULL
);
9017 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9018 d_printf("%s: gencache_get() failed\n", __location__
);
9023 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9024 d_printf("%s: gencache_get() failed\n", __location__
);
9028 if (strcmp(val
, "bar") != 0) {
9029 d_printf("%s: gencache_get() returned %s, expected %s\n",
9030 __location__
, val
, "bar");
9037 if (!gencache_del("foo")) {
9038 d_printf("%s: gencache_del() failed\n", __location__
);
9041 if (gencache_del("foo")) {
9042 d_printf("%s: second gencache_del() succeeded\n",
9047 if (gencache_get("foo", talloc_tos(), &val
, &tm
)) {
9048 d_printf("%s: gencache_get() on deleted entry "
9049 "succeeded\n", __location__
);
9053 blob
= data_blob_string_const_null("bar");
9054 tm
= time(NULL
) + 60;
9056 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
9057 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
9061 if (!gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
9062 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
9066 if (strcmp((const char *)blob
.data
, "bar") != 0) {
9067 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9068 __location__
, (const char *)blob
.data
, "bar");
9069 data_blob_free(&blob
);
9073 data_blob_free(&blob
);
9075 if (!gencache_del("foo")) {
9076 d_printf("%s: gencache_del() failed\n", __location__
);
9079 if (gencache_del("foo")) {
9080 d_printf("%s: second gencache_del() succeeded\n",
9085 if (gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
9086 d_printf("%s: gencache_get_data_blob() on deleted entry "
9087 "succeeded\n", __location__
);
9092 blob
.data
= (uint8_t *)&v
;
9093 blob
.length
= sizeof(v
);
9095 if (!gencache_set_data_blob("blob", &blob
, tm
)) {
9096 d_printf("%s: gencache_set_data_blob() failed\n",
9100 if (gencache_get("blob", talloc_tos(), &val
, &tm
)) {
9101 d_printf("%s: gencache_get succeeded\n", __location__
);
9108 static bool rbt_testval(struct db_context
*db
, const char *key
,
9111 struct db_record
*rec
;
9112 TDB_DATA data
= string_tdb_data(value
);
9117 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
9119 d_fprintf(stderr
, "fetch_locked failed\n");
9122 status
= dbwrap_record_store(rec
, data
, 0);
9123 if (!NT_STATUS_IS_OK(status
)) {
9124 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
9129 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
9131 d_fprintf(stderr
, "second fetch_locked failed\n");
9135 dbvalue
= dbwrap_record_get_value(rec
);
9136 if ((dbvalue
.dsize
!= data
.dsize
)
9137 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
9138 d_fprintf(stderr
, "Got wrong data back\n");
9148 static int local_rbtree_traverse_read(struct db_record
*rec
, void *private_data
)
9150 int *count2
= (int *)private_data
;
9155 static int local_rbtree_traverse_delete(struct db_record
*rec
, void *private_data
)
9157 int *count2
= (int *)private_data
;
9159 dbwrap_record_delete(rec
);
9163 static bool run_local_rbtree(int dummy
)
9165 struct db_context
*db
;
9172 db
= db_open_rbt(NULL
);
9175 d_fprintf(stderr
, "db_open_rbt failed\n");
9179 for (i
=0; i
<1000; i
++) {
9182 if (asprintf(&key
, "key%ld", random()) == -1) {
9185 if (asprintf(&value
, "value%ld", random()) == -1) {
9190 if (!rbt_testval(db
, key
, value
)) {
9197 if (asprintf(&value
, "value%ld", random()) == -1) {
9202 if (!rbt_testval(db
, key
, value
)) {
9213 count
= 0; count2
= 0;
9214 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
9216 printf("%s: read1: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
9217 if ((count
!= count2
) || (count
!= 1000)) {
9220 count
= 0; count2
= 0;
9221 status
= dbwrap_traverse(db
, local_rbtree_traverse_delete
,
9223 printf("%s: delete: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
9224 if ((count
!= count2
) || (count
!= 1000)) {
9227 count
= 0; count2
= 0;
9228 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
9230 printf("%s: read2: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
9231 if ((count
!= count2
) || (count
!= 0)) {
9242 local test for character set functions
9244 This is a very simple test for the functionality in convert_string_error()
9246 static bool run_local_convert_string(int dummy
)
9248 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
9249 const char *test_strings
[2] = { "March", "M\303\244rz" };
9253 for (i
=0; i
<2; i
++) {
9254 const char *str
= test_strings
[i
];
9255 int len
= strlen(str
);
9256 size_t converted_size
;
9259 memset(dst
, 'X', sizeof(dst
));
9261 /* first try with real source length */
9262 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
9267 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
9271 if (converted_size
!= len
) {
9272 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
9273 str
, len
, (int)converted_size
);
9277 if (strncmp(str
, dst
, converted_size
) != 0) {
9278 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
9282 if (strlen(str
) != converted_size
) {
9283 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
9284 (int)strlen(str
), (int)converted_size
);
9288 if (dst
[converted_size
] != 'X') {
9289 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
9293 /* now with srclen==-1, this causes the nul to be
9295 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
9300 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
9304 if (converted_size
!= len
+1) {
9305 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
9306 str
, len
, (int)converted_size
);
9310 if (strncmp(str
, dst
, converted_size
) != 0) {
9311 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
9315 if (len
+1 != converted_size
) {
9316 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
9317 len
+1, (int)converted_size
);
9321 if (dst
[converted_size
] != 'X') {
9322 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
9329 TALLOC_FREE(tmp_ctx
);
9332 TALLOC_FREE(tmp_ctx
);
9337 struct talloc_dict_test
{
9341 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
9343 int *count
= (int *)priv
;
9348 static bool run_local_talloc_dict(int dummy
)
9350 struct talloc_dict
*dict
;
9351 struct talloc_dict_test
*t
;
9352 int key
, count
, res
;
9355 dict
= talloc_dict_init(talloc_tos());
9360 t
= talloc(talloc_tos(), struct talloc_dict_test
);
9367 ok
= talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), &t
);
9373 res
= talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
);
9391 static bool run_local_string_to_sid(int dummy
) {
9394 if (string_to_sid(&sid
, "S--1-5-32-545")) {
9395 printf("allowing S--1-5-32-545\n");
9398 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
9399 printf("allowing S-1-5-32-+545\n");
9402 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")) {
9403 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
9406 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
9407 printf("allowing S-1-5-32-545-abc\n");
9410 if (string_to_sid(&sid
, "S-300-5-32-545")) {
9411 printf("allowing S-300-5-32-545\n");
9414 if (string_to_sid(&sid
, "S-1-0xfffffffffffffe-32-545")) {
9415 printf("allowing S-1-0xfffffffffffffe-32-545\n");
9418 if (string_to_sid(&sid
, "S-1-0xffffffffffff-5294967297-545")) {
9419 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
9422 if (!string_to_sid(&sid
, "S-1-0xfffffffffffe-32-545")) {
9423 printf("could not parse S-1-0xfffffffffffe-32-545\n");
9426 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
9427 printf("could not parse S-1-5-32-545\n");
9430 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
9431 printf("mis-parsed S-1-5-32-545 as %s\n",
9432 sid_string_tos(&sid
));
9438 static bool sid_to_string_test(const char *expected
) {
9443 if (!string_to_sid(&sid
, expected
)) {
9444 printf("could not parse %s\n", expected
);
9448 str
= dom_sid_string(NULL
, &sid
);
9449 if (strcmp(str
, expected
)) {
9450 printf("Comparison failed (%s != %s)\n", str
, expected
);
9457 static bool run_local_sid_to_string(int dummy
) {
9458 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
9460 if (!sid_to_string_test("S-1-545"))
9462 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
9467 static bool run_local_binary_to_sid(int dummy
) {
9468 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
9469 static const uint8_t good_binary_sid
[] = {
9470 0x1, /* revision number */
9472 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9473 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9474 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9475 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9476 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9477 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9478 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9479 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9480 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9481 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9482 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9483 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9484 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9485 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9486 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9487 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9490 static const uint8_t long_binary_sid
[] = {
9491 0x1, /* revision number */
9493 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9494 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9495 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9496 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9497 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9498 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9499 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9500 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9501 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9502 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9503 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9504 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9505 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9506 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9507 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9508 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9509 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9510 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9511 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9514 static const uint8_t long_binary_sid2
[] = {
9515 0x1, /* revision number */
9517 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9518 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9519 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9520 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9521 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9522 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9523 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9524 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9525 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9526 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9527 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9528 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9529 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9530 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9531 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9532 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9533 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9534 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9535 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9536 0x1, 0x1, 0x1, 0x1, /* auth[18] */
9537 0x1, 0x1, 0x1, 0x1, /* auth[19] */
9538 0x1, 0x1, 0x1, 0x1, /* auth[20] */
9539 0x1, 0x1, 0x1, 0x1, /* auth[21] */
9540 0x1, 0x1, 0x1, 0x1, /* auth[22] */
9541 0x1, 0x1, 0x1, 0x1, /* auth[23] */
9542 0x1, 0x1, 0x1, 0x1, /* auth[24] */
9543 0x1, 0x1, 0x1, 0x1, /* auth[25] */
9544 0x1, 0x1, 0x1, 0x1, /* auth[26] */
9545 0x1, 0x1, 0x1, 0x1, /* auth[27] */
9546 0x1, 0x1, 0x1, 0x1, /* auth[28] */
9547 0x1, 0x1, 0x1, 0x1, /* auth[29] */
9548 0x1, 0x1, 0x1, 0x1, /* auth[30] */
9549 0x1, 0x1, 0x1, 0x1, /* auth[31] */
9552 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
9555 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
9558 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
9564 /* Split a path name into filename and stream name components. Canonicalise
9565 * such that an implicit $DATA token is always explicit.
9567 * The "specification" of this function can be found in the
9568 * run_local_stream_name() function in torture.c, I've tried those
9569 * combinations against a W2k3 server.
9572 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
9573 char **pbase
, char **pstream
)
9576 char *stream
= NULL
;
9577 char *sname
; /* stream name */
9578 const char *stype
; /* stream type */
9580 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
9582 sname
= strchr_m(fname
, ':');
9584 if (sname
== NULL
) {
9585 if (pbase
!= NULL
) {
9586 base
= talloc_strdup(mem_ctx
, fname
);
9587 NT_STATUS_HAVE_NO_MEMORY(base
);
9592 if (pbase
!= NULL
) {
9593 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
9594 NT_STATUS_HAVE_NO_MEMORY(base
);
9599 stype
= strchr_m(sname
, ':');
9601 if (stype
== NULL
) {
9602 sname
= talloc_strdup(mem_ctx
, sname
);
9606 if (strcasecmp_m(stype
, ":$DATA") != 0) {
9608 * If there is an explicit stream type, so far we only
9609 * allow $DATA. Is there anything else allowed? -- vl
9611 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
9613 return NT_STATUS_OBJECT_NAME_INVALID
;
9615 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
9619 if (sname
== NULL
) {
9621 return NT_STATUS_NO_MEMORY
;
9624 if (sname
[0] == '\0') {
9626 * no stream name, so no stream
9631 if (pstream
!= NULL
) {
9632 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
9633 if (stream
== NULL
) {
9636 return NT_STATUS_NO_MEMORY
;
9639 * upper-case the type field
9641 (void)strupper_m(strchr_m(stream
, ':')+1);
9645 if (pbase
!= NULL
) {
9648 if (pstream
!= NULL
) {
9651 return NT_STATUS_OK
;
9654 static bool test_stream_name(const char *fname
, const char *expected_base
,
9655 const char *expected_stream
,
9656 NTSTATUS expected_status
)
9660 char *stream
= NULL
;
9662 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
9663 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
9667 if (!NT_STATUS_IS_OK(status
)) {
9671 if (base
== NULL
) goto error
;
9673 if (strcmp(expected_base
, base
) != 0) goto error
;
9675 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
9676 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
9678 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
9682 TALLOC_FREE(stream
);
9686 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
9687 fname
, expected_base
? expected_base
: "<NULL>",
9688 expected_stream
? expected_stream
: "<NULL>",
9689 nt_errstr(expected_status
));
9690 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
9691 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
9694 TALLOC_FREE(stream
);
9698 static bool run_local_stream_name(int dummy
)
9702 ret
&= test_stream_name(
9703 "bla", "bla", NULL
, NT_STATUS_OK
);
9704 ret
&= test_stream_name(
9705 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
9706 ret
&= test_stream_name(
9707 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
9708 ret
&= test_stream_name(
9709 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
9710 ret
&= test_stream_name(
9711 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
9712 ret
&= test_stream_name(
9713 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
9714 ret
&= test_stream_name(
9715 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
9716 ret
&= test_stream_name(
9717 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
9722 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
9724 if (a
.length
!= b
.length
) {
9725 printf("a.length=%d != b.length=%d\n",
9726 (int)a
.length
, (int)b
.length
);
9729 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
9730 printf("a.data and b.data differ\n");
9736 static bool run_local_memcache(int dummy
)
9738 struct memcache
*cache
;
9740 DATA_BLOB d1
, d2
, d3
;
9741 DATA_BLOB v1
, v2
, v3
;
9743 TALLOC_CTX
*mem_ctx
;
9745 size_t size1
, size2
;
9748 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
9750 if (cache
== NULL
) {
9751 printf("memcache_init failed\n");
9755 d1
= data_blob_const("d1", 2);
9756 d2
= data_blob_const("d2", 2);
9757 d3
= data_blob_const("d3", 2);
9759 k1
= data_blob_const("d1", 2);
9760 k2
= data_blob_const("d2", 2);
9762 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
9763 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
9765 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
9766 printf("could not find k1\n");
9769 if (!data_blob_equal(d1
, v1
)) {
9773 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
9774 printf("could not find k2\n");
9777 if (!data_blob_equal(d2
, v2
)) {
9781 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
9783 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
9784 printf("could not find replaced k1\n");
9787 if (!data_blob_equal(d3
, v3
)) {
9791 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
9793 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
9794 printf("Did find k2, should have been purged\n");
9800 cache
= memcache_init(NULL
, 0);
9802 mem_ctx
= talloc_init("foo");
9804 str1
= talloc_strdup(mem_ctx
, "string1");
9805 str2
= talloc_strdup(mem_ctx
, "string2");
9807 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
9808 data_blob_string_const("torture"), &str1
);
9809 size1
= talloc_total_size(cache
);
9811 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
9812 data_blob_string_const("torture"), &str2
);
9813 size2
= talloc_total_size(cache
);
9815 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
9817 if (size2
> size1
) {
9818 printf("memcache leaks memory!\n");
9828 static void wbclient_done(struct tevent_req
*req
)
9831 struct winbindd_response
*wb_resp
;
9832 int *i
= (int *)tevent_req_callback_data_void(req
);
9834 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
9837 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
9840 static bool run_wbclient_multi_ping(int dummy
)
9842 struct tevent_context
*ev
;
9843 struct wb_context
**wb_ctx
;
9844 struct winbindd_request wb_req
;
9845 bool result
= false;
9848 BlockSignals(True
, SIGPIPE
);
9850 ev
= tevent_context_init(talloc_tos());
9855 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
9856 if (wb_ctx
== NULL
) {
9860 ZERO_STRUCT(wb_req
);
9861 wb_req
.cmd
= WINBINDD_PING
;
9863 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
9865 for (i
=0; i
<torture_nprocs
; i
++) {
9866 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
9867 if (wb_ctx
[i
] == NULL
) {
9870 for (j
=0; j
<torture_numops
; j
++) {
9871 struct tevent_req
*req
;
9872 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
9873 (j
% 2) == 0, &wb_req
);
9877 tevent_req_set_callback(req
, wbclient_done
, &i
);
9883 while (i
< torture_nprocs
* torture_numops
) {
9884 tevent_loop_once(ev
);
9893 static void getaddrinfo_finished(struct tevent_req
*req
)
9895 char *name
= (char *)tevent_req_callback_data_void(req
);
9896 struct addrinfo
*ainfo
;
9899 res
= getaddrinfo_recv(req
, &ainfo
);
9901 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
9904 d_printf("gai(%s) succeeded\n", name
);
9905 freeaddrinfo(ainfo
);
9908 static bool run_getaddrinfo_send(int dummy
)
9910 TALLOC_CTX
*frame
= talloc_stackframe();
9911 struct fncall_context
*ctx
;
9912 struct tevent_context
*ev
;
9913 bool result
= false;
9914 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
9915 "www.slashdot.org", "heise.de" };
9916 struct tevent_req
*reqs
[4];
9919 ev
= samba_tevent_context_init(frame
);
9924 ctx
= fncall_context_init(frame
, 4);
9926 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
9927 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
9929 if (reqs
[i
] == NULL
) {
9932 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
9933 discard_const_p(void, names
[i
]));
9936 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
9937 tevent_loop_once(ev
);
9946 static bool dbtrans_inc(struct db_context
*db
)
9948 struct db_record
*rec
;
9954 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
9956 printf(__location__
"fetch_lock failed\n");
9960 value
= dbwrap_record_get_value(rec
);
9962 if (value
.dsize
!= sizeof(uint32_t)) {
9963 printf(__location__
"value.dsize = %d\n",
9968 memcpy(&val
, value
.dptr
, sizeof(val
));
9971 status
= dbwrap_record_store(
9972 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
9973 if (!NT_STATUS_IS_OK(status
)) {
9974 printf(__location__
"store failed: %s\n",
9985 static bool run_local_dbtrans(int dummy
)
9987 struct db_context
*db
;
9988 struct db_record
*rec
;
9994 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
9995 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
,
9998 printf("Could not open transtest.db\n");
10002 res
= dbwrap_transaction_start(db
);
10004 printf(__location__
"transaction_start failed\n");
10008 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
10010 printf(__location__
"fetch_lock failed\n");
10014 value
= dbwrap_record_get_value(rec
);
10016 if (value
.dptr
== NULL
) {
10018 status
= dbwrap_record_store(
10019 rec
, make_tdb_data((uint8_t *)&initial
,
10022 if (!NT_STATUS_IS_OK(status
)) {
10023 printf(__location__
"store returned %s\n",
10024 nt_errstr(status
));
10031 res
= dbwrap_transaction_commit(db
);
10033 printf(__location__
"transaction_commit failed\n");
10038 uint32_t val
, val2
;
10041 res
= dbwrap_transaction_start(db
);
10043 printf(__location__
"transaction_start failed\n");
10047 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val
);
10048 if (!NT_STATUS_IS_OK(status
)) {
10049 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
10050 nt_errstr(status
));
10054 for (i
=0; i
<10; i
++) {
10055 if (!dbtrans_inc(db
)) {
10060 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val2
);
10061 if (!NT_STATUS_IS_OK(status
)) {
10062 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
10063 nt_errstr(status
));
10067 if (val2
!= val
+ 10) {
10068 printf(__location__
"val=%d, val2=%d\n",
10069 (int)val
, (int)val2
);
10073 printf("val2=%d\r", val2
);
10075 res
= dbwrap_transaction_commit(db
);
10077 printf(__location__
"transaction_commit failed\n");
10087 * Just a dummy test to be run under a debugger. There's no real way
10088 * to inspect the tevent_select specific function from outside of
10092 static bool run_local_tevent_select(int dummy
)
10094 struct tevent_context
*ev
;
10095 struct tevent_fd
*fd1
, *fd2
;
10096 bool result
= false;
10098 ev
= tevent_context_init_byname(NULL
, "select");
10100 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
10104 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
10106 d_fprintf(stderr
, "tevent_add_fd failed\n");
10109 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
10111 d_fprintf(stderr
, "tevent_add_fd failed\n");
10116 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
10118 d_fprintf(stderr
, "tevent_add_fd failed\n");
10128 static bool run_local_hex_encode_buf(int dummy
)
10134 for (i
=0; i
<sizeof(src
); i
++) {
10137 hex_encode_buf(buf
, src
, sizeof(src
));
10138 if (strcmp(buf
, "0001020304050607") != 0) {
10141 hex_encode_buf(buf
, NULL
, 0);
10142 if (buf
[0] != '\0') {
10148 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
10170 "1001:1111:1111:1000:0:1111:1111:1111",
10179 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
10193 "1001:1111:1111:1000:0:1111:1111:1111"
10196 static bool run_local_remove_duplicate_addrs2(int dummy
)
10198 struct ip_service test_vector
[28];
10201 /* Construct the sockaddr_storage test vector. */
10202 for (i
= 0; i
< 28; i
++) {
10203 struct addrinfo hints
;
10204 struct addrinfo
*res
= NULL
;
10207 memset(&hints
, '\0', sizeof(hints
));
10208 hints
.ai_flags
= AI_NUMERICHOST
;
10209 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
10214 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
10215 remove_duplicate_addrs2_test_strings_vector
[i
]);
10218 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
10219 memcpy(&test_vector
[i
].ss
,
10225 count
= remove_duplicate_addrs2(test_vector
, i
);
10228 fprintf(stderr
, "count wrong (%d) should be 14\n",
10233 for (i
= 0; i
< count
; i
++) {
10234 char addr
[INET6_ADDRSTRLEN
];
10236 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
10238 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
10239 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
10242 remove_duplicate_addrs2_test_strings_result
[i
]);
10247 printf("run_local_remove_duplicate_addrs2: success\n");
10251 static bool run_local_tdb_opener(int dummy
)
10257 t
= tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST
,
10258 O_RDWR
|O_CREAT
, 0755);
10260 perror("tdb_open failed");
10271 static bool run_local_tdb_writer(int dummy
)
10277 t
= tdb_open("test.tdb", 1000, 0, O_RDWR
|O_CREAT
, 0755);
10279 perror("tdb_open failed");
10283 val
.dptr
= (uint8_t *)&v
;
10284 val
.dsize
= sizeof(v
);
10290 ret
= tdb_store(t
, val
, val
, 0);
10292 printf("%s\n", tdb_errorstr(t
));
10297 data
= tdb_fetch(t
, val
);
10298 if (data
.dptr
!= NULL
) {
10299 SAFE_FREE(data
.dptr
);
10305 static double create_procs(bool (*fn
)(int), bool *result
)
10308 volatile pid_t
*child_status
;
10309 volatile bool *child_status_out
;
10312 struct timeval start
;
10316 child_status
= (volatile pid_t
*)anonymous_shared_allocate(sizeof(pid_t
)*torture_nprocs
);
10317 if (!child_status
) {
10318 printf("Failed to setup shared memory\n");
10322 child_status_out
= (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs
);
10323 if (!child_status_out
) {
10324 printf("Failed to setup result status shared memory\n");
10328 for (i
= 0; i
< torture_nprocs
; i
++) {
10329 child_status
[i
] = 0;
10330 child_status_out
[i
] = True
;
10333 start
= timeval_current();
10335 for (i
=0;i
<torture_nprocs
;i
++) {
10338 pid_t mypid
= getpid();
10339 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
10341 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
10344 if (torture_open_connection(¤t_cli
, i
)) break;
10345 if (tries
-- == 0) {
10346 printf("pid %d failed to start\n", (int)getpid());
10352 child_status
[i
] = getpid();
10354 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
10356 child_status_out
[i
] = fn(i
);
10363 for (i
=0;i
<torture_nprocs
;i
++) {
10364 if (child_status
[i
]) synccount
++;
10366 if (synccount
== torture_nprocs
) break;
10368 } while (timeval_elapsed(&start
) < 30);
10370 if (synccount
!= torture_nprocs
) {
10371 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
10373 return timeval_elapsed(&start
);
10376 /* start the client load */
10377 start
= timeval_current();
10379 for (i
=0;i
<torture_nprocs
;i
++) {
10380 child_status
[i
] = 0;
10383 printf("%d clients started\n", torture_nprocs
);
10385 for (i
=0;i
<torture_nprocs
;i
++) {
10386 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
10391 for (i
=0;i
<torture_nprocs
;i
++) {
10392 if (!child_status_out
[i
]) {
10396 return timeval_elapsed(&start
);
10399 #define FLAG_MULTIPROC 1
10405 } torture_ops
[] = {
10406 {"FDPASS", run_fdpasstest
, 0},
10407 {"LOCK1", run_locktest1
, 0},
10408 {"LOCK2", run_locktest2
, 0},
10409 {"LOCK3", run_locktest3
, 0},
10410 {"LOCK4", run_locktest4
, 0},
10411 {"LOCK5", run_locktest5
, 0},
10412 {"LOCK6", run_locktest6
, 0},
10413 {"LOCK7", run_locktest7
, 0},
10414 {"LOCK8", run_locktest8
, 0},
10415 {"LOCK9", run_locktest9
, 0},
10416 {"UNLINK", run_unlinktest
, 0},
10417 {"BROWSE", run_browsetest
, 0},
10418 {"ATTR", run_attrtest
, 0},
10419 {"TRANS2", run_trans2test
, 0},
10420 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
10421 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
10422 {"RANDOMIPC", run_randomipc
, 0},
10423 {"NEGNOWAIT", run_negprot_nowait
, 0},
10424 {"NBENCH", run_nbench
, 0},
10425 {"NBENCH2", run_nbench2
, 0},
10426 {"OPLOCK1", run_oplock1
, 0},
10427 {"OPLOCK2", run_oplock2
, 0},
10428 {"OPLOCK4", run_oplock4
, 0},
10429 {"DIR", run_dirtest
, 0},
10430 {"DIR1", run_dirtest1
, 0},
10431 {"DIR-CREATETIME", run_dir_createtime
, 0},
10432 {"DENY1", torture_denytest1
, 0},
10433 {"DENY2", torture_denytest2
, 0},
10434 {"TCON", run_tcon_test
, 0},
10435 {"TCONDEV", run_tcon_devtype_test
, 0},
10436 {"RW1", run_readwritetest
, 0},
10437 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
10438 {"RW3", run_readwritelarge
, 0},
10439 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
10440 {"OPEN", run_opentest
, 0},
10441 {"POSIX", run_simple_posix_open_test
, 0},
10442 {"POSIX-APPEND", run_posix_append
, 0},
10443 {"POSIX-SYMLINK-ACL", run_acl_symlink_test
, 0},
10444 {"POSIX-SYMLINK-EA", run_ea_symlink_test
, 0},
10445 {"POSIX-STREAM-DELETE", run_posix_stream_delete
, 0},
10446 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test
, 0},
10447 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
10448 {"ASYNC-ECHO", run_async_echo
, 0},
10449 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
10450 { "SHORTNAME-TEST", run_shortname_test
, 0},
10451 { "ADDRCHANGE", run_addrchange
, 0},
10453 {"OPENATTR", run_openattrtest
, 0},
10455 {"XCOPY", run_xcopy
, 0},
10456 {"RENAME", run_rename
, 0},
10457 {"DELETE", run_deletetest
, 0},
10458 {"WILDDELETE", run_wild_deletetest
, 0},
10459 {"DELETE-LN", run_deletetest_ln
, 0},
10460 {"PROPERTIES", run_properties
, 0},
10461 {"MANGLE", torture_mangle
, 0},
10462 {"MANGLE1", run_mangle1
, 0},
10463 {"W2K", run_w2ktest
, 0},
10464 {"TRANS2SCAN", torture_trans2_scan
, 0},
10465 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
10466 {"UTABLE", torture_utable
, 0},
10467 {"CASETABLE", torture_casetable
, 0},
10468 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
10469 {"PIPE_NUMBER", run_pipe_number
, 0},
10470 {"TCON2", run_tcon2_test
, 0},
10471 {"IOCTL", torture_ioctl_test
, 0},
10472 {"CHKPATH", torture_chkpath_test
, 0},
10473 {"FDSESS", run_fdsesstest
, 0},
10474 { "EATEST", run_eatest
, 0},
10475 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
10476 { "CHAIN1", run_chain1
, 0},
10477 { "CHAIN2", run_chain2
, 0},
10478 { "CHAIN3", run_chain3
, 0},
10479 { "WINDOWS-WRITE", run_windows_write
, 0},
10480 { "LARGE_READX", run_large_readx
, 0},
10481 { "NTTRANS-CREATE", run_nttrans_create
, 0},
10482 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
10483 { "CLI_ECHO", run_cli_echo
, 0},
10484 { "GETADDRINFO", run_getaddrinfo_send
, 0},
10485 { "TLDAP", run_tldap
},
10486 { "STREAMERROR", run_streamerror
},
10487 { "NOTIFY-BENCH", run_notify_bench
},
10488 { "NOTIFY-BENCH2", run_notify_bench2
},
10489 { "NOTIFY-BENCH3", run_notify_bench3
},
10490 { "BAD-NBT-SESSION", run_bad_nbt_session
},
10491 { "SMB-ANY-CONNECT", run_smb_any_connect
},
10492 { "NOTIFY-ONLINE", run_notify_online
},
10493 { "SMB2-BASIC", run_smb2_basic
},
10494 { "SMB2-NEGPROT", run_smb2_negprot
},
10495 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
10496 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
10497 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
10498 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
10499 { "CLEANUP1", run_cleanup1
},
10500 { "CLEANUP2", run_cleanup2
},
10501 { "CLEANUP3", run_cleanup3
},
10502 { "CLEANUP4", run_cleanup4
},
10503 { "OPLOCK-CANCEL", run_oplock_cancel
},
10504 { "PIDHIGH", run_pidhigh
},
10505 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
10506 { "LOCAL-GENCACHE", run_local_gencache
, 0},
10507 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
10508 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
10509 { "LOCAL-MESSAGING-READ1", run_messaging_read1
, 0 },
10510 { "LOCAL-MESSAGING-READ2", run_messaging_read2
, 0 },
10511 { "LOCAL-MESSAGING-READ3", run_messaging_read3
, 0 },
10512 { "LOCAL-MESSAGING-READ4", run_messaging_read4
, 0 },
10513 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1
, 0 },
10514 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2
, 0 },
10515 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a
, 0 },
10516 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b
, 0 },
10517 { "LOCAL-BASE64", run_local_base64
, 0},
10518 { "LOCAL-RBTREE", run_local_rbtree
, 0},
10519 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
10520 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
10521 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping
, 0},
10522 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
10523 { "LOCAL-sid_to_string", run_local_sid_to_string
, 0},
10524 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
10525 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
10526 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
10527 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
10528 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
10529 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
10530 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
10531 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
10532 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
10533 { "local-tdb-opener", run_local_tdb_opener
, 0 },
10534 { "local-tdb-writer", run_local_tdb_writer
, 0 },
10535 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb
, 0 },
10536 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool
, 0 },
10537 { "qpathinfo-bufsize", run_qpathinfo_bufsize
, 0 },
10541 * dummy function to satisfy linker dependency
10543 struct tevent_context
*winbind_event_context(void);
10544 struct tevent_context
*winbind_event_context(void)
10549 /****************************************************************************
10550 run a specified test or "ALL"
10551 ****************************************************************************/
10552 static bool run_test(const char *name
)
10555 bool result
= True
;
10556 bool found
= False
;
10559 if (strequal(name
,"ALL")) {
10560 for (i
=0;torture_ops
[i
].name
;i
++) {
10561 run_test(torture_ops
[i
].name
);
10566 for (i
=0;torture_ops
[i
].name
;i
++) {
10567 fstr_sprintf(randomfname
, "\\XX%x",
10568 (unsigned)random());
10570 if (strequal(name
, torture_ops
[i
].name
)) {
10572 printf("Running %s\n", name
);
10573 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
10574 t
= create_procs(torture_ops
[i
].fn
, &result
);
10577 printf("TEST %s FAILED!\n", name
);
10580 struct timeval start
;
10581 start
= timeval_current();
10582 if (!torture_ops
[i
].fn(0)) {
10584 printf("TEST %s FAILED!\n", name
);
10586 t
= timeval_elapsed(&start
);
10588 printf("%s took %g secs\n\n", name
, t
);
10593 printf("Did not find a test named %s\n", name
);
10601 static void usage(void)
10605 printf("WARNING samba4 test suite is much more complete nowadays.\n");
10606 printf("Please use samba4 torture.\n\n");
10608 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
10610 printf("\t-d debuglevel\n");
10611 printf("\t-U user%%pass\n");
10612 printf("\t-k use kerberos\n");
10613 printf("\t-N numprocs\n");
10614 printf("\t-n my_netbios_name\n");
10615 printf("\t-W workgroup\n");
10616 printf("\t-o num_operations\n");
10617 printf("\t-O socket_options\n");
10618 printf("\t-m maximum protocol\n");
10619 printf("\t-L use oplocks\n");
10620 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
10621 printf("\t-A showall\n");
10622 printf("\t-p port\n");
10623 printf("\t-s seed\n");
10624 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
10625 printf("\t-f filename filename to test\n");
10626 printf("\t-e encrypt\n");
10629 printf("tests are:");
10630 for (i
=0;torture_ops
[i
].name
;i
++) {
10631 printf(" %s", torture_ops
[i
].name
);
10635 printf("default test is ALL\n");
10640 /****************************************************************************
10642 ****************************************************************************/
10643 int main(int argc
,char *argv
[])
10649 bool correct
= True
;
10650 TALLOC_CTX
*frame
= talloc_stackframe();
10651 int seed
= time(NULL
);
10653 #ifdef HAVE_SETBUFFER
10654 setbuffer(stdout
, NULL
, 0);
10657 setup_logging("smbtorture", DEBUG_STDOUT
);
10662 if (is_default_dyn_CONFIGFILE()) {
10663 if(getenv("SMB_CONF_PATH")) {
10664 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
10667 lp_load_global(get_dyn_CONFIGFILE());
10674 for(p
= argv
[1]; *p
; p
++)
10678 if (strncmp(argv
[1], "//", 2)) {
10682 fstrcpy(host
, &argv
[1][2]);
10683 p
= strchr_m(&host
[2],'/');
10688 fstrcpy(share
, p
+1);
10690 fstrcpy(myname
, get_myname(talloc_tos()));
10692 fprintf(stderr
, "Failed to get my hostname.\n");
10696 if (*username
== 0 && getenv("LOGNAME")) {
10697 fstrcpy(username
,getenv("LOGNAME"));
10703 fstrcpy(workgroup
, lp_workgroup());
10705 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
10709 port_to_use
= atoi(optarg
);
10712 seed
= atoi(optarg
);
10715 fstrcpy(workgroup
,optarg
);
10718 lp_set_cmdline("client max protocol", optarg
);
10721 torture_nprocs
= atoi(optarg
);
10724 torture_numops
= atoi(optarg
);
10727 lp_set_cmdline("log level", optarg
);
10733 use_oplocks
= True
;
10736 local_path
= optarg
;
10739 torture_showall
= True
;
10742 fstrcpy(myname
, optarg
);
10745 client_txt
= optarg
;
10752 use_kerberos
= True
;
10754 d_printf("No kerberos support compiled in\n");
10760 fstrcpy(username
,optarg
);
10761 p
= strchr_m(username
,'%');
10764 fstrcpy(password
, p
+1);
10769 fstrcpy(multishare_conn_fname
, optarg
);
10770 use_multishare_conn
= True
;
10773 torture_blocksize
= atoi(optarg
);
10776 test_filename
= SMB_STRDUP(optarg
);
10779 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
10784 d_printf("using seed %d\n", seed
);
10788 if(use_kerberos
&& !gotuser
) gotpass
= True
;
10791 char pwd
[256] = {0};
10794 rc
= samba_getpass("Password:", pwd
, sizeof(pwd
), false, false);
10796 fstrcpy(password
, pwd
);
10801 printf("host=%s share=%s user=%s myname=%s\n",
10802 host
, share
, username
, myname
);
10804 if (argc
== optind
) {
10805 correct
= run_test("ALL");
10807 for (i
=optind
;i
<argc
;i
++) {
10808 if (!run_test(argv
[i
])) {
10814 TALLOC_FREE(frame
);