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 "libsmb/namequery.h"
24 #include "wbc_async.h"
25 #include "torture/proto.h"
26 #include "libcli/security/security.h"
28 #include "tldap_util.h"
29 #include "../librpc/gen_ndr/svcctl.h"
30 #include "../lib/util/memcache.h"
31 #include "nsswitch/winbind_client.h"
32 #include "dbwrap/dbwrap.h"
33 #include "dbwrap/dbwrap_open.h"
34 #include "dbwrap/dbwrap_rbt.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"
46 #include "lib/util/time.h"
47 #include "lib/crypto/md5.h"
48 #include "lib/gencache.h"
53 fstring host
, workgroup
, share
, password
, username
, myname
;
54 struct cli_credentials
*torture_creds
;
55 static const char *sockops
="TCP_NODELAY";
57 static int port_to_use
=0;
58 int torture_numops
=100;
59 int torture_blocksize
=1024*1024;
60 static int procnum
; /* records process count number when forking */
61 static struct cli_state
*current_cli
;
62 static fstring randomfname
;
63 static bool use_oplocks
;
64 static bool use_level_II_oplocks
;
65 static const char *client_txt
= "client_oplocks.txt";
66 static bool disable_spnego
;
67 static bool use_kerberos
;
68 static bool force_dos_errors
;
69 static fstring multishare_conn_fname
;
70 static bool use_multishare_conn
= False
;
71 static bool do_encrypt
;
72 static const char *local_path
= NULL
;
73 static enum smb_signing_setting signing_state
= SMB_SIGNING_DEFAULT
;
76 bool torture_showall
= False
;
78 static double create_procs(bool (*fn
)(int), bool *result
);
80 /********************************************************************
81 Ensure a connection is encrypted.
82 ********************************************************************/
84 static bool force_cli_encryption(struct cli_state
*c
,
85 const char *sharename
)
87 uint16_t major
, minor
;
88 uint32_t caplow
, caphigh
;
91 if (!SERVER_HAS_UNIX_CIFS(c
)) {
92 d_printf("Encryption required and "
93 "server that doesn't support "
94 "UNIX extensions - failing connect\n");
98 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
100 if (!NT_STATUS_IS_OK(status
)) {
101 d_printf("Encryption required and "
102 "can't get UNIX CIFS extensions "
103 "version from server: %s\n", nt_errstr(status
));
107 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
108 d_printf("Encryption required and "
109 "share %s doesn't support "
110 "encryption.\n", sharename
);
114 status
= cli_smb1_setup_encryption(c
, torture_creds
);
115 if (!NT_STATUS_IS_OK(status
)) {
116 d_printf("Encryption required and "
117 "setup failed with error %s.\n",
126 static struct cli_state
*open_nbt_connection(void)
132 if (disable_spnego
) {
133 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
137 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
140 if (use_level_II_oplocks
) {
141 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
145 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
148 if (force_dos_errors
) {
149 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
152 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
153 signing_state
, flags
, &c
);
154 if (!NT_STATUS_IS_OK(status
)) {
155 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
159 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
164 /****************************************************************************
165 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
166 ****************************************************************************/
168 static bool cli_bad_session_request(int fd
,
169 struct nmb_name
*calling
, struct nmb_name
*called
)
178 uint8_t message_type
;
180 struct tevent_context
*ev
;
181 struct tevent_req
*req
;
183 frame
= talloc_stackframe();
185 iov
[0].iov_base
= len_buf
;
186 iov
[0].iov_len
= sizeof(len_buf
);
188 /* put in the destination name */
190 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
192 if (iov
[1].iov_base
== NULL
) {
195 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
196 talloc_get_size(iov
[1].iov_base
));
200 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
202 if (iov
[2].iov_base
== NULL
) {
205 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
206 talloc_get_size(iov
[2].iov_base
));
208 /* Deliberately corrupt the name len (first byte) */
209 *((uint8_t *)iov
[2].iov_base
) = 100;
211 /* send a session request (RFC 1002) */
212 /* setup the packet length
213 * Remove four bytes from the length count, since the length
214 * field in the NBT Session Service header counts the number
215 * of bytes which follow. The cli_send_smb() function knows
216 * about this and accounts for those four bytes.
220 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
221 SCVAL(len_buf
,0,0x81);
223 len
= write_data_iov(fd
, iov
, 3);
228 ev
= samba_tevent_context_init(frame
);
232 req
= read_smb_send(frame
, ev
, fd
);
236 if (!tevent_req_poll(req
, ev
)) {
239 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
246 message_type
= CVAL(inbuf
, 0);
247 if (message_type
!= 0x83) {
248 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
253 if (smb_len(inbuf
) != 1) {
254 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
255 (int)smb_len(inbuf
));
259 error
= CVAL(inbuf
, 4);
261 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
272 /* Insert a NULL at the first separator of the given path and return a pointer
273 * to the remainder of the string.
276 terminate_path_at_separator(char * path
)
284 if ((p
= strchr_m(path
, '/'))) {
289 if ((p
= strchr_m(path
, '\\'))) {
299 parse a //server/share type UNC name
301 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
302 char **hostname
, char **sharename
)
306 *hostname
= *sharename
= NULL
;
308 if (strncmp(unc_name
, "\\\\", 2) &&
309 strncmp(unc_name
, "//", 2)) {
313 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
314 p
= terminate_path_at_separator(*hostname
);
317 *sharename
= talloc_strdup(mem_ctx
, p
);
318 terminate_path_at_separator(*sharename
);
321 if (*hostname
&& *sharename
) {
325 TALLOC_FREE(*hostname
);
326 TALLOC_FREE(*sharename
);
330 static bool torture_open_connection_share(struct cli_state
**c
,
331 const char *hostname
,
332 const char *sharename
,
337 status
= cli_full_connection_creds(c
,
347 if (!NT_STATUS_IS_OK(status
)) {
348 printf("failed to open share connection: //%s/%s port:%d - %s\n",
349 hostname
, sharename
, port_to_use
, nt_errstr(status
));
353 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
356 return force_cli_encryption(*c
,
362 bool torture_open_connection_flags(struct cli_state
**c
, int conn_index
, int flags
)
364 char **unc_list
= NULL
;
365 int num_unc_names
= 0;
368 if (use_multishare_conn
==True
) {
370 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
371 if (!unc_list
|| num_unc_names
<= 0) {
372 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
376 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
378 printf("Failed to parse UNC name %s\n",
379 unc_list
[conn_index
% num_unc_names
]);
380 TALLOC_FREE(unc_list
);
384 result
= torture_open_connection_share(c
, h
, s
, flags
);
386 /* h, s were copied earlier */
387 TALLOC_FREE(unc_list
);
391 return torture_open_connection_share(c
, host
, share
, flags
);
394 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
396 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
399 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
401 if (use_level_II_oplocks
) {
402 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
405 return torture_open_connection_flags(c
, conn_index
, flags
);
408 bool torture_init_connection(struct cli_state
**pcli
)
410 struct cli_state
*cli
;
412 cli
= open_nbt_connection();
421 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16_t *new_vuid
)
423 uint16_t old_vuid
= cli_state_get_uid(cli
);
427 cli_state_set_uid(cli
, 0);
428 status
= cli_session_setup_creds(cli
, torture_creds
);
429 ret
= NT_STATUS_IS_OK(status
);
430 *new_vuid
= cli_state_get_uid(cli
);
431 cli_state_set_uid(cli
, old_vuid
);
436 bool torture_close_connection(struct cli_state
*c
)
441 status
= cli_tdis(c
);
442 if (!NT_STATUS_IS_OK(status
)) {
443 printf("tdis failed (%s)\n", nt_errstr(status
));
453 /* check if the server produced the expected dos or nt error code */
454 static bool check_both_error(int line
, NTSTATUS status
,
455 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
457 if (NT_STATUS_IS_DOS(status
)) {
461 /* Check DOS error */
462 cclass
= NT_STATUS_DOS_CLASS(status
);
463 num
= NT_STATUS_DOS_CODE(status
);
465 if (eclass
!= cclass
|| ecode
!= num
) {
466 printf("unexpected error code class=%d code=%d\n",
467 (int)cclass
, (int)num
);
468 printf(" expected %d/%d %s (line=%d)\n",
469 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
474 if (!NT_STATUS_EQUAL(nterr
, status
)) {
475 printf("unexpected error code %s\n",
477 printf(" expected %s (line=%d)\n",
478 nt_errstr(nterr
), line
);
487 /* check if the server produced the expected error code */
488 static bool check_error(int line
, NTSTATUS status
,
489 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
491 if (NT_STATUS_IS_DOS(status
)) {
495 /* Check DOS error */
497 cclass
= NT_STATUS_DOS_CLASS(status
);
498 num
= NT_STATUS_DOS_CODE(status
);
500 if (eclass
!= cclass
|| ecode
!= num
) {
501 printf("unexpected error code class=%d code=%d\n",
502 (int)cclass
, (int)num
);
503 printf(" expected %d/%d %s (line=%d)\n",
504 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
512 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
513 printf("unexpected error code %s\n",
515 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
525 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
529 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
531 while (!NT_STATUS_IS_OK(status
)) {
532 if (!check_both_error(__LINE__
, status
, ERRDOS
,
533 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
537 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
544 static bool rw_torture(struct cli_state
*c
)
546 const char *lockfname
= "\\torture.lck";
550 pid_t pid2
, pid
= getpid();
557 memset(buf
, '\0', sizeof(buf
));
559 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
561 if (!NT_STATUS_IS_OK(status
)) {
562 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
564 if (!NT_STATUS_IS_OK(status
)) {
565 printf("open of %s failed (%s)\n",
566 lockfname
, nt_errstr(status
));
570 for (i
=0;i
<torture_numops
;i
++) {
571 unsigned n
= (unsigned)sys_random()%10;
574 printf("%d\r", i
); fflush(stdout
);
576 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
578 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
582 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
584 if (!NT_STATUS_IS_OK(status
)) {
585 printf("open failed (%s)\n", nt_errstr(status
));
590 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
592 if (!NT_STATUS_IS_OK(status
)) {
593 printf("write failed (%s)\n", nt_errstr(status
));
598 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
599 sizeof(pid
)+(j
*sizeof(buf
)),
601 if (!NT_STATUS_IS_OK(status
)) {
602 printf("write failed (%s)\n",
610 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
612 if (!NT_STATUS_IS_OK(status
)) {
613 printf("read failed (%s)\n", nt_errstr(status
));
615 } else if (nread
!= sizeof(pid
)) {
616 printf("read/write compare failed: "
617 "recv %ld req %ld\n", (unsigned long)nread
,
618 (unsigned long)sizeof(pid
));
623 printf("data corruption!\n");
627 status
= cli_close(c
, fnum
);
628 if (!NT_STATUS_IS_OK(status
)) {
629 printf("close failed (%s)\n", nt_errstr(status
));
633 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
634 if (!NT_STATUS_IS_OK(status
)) {
635 printf("unlink failed (%s)\n", nt_errstr(status
));
639 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
640 if (!NT_STATUS_IS_OK(status
)) {
641 printf("unlock failed (%s)\n", nt_errstr(status
));
647 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
654 static bool run_torture(int dummy
)
656 struct cli_state
*cli
;
661 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
663 ret
= rw_torture(cli
);
665 if (!torture_close_connection(cli
)) {
672 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
674 uint16_t fnum
= (uint16_t)-1;
679 unsigned countprev
= 0;
682 NTSTATUS status
= NT_STATUS_OK
;
685 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32_t))
687 SIVAL(buf
, i
, sys_random());
694 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
695 if (!NT_STATUS_IS_OK(status
)) {
696 printf("unlink failed (%s) (normal, this file should "
697 "not exist)\n", nt_errstr(status
));
700 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
702 if (!NT_STATUS_IS_OK(status
)) {
703 printf("first open read/write of %s failed (%s)\n",
704 lockfname
, nt_errstr(status
));
710 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
712 status
= cli_openx(c
, lockfname
, O_RDONLY
,
714 if (NT_STATUS_IS_OK(status
)) {
719 if (!NT_STATUS_IS_OK(status
)) {
720 printf("second open read-only of %s failed (%s)\n",
721 lockfname
, nt_errstr(status
));
727 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
729 if (count
>= countprev
) {
730 printf("%d %8d\r", i
, count
);
733 countprev
+= (sizeof(buf
) / 20);
738 sent
= ((unsigned)sys_random()%(20))+ 1;
739 if (sent
> sizeof(buf
) - count
)
741 sent
= sizeof(buf
) - count
;
744 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
746 if (!NT_STATUS_IS_OK(status
)) {
747 printf("write failed (%s)\n",
754 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
755 sizeof(buf
)-count
, &sent
);
756 if(!NT_STATUS_IS_OK(status
)) {
757 printf("read failed offset:%d size:%ld (%s)\n",
758 count
, (unsigned long)sizeof(buf
)-count
,
762 } else if (sent
> 0) {
763 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
765 printf("read/write compare failed\n");
766 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
775 status
= cli_close(c
, fnum
);
776 if (!NT_STATUS_IS_OK(status
)) {
777 printf("close failed (%s)\n", nt_errstr(status
));
784 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
786 const char *lockfname
= "\\torture2.lck";
796 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
797 if (!NT_STATUS_IS_OK(status
)) {
798 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
801 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
803 if (!NT_STATUS_IS_OK(status
)) {
804 printf("first open read/write of %s failed (%s)\n",
805 lockfname
, nt_errstr(status
));
809 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
810 if (!NT_STATUS_IS_OK(status
)) {
811 printf("second open read-only of %s failed (%s)\n",
812 lockfname
, nt_errstr(status
));
813 cli_close(c1
, fnum1
);
817 for (i
= 0; i
< torture_numops
; i
++)
819 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
821 printf("%d\r", i
); fflush(stdout
);
824 generate_random_buffer((unsigned char *)buf
, buf_size
);
826 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
828 if (!NT_STATUS_IS_OK(status
)) {
829 printf("write failed (%s)\n", nt_errstr(status
));
834 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
835 if(!NT_STATUS_IS_OK(status
)) {
836 printf("read failed (%s)\n", nt_errstr(status
));
839 } else if (bytes_read
!= buf_size
) {
840 printf("read failed\n");
841 printf("read %ld, expected %ld\n",
842 (unsigned long)bytes_read
,
843 (unsigned long)buf_size
);
848 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
850 printf("read/write compare failed\n");
856 status
= cli_close(c2
, fnum2
);
857 if (!NT_STATUS_IS_OK(status
)) {
858 printf("close failed (%s)\n", nt_errstr(status
));
862 status
= cli_close(c1
, fnum1
);
863 if (!NT_STATUS_IS_OK(status
)) {
864 printf("close failed (%s)\n", nt_errstr(status
));
868 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
869 if (!NT_STATUS_IS_OK(status
)) {
870 printf("unlink failed (%s)\n", nt_errstr(status
));
877 static bool run_readwritetest(int dummy
)
879 struct cli_state
*cli1
, *cli2
;
880 bool test1
, test2
= False
;
882 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
885 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
886 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
888 printf("starting readwritetest\n");
890 test1
= rw_torture2(cli1
, cli2
);
891 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
894 test2
= rw_torture2(cli1
, cli1
);
895 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
898 if (!torture_close_connection(cli1
)) {
902 if (!torture_close_connection(cli2
)) {
906 return (test1
&& test2
);
909 static bool run_readwritemulti(int dummy
)
911 struct cli_state
*cli
;
916 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
918 printf("run_readwritemulti: fname %s\n", randomfname
);
919 test
= rw_torture3(cli
, randomfname
);
921 if (!torture_close_connection(cli
)) {
928 static bool run_readwritelarge_internal(void)
930 static struct cli_state
*cli1
;
932 const char *lockfname
= "\\large.dat";
938 if (!torture_open_connection(&cli1
, 0)) {
941 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
942 memset(buf
,'\0',sizeof(buf
));
944 printf("starting readwritelarge_internal\n");
946 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
948 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
950 if (!NT_STATUS_IS_OK(status
)) {
951 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
955 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
957 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
959 if (!NT_STATUS_IS_OK(status
)) {
960 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
964 if (fsize
== sizeof(buf
))
965 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
966 (unsigned long)fsize
);
968 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
969 (unsigned long)fsize
);
973 status
= cli_close(cli1
, fnum1
);
974 if (!NT_STATUS_IS_OK(status
)) {
975 printf("close failed (%s)\n", nt_errstr(status
));
979 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
980 if (!NT_STATUS_IS_OK(status
)) {
981 printf("unlink failed (%s)\n", nt_errstr(status
));
985 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
987 if (!NT_STATUS_IS_OK(status
)) {
988 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
992 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
994 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
996 if (!NT_STATUS_IS_OK(status
)) {
997 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1001 if (fsize
== sizeof(buf
))
1002 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1003 (unsigned long)fsize
);
1005 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1006 (unsigned long)fsize
);
1011 /* ToDo - set allocation. JRA */
1012 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1013 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1016 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1018 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1022 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1025 status
= cli_close(cli1
, fnum1
);
1026 if (!NT_STATUS_IS_OK(status
)) {
1027 printf("close failed (%s)\n", nt_errstr(status
));
1031 if (!torture_close_connection(cli1
)) {
1037 static bool run_readwritelarge(int dummy
)
1039 return run_readwritelarge_internal();
1042 static bool run_readwritelarge_signtest(int dummy
)
1045 signing_state
= SMB_SIGNING_REQUIRED
;
1046 ret
= run_readwritelarge_internal();
1047 signing_state
= SMB_SIGNING_DEFAULT
;
1054 #define ival(s) strtol(s, NULL, 0)
1056 /* run a test that simulates an approximate netbench client load */
1057 static bool run_netbench(int client
)
1059 struct cli_state
*cli
;
1064 const char *params
[20];
1065 bool correct
= True
;
1071 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1075 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1077 f
= fopen(client_txt
, "r");
1084 while (fgets(line
, sizeof(line
)-1, f
)) {
1088 line
[strlen(line
)-1] = 0;
1090 /* printf("[%d] %s\n", line_count, line); */
1092 all_string_sub(line
,"client1", cname
, sizeof(line
));
1094 /* parse the command parameters */
1095 params
[0] = strtok_r(line
, " ", &saveptr
);
1097 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1101 if (i
< 2) continue;
1103 if (!strncmp(params
[0],"SMB", 3)) {
1104 printf("ERROR: You are using a dbench 1 load file\n");
1108 if (!strcmp(params
[0],"NTCreateX")) {
1109 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1111 } else if (!strcmp(params
[0],"Close")) {
1112 nb_close(ival(params
[1]));
1113 } else if (!strcmp(params
[0],"Rename")) {
1114 nb_rename(params
[1], params
[2]);
1115 } else if (!strcmp(params
[0],"Unlink")) {
1116 nb_unlink(params
[1]);
1117 } else if (!strcmp(params
[0],"Deltree")) {
1118 nb_deltree(params
[1]);
1119 } else if (!strcmp(params
[0],"Rmdir")) {
1120 nb_rmdir(params
[1]);
1121 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1122 nb_qpathinfo(params
[1]);
1123 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1124 nb_qfileinfo(ival(params
[1]));
1125 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1126 nb_qfsinfo(ival(params
[1]));
1127 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1128 nb_findfirst(params
[1]);
1129 } else if (!strcmp(params
[0],"WriteX")) {
1130 nb_writex(ival(params
[1]),
1131 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1132 } else if (!strcmp(params
[0],"ReadX")) {
1133 nb_readx(ival(params
[1]),
1134 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1135 } else if (!strcmp(params
[0],"Flush")) {
1136 nb_flush(ival(params
[1]));
1138 printf("Unknown operation %s\n", params
[0]);
1146 if (!torture_close_connection(cli
)) {
1154 /* run a test that simulates an approximate netbench client load */
1155 static bool run_nbench(int dummy
)
1158 bool correct
= True
;
1160 nbio_shmem(torture_nprocs
);
1164 signal(SIGALRM
, nb_alarm
);
1166 t
= create_procs(run_netbench
, &correct
);
1169 printf("\nThroughput %g MB/sec\n",
1170 1.0e-6 * nbio_total() / t
);
1176 This test checks for two things:
1178 1) correct support for retaining locks over a close (ie. the server
1179 must not use posix semantics)
1180 2) support for lock timeouts
1182 static bool run_locktest1(int dummy
)
1184 struct cli_state
*cli1
, *cli2
;
1185 const char *fname
= "\\lockt1.lck";
1186 uint16_t fnum1
, fnum2
, fnum3
;
1188 unsigned lock_timeout
;
1191 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1194 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1195 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1197 printf("starting locktest1\n");
1199 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1201 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1208 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1209 if (!NT_STATUS_IS_OK(status
)) {
1210 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1214 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1215 if (!NT_STATUS_IS_OK(status
)) {
1216 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1220 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1221 if (!NT_STATUS_IS_OK(status
)) {
1222 printf("lock1 failed (%s)\n", nt_errstr(status
));
1226 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1227 if (NT_STATUS_IS_OK(status
)) {
1228 printf("lock2 succeeded! This is a locking bug\n");
1231 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1232 NT_STATUS_LOCK_NOT_GRANTED
)) {
1237 lock_timeout
= (1 + (random() % 20));
1238 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1240 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1241 if (NT_STATUS_IS_OK(status
)) {
1242 printf("lock3 succeeded! This is a locking bug\n");
1245 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1246 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1252 if (ABS(t2
- t1
) < lock_timeout
-1) {
1253 printf("error: This server appears not to support timed lock requests\n");
1256 printf("server slept for %u seconds for a %u second timeout\n",
1257 (unsigned int)(t2
-t1
), lock_timeout
);
1259 status
= cli_close(cli1
, fnum2
);
1260 if (!NT_STATUS_IS_OK(status
)) {
1261 printf("close1 failed (%s)\n", nt_errstr(status
));
1265 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1266 if (NT_STATUS_IS_OK(status
)) {
1267 printf("lock4 succeeded! This is a locking bug\n");
1270 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1271 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1276 status
= cli_close(cli1
, fnum1
);
1277 if (!NT_STATUS_IS_OK(status
)) {
1278 printf("close2 failed (%s)\n", nt_errstr(status
));
1282 status
= cli_close(cli2
, fnum3
);
1283 if (!NT_STATUS_IS_OK(status
)) {
1284 printf("close3 failed (%s)\n", nt_errstr(status
));
1288 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1289 if (!NT_STATUS_IS_OK(status
)) {
1290 printf("unlink failed (%s)\n", nt_errstr(status
));
1295 if (!torture_close_connection(cli1
)) {
1299 if (!torture_close_connection(cli2
)) {
1303 printf("Passed locktest1\n");
1308 this checks to see if a secondary tconx can use open files from an
1311 static bool run_tcon_test(int dummy
)
1313 static struct cli_state
*cli
;
1314 const char *fname
= "\\tcontest.tmp";
1316 uint32_t cnum1
, cnum2
, cnum3
;
1317 struct smbXcli_tcon
*orig_tcon
= NULL
;
1318 uint16_t vuid1
, vuid2
;
1323 memset(buf
, '\0', sizeof(buf
));
1325 if (!torture_open_connection(&cli
, 0)) {
1328 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1330 printf("starting tcontest\n");
1332 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1334 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1335 if (!NT_STATUS_IS_OK(status
)) {
1336 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1340 cnum1
= cli_state_get_tid(cli
);
1341 vuid1
= cli_state_get_uid(cli
);
1343 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1344 if (!NT_STATUS_IS_OK(status
)) {
1345 printf("initial write failed (%s)", nt_errstr(status
));
1349 orig_tcon
= cli_state_save_tcon(cli
);
1350 if (orig_tcon
== NULL
) {
1354 status
= cli_tree_connect_creds(cli
, share
, "?????", torture_creds
);
1355 if (!NT_STATUS_IS_OK(status
)) {
1356 printf("%s refused 2nd tree connect (%s)\n", host
,
1362 cnum2
= cli_state_get_tid(cli
);
1363 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1364 vuid2
= cli_state_get_uid(cli
) + 1;
1366 /* try a write with the wrong tid */
1367 cli_state_set_tid(cli
, cnum2
);
1369 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1370 if (NT_STATUS_IS_OK(status
)) {
1371 printf("* server allows write with wrong TID\n");
1374 printf("server fails write with wrong TID : %s\n",
1379 /* try a write with an invalid tid */
1380 cli_state_set_tid(cli
, cnum3
);
1382 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1383 if (NT_STATUS_IS_OK(status
)) {
1384 printf("* server allows write with invalid TID\n");
1387 printf("server fails write with invalid TID : %s\n",
1391 /* try a write with an invalid vuid */
1392 cli_state_set_uid(cli
, vuid2
);
1393 cli_state_set_tid(cli
, cnum1
);
1395 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1396 if (NT_STATUS_IS_OK(status
)) {
1397 printf("* server allows write with invalid VUID\n");
1400 printf("server fails write with invalid VUID : %s\n",
1404 cli_state_set_tid(cli
, cnum1
);
1405 cli_state_set_uid(cli
, vuid1
);
1407 status
= cli_close(cli
, fnum1
);
1408 if (!NT_STATUS_IS_OK(status
)) {
1409 printf("close failed (%s)\n", nt_errstr(status
));
1413 cli_state_set_tid(cli
, cnum2
);
1415 status
= cli_tdis(cli
);
1416 if (!NT_STATUS_IS_OK(status
)) {
1417 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1421 cli_state_restore_tcon(cli
, orig_tcon
);
1423 cli_state_set_tid(cli
, cnum1
);
1425 if (!torture_close_connection(cli
)) {
1434 checks for old style tcon support
1436 static bool run_tcon2_test(int dummy
)
1438 static struct cli_state
*cli
;
1439 uint16_t cnum
, max_xmit
;
1443 if (!torture_open_connection(&cli
, 0)) {
1446 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1448 printf("starting tcon2 test\n");
1450 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1454 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1458 if (!NT_STATUS_IS_OK(status
)) {
1459 printf("tcon2 failed : %s\n", nt_errstr(status
));
1461 printf("tcon OK : max_xmit=%d cnum=%d\n",
1462 (int)max_xmit
, (int)cnum
);
1465 if (!torture_close_connection(cli
)) {
1469 printf("Passed tcon2 test\n");
1473 static bool tcon_devtest(struct cli_state
*cli
,
1474 const char *myshare
, const char *devtype
,
1475 const char *return_devtype
,
1476 NTSTATUS expected_error
)
1481 status
= cli_tree_connect_creds(cli
, myshare
, devtype
, torture_creds
);
1483 if (NT_STATUS_IS_OK(expected_error
)) {
1484 if (NT_STATUS_IS_OK(status
)) {
1485 if (return_devtype
!= NULL
&&
1486 strequal(cli
->dev
, return_devtype
)) {
1489 printf("tconX to share %s with type %s "
1490 "succeeded but returned the wrong "
1491 "device type (got [%s] but should have got [%s])\n",
1492 myshare
, devtype
, cli
->dev
, return_devtype
);
1496 printf("tconX to share %s with type %s "
1497 "should have succeeded but failed\n",
1503 if (NT_STATUS_IS_OK(status
)) {
1504 printf("tconx to share %s with type %s "
1505 "should have failed but succeeded\n",
1509 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1512 printf("Returned unexpected error\n");
1521 checks for correct tconX support
1523 static bool run_tcon_devtype_test(int dummy
)
1525 static struct cli_state
*cli1
= NULL
;
1526 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
1530 status
= cli_full_connection_creds(&cli1
,
1536 NULL
, /* service_type */
1541 if (!NT_STATUS_IS_OK(status
)) {
1542 printf("could not open connection\n");
1546 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1549 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1552 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1555 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1558 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1561 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1564 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1567 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1570 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1573 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1579 printf("Passed tcondevtest\n");
1586 This test checks that
1588 1) the server supports multiple locking contexts on the one SMB
1589 connection, distinguished by PID.
1591 2) the server correctly fails overlapping locks made by the same PID (this
1592 goes against POSIX behaviour, which is why it is tricky to implement)
1594 3) the server denies unlock requests by an incorrect client PID
1596 static bool run_locktest2(int dummy
)
1598 static struct cli_state
*cli
;
1599 const char *fname
= "\\lockt2.lck";
1600 uint16_t fnum1
, fnum2
, fnum3
;
1601 bool correct
= True
;
1604 if (!torture_open_connection(&cli
, 0)) {
1608 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1610 printf("starting locktest2\n");
1612 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1616 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1617 if (!NT_STATUS_IS_OK(status
)) {
1618 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1622 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1623 if (!NT_STATUS_IS_OK(status
)) {
1624 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1630 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1631 if (!NT_STATUS_IS_OK(status
)) {
1632 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1638 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1639 if (!NT_STATUS_IS_OK(status
)) {
1640 printf("lock1 failed (%s)\n", nt_errstr(status
));
1644 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1645 if (NT_STATUS_IS_OK(status
)) {
1646 printf("WRITE lock1 succeeded! This is a locking bug\n");
1649 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1650 NT_STATUS_LOCK_NOT_GRANTED
)) {
1655 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1656 if (NT_STATUS_IS_OK(status
)) {
1657 printf("WRITE lock2 succeeded! This is a locking bug\n");
1660 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1661 NT_STATUS_LOCK_NOT_GRANTED
)) {
1666 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1667 if (NT_STATUS_IS_OK(status
)) {
1668 printf("READ lock2 succeeded! This is a locking bug\n");
1671 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1672 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1677 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1678 if (!NT_STATUS_IS_OK(status
)) {
1679 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1682 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1683 printf("unlock at 100 succeeded! This is a locking bug\n");
1687 status
= cli_unlock(cli
, fnum1
, 0, 4);
1688 if (NT_STATUS_IS_OK(status
)) {
1689 printf("unlock1 succeeded! This is a locking bug\n");
1692 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1693 NT_STATUS_RANGE_NOT_LOCKED
)) {
1698 status
= cli_unlock(cli
, fnum1
, 0, 8);
1699 if (NT_STATUS_IS_OK(status
)) {
1700 printf("unlock2 succeeded! This is a locking bug\n");
1703 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1704 NT_STATUS_RANGE_NOT_LOCKED
)) {
1709 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1710 if (NT_STATUS_IS_OK(status
)) {
1711 printf("lock3 succeeded! This is a locking bug\n");
1714 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1715 NT_STATUS_LOCK_NOT_GRANTED
)) {
1722 status
= cli_close(cli
, fnum1
);
1723 if (!NT_STATUS_IS_OK(status
)) {
1724 printf("close1 failed (%s)\n", nt_errstr(status
));
1728 status
= cli_close(cli
, fnum2
);
1729 if (!NT_STATUS_IS_OK(status
)) {
1730 printf("close2 failed (%s)\n", nt_errstr(status
));
1734 status
= cli_close(cli
, fnum3
);
1735 if (!NT_STATUS_IS_OK(status
)) {
1736 printf("close3 failed (%s)\n", nt_errstr(status
));
1740 if (!torture_close_connection(cli
)) {
1744 printf("locktest2 finished\n");
1751 This test checks that
1753 1) the server supports the full offset range in lock requests
1755 static bool run_locktest3(int dummy
)
1757 static struct cli_state
*cli1
, *cli2
;
1758 const char *fname
= "\\lockt3.lck";
1759 uint16_t fnum1
, fnum2
;
1762 bool correct
= True
;
1765 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1767 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1770 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1771 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1773 printf("starting locktest3\n");
1775 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1777 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1779 if (!NT_STATUS_IS_OK(status
)) {
1780 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1784 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1785 if (!NT_STATUS_IS_OK(status
)) {
1786 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1790 for (offset
=i
=0;i
<torture_numops
;i
++) {
1793 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1794 if (!NT_STATUS_IS_OK(status
)) {
1795 printf("lock1 %d failed (%s)\n",
1801 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1802 if (!NT_STATUS_IS_OK(status
)) {
1803 printf("lock2 %d failed (%s)\n",
1810 for (offset
=i
=0;i
<torture_numops
;i
++) {
1813 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1814 if (NT_STATUS_IS_OK(status
)) {
1815 printf("error: lock1 %d succeeded!\n", i
);
1819 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1820 if (NT_STATUS_IS_OK(status
)) {
1821 printf("error: lock2 %d succeeded!\n", i
);
1825 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1826 if (NT_STATUS_IS_OK(status
)) {
1827 printf("error: lock3 %d succeeded!\n", i
);
1831 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1832 if (NT_STATUS_IS_OK(status
)) {
1833 printf("error: lock4 %d succeeded!\n", i
);
1838 for (offset
=i
=0;i
<torture_numops
;i
++) {
1841 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1842 if (!NT_STATUS_IS_OK(status
)) {
1843 printf("unlock1 %d failed (%s)\n",
1849 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1850 if (!NT_STATUS_IS_OK(status
)) {
1851 printf("unlock2 %d failed (%s)\n",
1858 status
= cli_close(cli1
, fnum1
);
1859 if (!NT_STATUS_IS_OK(status
)) {
1860 printf("close1 failed (%s)\n", nt_errstr(status
));
1864 status
= cli_close(cli2
, fnum2
);
1865 if (!NT_STATUS_IS_OK(status
)) {
1866 printf("close2 failed (%s)\n", nt_errstr(status
));
1870 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1871 if (!NT_STATUS_IS_OK(status
)) {
1872 printf("unlink failed (%s)\n", nt_errstr(status
));
1876 if (!torture_close_connection(cli1
)) {
1880 if (!torture_close_connection(cli2
)) {
1884 printf("finished locktest3\n");
1889 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1890 char *buf
, off_t offset
, size_t size
,
1891 size_t *nread
, size_t expect
)
1896 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1898 if(!NT_STATUS_IS_OK(status
)) {
1900 } else if (l_nread
!= expect
) {
1911 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1912 printf("** "); correct = False; \
1916 looks at overlapping locks
1918 static bool run_locktest4(int dummy
)
1920 static struct cli_state
*cli1
, *cli2
;
1921 const char *fname
= "\\lockt4.lck";
1922 uint16_t fnum1
, fnum2
, f
;
1925 bool correct
= True
;
1928 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1932 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1933 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1935 printf("starting locktest4\n");
1937 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1939 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1940 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1942 memset(buf
, 0, sizeof(buf
));
1944 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1946 if (!NT_STATUS_IS_OK(status
)) {
1947 printf("Failed to create file: %s\n", nt_errstr(status
));
1952 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1953 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1954 EXPECTED(ret
, False
);
1955 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1957 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
1958 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
1959 EXPECTED(ret
, True
);
1960 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1962 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
1963 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
1964 EXPECTED(ret
, False
);
1965 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1967 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
1968 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
1969 EXPECTED(ret
, True
);
1970 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1972 ret
= (cli_setpid(cli1
, 1),
1973 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
1974 (cli_setpid(cli1
, 2),
1975 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
1976 EXPECTED(ret
, False
);
1977 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1979 ret
= (cli_setpid(cli1
, 1),
1980 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
1981 (cli_setpid(cli1
, 2),
1982 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
1983 EXPECTED(ret
, True
);
1984 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1986 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
1987 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
1988 EXPECTED(ret
, True
);
1989 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1991 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
1992 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
1993 EXPECTED(ret
, False
);
1994 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1996 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
1998 EXPECTED(ret
, False
);
1999 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
2001 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
2002 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
2003 EXPECTED(ret
, True
);
2004 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2006 ret
= (cli_setpid(cli1
, 1),
2007 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2008 (cli_setpid(cli1
, 2),
2009 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2010 EXPECTED(ret
, False
);
2011 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2013 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2014 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2015 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2016 EXPECTED(ret
, False
);
2017 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2020 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2021 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2022 EXPECTED(ret
, False
);
2023 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2025 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2026 ret
= NT_STATUS_IS_OK(status
);
2028 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2030 ret
= NT_STATUS_IS_OK(status
);
2032 EXPECTED(ret
, False
);
2033 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2036 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2037 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2038 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2039 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2040 EXPECTED(ret
, True
);
2041 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2044 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2045 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2047 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2048 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2050 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2051 EXPECTED(ret
, True
);
2052 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2054 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2055 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2056 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2058 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2059 EXPECTED(ret
, True
);
2060 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2062 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2063 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2064 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2066 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2067 EXPECTED(ret
, True
);
2068 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2070 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2072 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2073 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2075 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2076 EXPECTED(ret
, True
);
2077 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2079 cli_close(cli1
, fnum1
);
2080 cli_close(cli2
, fnum2
);
2081 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2082 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2083 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2084 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2085 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2086 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2087 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2089 cli_close(cli1
, fnum1
);
2090 EXPECTED(ret
, True
);
2091 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2094 cli_close(cli1
, fnum1
);
2095 cli_close(cli2
, fnum2
);
2096 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2097 torture_close_connection(cli1
);
2098 torture_close_connection(cli2
);
2100 printf("finished locktest4\n");
2105 looks at lock upgrade/downgrade.
2107 static bool run_locktest5(int dummy
)
2109 static struct cli_state
*cli1
, *cli2
;
2110 const char *fname
= "\\lockt5.lck";
2111 uint16_t fnum1
, fnum2
, fnum3
;
2114 bool correct
= True
;
2117 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2121 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2122 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2124 printf("starting locktest5\n");
2126 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2128 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2129 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2130 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2132 memset(buf
, 0, sizeof(buf
));
2134 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2136 if (!NT_STATUS_IS_OK(status
)) {
2137 printf("Failed to create file: %s\n", nt_errstr(status
));
2142 /* Check for NT bug... */
2143 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2144 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2145 cli_close(cli1
, fnum1
);
2146 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2147 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2148 ret
= NT_STATUS_IS_OK(status
);
2149 EXPECTED(ret
, True
);
2150 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2151 cli_close(cli1
, fnum1
);
2152 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2153 cli_unlock(cli1
, fnum3
, 0, 1);
2155 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2156 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2157 EXPECTED(ret
, True
);
2158 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2160 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2161 ret
= NT_STATUS_IS_OK(status
);
2162 EXPECTED(ret
, False
);
2164 printf("a different process %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2166 /* Unlock the process 2 lock. */
2167 cli_unlock(cli2
, fnum2
, 0, 4);
2169 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2170 ret
= NT_STATUS_IS_OK(status
);
2171 EXPECTED(ret
, False
);
2173 printf("the same process on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2175 /* Unlock the process 1 fnum3 lock. */
2176 cli_unlock(cli1
, fnum3
, 0, 4);
2178 /* Stack 2 more locks here. */
2179 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2180 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2182 EXPECTED(ret
, True
);
2183 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2185 /* Unlock the first process lock, then check this was the WRITE lock that was
2188 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2189 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2191 EXPECTED(ret
, True
);
2192 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2194 /* Unlock the process 2 lock. */
2195 cli_unlock(cli2
, fnum2
, 0, 4);
2197 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2199 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2200 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2201 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2203 EXPECTED(ret
, True
);
2204 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2206 /* Ensure the next unlock fails. */
2207 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2208 EXPECTED(ret
, False
);
2209 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2211 /* Ensure connection 2 can get a write lock. */
2212 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2213 ret
= NT_STATUS_IS_OK(status
);
2214 EXPECTED(ret
, True
);
2216 printf("a different process %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2220 cli_close(cli1
, fnum1
);
2221 cli_close(cli2
, fnum2
);
2222 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2223 if (!torture_close_connection(cli1
)) {
2226 if (!torture_close_connection(cli2
)) {
2230 printf("finished locktest5\n");
2236 tries the unusual lockingX locktype bits
2238 static bool run_locktest6(int dummy
)
2240 static struct cli_state
*cli
;
2241 const char *fname
[1] = { "\\lock6.txt" };
2246 if (!torture_open_connection(&cli
, 0)) {
2250 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2252 printf("starting locktest6\n");
2255 printf("Testing %s\n", fname
[i
]);
2257 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2259 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2260 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2261 cli_close(cli
, fnum
);
2262 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2264 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2265 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2266 cli_close(cli
, fnum
);
2267 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2269 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2272 torture_close_connection(cli
);
2274 printf("finished locktest6\n");
2278 static bool run_locktest7(int dummy
)
2280 struct cli_state
*cli1
;
2281 const char *fname
= "\\lockt7.lck";
2284 bool correct
= False
;
2288 if (!torture_open_connection(&cli1
, 0)) {
2292 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2294 printf("starting locktest7\n");
2296 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2298 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2300 memset(buf
, 0, sizeof(buf
));
2302 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2304 if (!NT_STATUS_IS_OK(status
)) {
2305 printf("Failed to create file: %s\n", nt_errstr(status
));
2309 cli_setpid(cli1
, 1);
2311 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2312 if (!NT_STATUS_IS_OK(status
)) {
2313 printf("Unable to apply read lock on range 130:4, "
2314 "error was %s\n", nt_errstr(status
));
2317 printf("pid1 successfully locked range 130:4 for READ\n");
2320 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2321 if (!NT_STATUS_IS_OK(status
)) {
2322 printf("pid1 unable to read the range 130:4, error was %s\n",
2325 } else if (nread
!= 4) {
2326 printf("pid1 unable to read the range 130:4, "
2327 "recv %ld req %d\n", (unsigned long)nread
, 4);
2330 printf("pid1 successfully read the range 130:4\n");
2333 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2334 if (!NT_STATUS_IS_OK(status
)) {
2335 printf("pid1 unable to write to the range 130:4, error was "
2336 "%s\n", nt_errstr(status
));
2337 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2338 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2342 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2346 cli_setpid(cli1
, 2);
2348 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2349 if (!NT_STATUS_IS_OK(status
)) {
2350 printf("pid2 unable to read the range 130:4, error was %s\n",
2353 } else if (nread
!= 4) {
2354 printf("pid2 unable to read the range 130:4, "
2355 "recv %ld req %d\n", (unsigned long)nread
, 4);
2358 printf("pid2 successfully read the range 130:4\n");
2361 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2362 if (!NT_STATUS_IS_OK(status
)) {
2363 printf("pid2 unable to write to the range 130:4, error was "
2364 "%s\n", nt_errstr(status
));
2365 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2366 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2370 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2374 cli_setpid(cli1
, 1);
2375 cli_unlock(cli1
, fnum1
, 130, 4);
2377 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2378 if (!NT_STATUS_IS_OK(status
)) {
2379 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2382 printf("pid1 successfully locked range 130:4 for WRITE\n");
2385 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2386 if (!NT_STATUS_IS_OK(status
)) {
2387 printf("pid1 unable to read the range 130:4, error was %s\n",
2390 } else if (nread
!= 4) {
2391 printf("pid1 unable to read the range 130:4, "
2392 "recv %ld req %d\n", (unsigned long)nread
, 4);
2395 printf("pid1 successfully read the range 130:4\n");
2398 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2399 if (!NT_STATUS_IS_OK(status
)) {
2400 printf("pid1 unable to write to the range 130:4, error was "
2401 "%s\n", nt_errstr(status
));
2404 printf("pid1 successfully wrote to the range 130:4\n");
2407 cli_setpid(cli1
, 2);
2409 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2410 if (!NT_STATUS_IS_OK(status
)) {
2411 printf("pid2 unable to read the range 130:4, error was "
2412 "%s\n", nt_errstr(status
));
2413 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2414 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2418 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2419 (unsigned long)nread
);
2423 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2424 if (!NT_STATUS_IS_OK(status
)) {
2425 printf("pid2 unable to write to the range 130:4, error was "
2426 "%s\n", nt_errstr(status
));
2427 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2428 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2432 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2436 cli_unlock(cli1
, fnum1
, 130, 0);
2440 cli_close(cli1
, fnum1
);
2441 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2442 torture_close_connection(cli1
);
2444 printf("finished locktest7\n");
2449 * This demonstrates a problem with our use of GPFS share modes: A file
2450 * descriptor sitting in the pending close queue holding a GPFS share mode
2451 * blocks opening a file another time. Happens with Word 2007 temp files.
2452 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2453 * open is denied with NT_STATUS_SHARING_VIOLATION.
2456 static bool run_locktest8(int dummy
)
2458 struct cli_state
*cli1
;
2459 const char *fname
= "\\lockt8.lck";
2460 uint16_t fnum1
, fnum2
;
2462 bool correct
= False
;
2465 if (!torture_open_connection(&cli1
, 0)) {
2469 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2471 printf("starting locktest8\n");
2473 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2475 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2477 if (!NT_STATUS_IS_OK(status
)) {
2478 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2482 memset(buf
, 0, sizeof(buf
));
2484 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2485 if (!NT_STATUS_IS_OK(status
)) {
2486 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2491 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2492 if (!NT_STATUS_IS_OK(status
)) {
2493 printf("Unable to apply read lock on range 1:1, error was "
2494 "%s\n", nt_errstr(status
));
2498 status
= cli_close(cli1
, fnum1
);
2499 if (!NT_STATUS_IS_OK(status
)) {
2500 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2504 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2505 if (!NT_STATUS_IS_OK(status
)) {
2506 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2514 cli_close(cli1
, fnum1
);
2515 cli_close(cli1
, fnum2
);
2516 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2517 torture_close_connection(cli1
);
2519 printf("finished locktest8\n");
2524 * This test is designed to be run in conjunction with
2525 * external NFS or POSIX locks taken in the filesystem.
2526 * It checks that the smbd server will block until the
2527 * lock is released and then acquire it. JRA.
2530 static bool got_alarm
;
2531 static struct cli_state
*alarm_cli
;
2533 static void alarm_handler(int dummy
)
2538 static void alarm_handler_parent(int dummy
)
2540 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_OK
);
2543 static void do_local_lock(int read_fd
, int write_fd
)
2548 const char *local_pathname
= NULL
;
2551 local_pathname
= talloc_asprintf(talloc_tos(),
2552 "%s/lockt9.lck", local_path
);
2553 if (!local_pathname
) {
2554 printf("child: alloc fail\n");
2558 unlink(local_pathname
);
2559 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2561 printf("child: open of %s failed %s.\n",
2562 local_pathname
, strerror(errno
));
2566 /* Now take a fcntl lock. */
2567 lock
.l_type
= F_WRLCK
;
2568 lock
.l_whence
= SEEK_SET
;
2571 lock
.l_pid
= getpid();
2573 ret
= fcntl(fd
,F_SETLK
,&lock
);
2575 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2576 local_pathname
, strerror(errno
));
2579 printf("child: got lock 0:4 on file %s.\n",
2584 CatchSignal(SIGALRM
, alarm_handler
);
2586 /* Signal the parent. */
2587 if (write(write_fd
, &c
, 1) != 1) {
2588 printf("child: start signal fail %s.\n",
2595 /* Wait for the parent to be ready. */
2596 if (read(read_fd
, &c
, 1) != 1) {
2597 printf("child: reply signal fail %s.\n",
2605 printf("child: released lock 0:4 on file %s.\n",
2611 static bool run_locktest9(int dummy
)
2613 struct cli_state
*cli1
;
2614 const char *fname
= "\\lockt9.lck";
2616 bool correct
= False
;
2617 int pipe_in
[2], pipe_out
[2];
2621 struct timeval start
;
2625 printf("starting locktest9\n");
2627 if (local_path
== NULL
) {
2628 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2632 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2637 if (child_pid
== -1) {
2641 if (child_pid
== 0) {
2643 do_local_lock(pipe_out
[0], pipe_in
[1]);
2653 ret
= read(pipe_in
[0], &c
, 1);
2655 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2660 if (!torture_open_connection(&cli1
, 0)) {
2664 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2666 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
,
2668 if (!NT_STATUS_IS_OK(status
)) {
2669 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2673 /* Ensure the child has the lock. */
2674 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2675 if (NT_STATUS_IS_OK(status
)) {
2676 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2679 d_printf("Child has the lock.\n");
2682 /* Tell the child to wait 5 seconds then exit. */
2683 ret
= write(pipe_out
[1], &c
, 1);
2685 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2690 /* Wait 20 seconds for the lock. */
2692 CatchSignal(SIGALRM
, alarm_handler_parent
);
2695 start
= timeval_current();
2697 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2698 if (!NT_STATUS_IS_OK(status
)) {
2699 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2700 "%s\n", nt_errstr(status
));
2705 seconds
= timeval_elapsed(&start
);
2707 printf("Parent got the lock after %.2f seconds.\n",
2710 status
= cli_close(cli1
, fnum
);
2711 if (!NT_STATUS_IS_OK(status
)) {
2712 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2719 cli_close(cli1
, fnum
);
2720 torture_close_connection(cli1
);
2724 printf("finished locktest9\n");
2729 test whether fnums and tids open on one VC are available on another (a major
2732 static bool run_fdpasstest(int dummy
)
2734 struct cli_state
*cli1
, *cli2
;
2735 const char *fname
= "\\fdpass.tst";
2740 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2743 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2744 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2746 printf("starting fdpasstest\n");
2748 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2750 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2752 if (!NT_STATUS_IS_OK(status
)) {
2753 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2757 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2759 if (!NT_STATUS_IS_OK(status
)) {
2760 printf("write failed (%s)\n", nt_errstr(status
));
2764 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2765 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2766 cli_setpid(cli2
, cli_getpid(cli1
));
2768 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2769 printf("read succeeded! nasty security hole [%s]\n", buf
);
2773 cli_close(cli1
, fnum1
);
2774 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2776 torture_close_connection(cli1
);
2777 torture_close_connection(cli2
);
2779 printf("finished fdpasstest\n");
2783 static bool run_fdsesstest(int dummy
)
2785 struct cli_state
*cli
;
2787 uint16_t saved_vuid
;
2789 uint32_t saved_cnum
;
2790 const char *fname
= "\\fdsess.tst";
2791 const char *fname1
= "\\fdsess1.tst";
2798 if (!torture_open_connection(&cli
, 0))
2800 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2802 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2805 saved_cnum
= cli_state_get_tid(cli
);
2806 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", NULL
)))
2808 new_cnum
= cli_state_get_tid(cli
);
2809 cli_state_set_tid(cli
, saved_cnum
);
2811 printf("starting fdsesstest\n");
2813 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2814 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2816 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2817 if (!NT_STATUS_IS_OK(status
)) {
2818 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2822 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2824 if (!NT_STATUS_IS_OK(status
)) {
2825 printf("write failed (%s)\n", nt_errstr(status
));
2829 saved_vuid
= cli_state_get_uid(cli
);
2830 cli_state_set_uid(cli
, new_vuid
);
2832 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2833 printf("read succeeded with different vuid! "
2834 "nasty security hole [%s]\n", buf
);
2837 /* Try to open a file with different vuid, samba cnum. */
2838 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2839 printf("create with different vuid, same cnum succeeded.\n");
2840 cli_close(cli
, fnum2
);
2841 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2843 printf("create with different vuid, same cnum failed.\n");
2844 printf("This will cause problems with service clients.\n");
2848 cli_state_set_uid(cli
, saved_vuid
);
2850 /* Try with same vuid, different cnum. */
2851 cli_state_set_tid(cli
, new_cnum
);
2853 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2854 printf("read succeeded with different cnum![%s]\n", buf
);
2858 cli_state_set_tid(cli
, saved_cnum
);
2859 cli_close(cli
, fnum1
);
2860 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2862 torture_close_connection(cli
);
2864 printf("finished fdsesstest\n");
2869 This test checks that
2871 1) the server does not allow an unlink on a file that is open
2873 static bool run_unlinktest(int dummy
)
2875 struct cli_state
*cli
;
2876 const char *fname
= "\\unlink.tst";
2878 bool correct
= True
;
2881 if (!torture_open_connection(&cli
, 0)) {
2885 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2887 printf("starting unlink test\n");
2889 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2893 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2894 if (!NT_STATUS_IS_OK(status
)) {
2895 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2899 status
= cli_unlink(cli
, fname
,
2900 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2901 if (NT_STATUS_IS_OK(status
)) {
2902 printf("error: server allowed unlink on an open file\n");
2905 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2906 NT_STATUS_SHARING_VIOLATION
);
2909 cli_close(cli
, fnum
);
2910 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2912 if (!torture_close_connection(cli
)) {
2916 printf("unlink test finished\n");
2923 test how many open files this server supports on the one socket
2925 static bool run_maxfidtest(int dummy
)
2927 struct cli_state
*cli
;
2929 uint16_t fnums
[0x11000];
2932 bool correct
= True
;
2938 printf("failed to connect\n");
2942 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2944 for (i
=0; i
<0x11000; i
++) {
2945 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2946 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2948 if (!NT_STATUS_IS_OK(status
)) {
2949 printf("open of %s failed (%s)\n",
2950 fname
, nt_errstr(status
));
2951 printf("maximum fnum is %d\n", i
);
2959 printf("cleaning up\n");
2961 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2962 cli_close(cli
, fnums
[i
]);
2964 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2965 if (!NT_STATUS_IS_OK(status
)) {
2966 printf("unlink of %s failed (%s)\n",
2967 fname
, nt_errstr(status
));
2974 printf("maxfid test finished\n");
2975 if (!torture_close_connection(cli
)) {
2981 /* generate a random buffer */
2982 static void rand_buf(char *buf
, int len
)
2985 *buf
= (char)sys_random();
2990 /* send smb negprot commands, not reading the response */
2991 static bool run_negprot_nowait(int dummy
)
2993 struct tevent_context
*ev
;
2995 struct cli_state
*cli
;
2996 bool correct
= True
;
2998 printf("starting negprot nowait test\n");
3000 ev
= samba_tevent_context_init(talloc_tos());
3005 if (!(cli
= open_nbt_connection())) {
3010 for (i
=0;i
<50000;i
++) {
3011 struct tevent_req
*req
;
3013 req
= smbXcli_negprot_send(ev
, ev
, cli
->conn
, cli
->timeout
,
3014 PROTOCOL_CORE
, PROTOCOL_NT1
, 0);
3019 if (!tevent_req_poll(req
, ev
)) {
3020 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3028 if (torture_close_connection(cli
)) {
3032 printf("finished negprot nowait test\n");
3037 /* send smb negprot commands, not reading the response */
3038 static bool run_bad_nbt_session(int dummy
)
3040 struct nmb_name called
, calling
;
3041 struct sockaddr_storage ss
;
3046 printf("starting bad nbt session test\n");
3048 make_nmb_name(&calling
, myname
, 0x0);
3049 make_nmb_name(&called
, host
, 0x20);
3051 if (!resolve_name(host
, &ss
, 0x20, true)) {
3052 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3056 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
3057 if (!NT_STATUS_IS_OK(status
)) {
3058 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3063 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3066 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3071 printf("finished bad nbt session test\n");
3075 /* send random IPC commands */
3076 static bool run_randomipc(int dummy
)
3078 char *rparam
= NULL
;
3080 unsigned int rdrcnt
,rprcnt
;
3082 int api
, param_len
, i
;
3083 struct cli_state
*cli
;
3084 bool correct
= True
;
3087 printf("starting random ipc test\n");
3089 if (!torture_open_connection(&cli
, 0)) {
3093 for (i
=0;i
<count
;i
++) {
3094 api
= sys_random() % 500;
3095 param_len
= (sys_random() % 64);
3097 rand_buf(param
, param_len
);
3102 param
, param_len
, 8,
3103 NULL
, 0, CLI_BUFFER_SIZE
,
3107 printf("%d/%d\r", i
,count
);
3110 printf("%d/%d\n", i
, count
);
3112 if (!torture_close_connection(cli
)) {
3119 printf("finished random ipc test\n");
3126 static void browse_callback(const char *sname
, uint32_t stype
,
3127 const char *comment
, void *state
)
3129 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3135 This test checks the browse list code
3138 static bool run_browsetest(int dummy
)
3140 static struct cli_state
*cli
;
3141 bool correct
= True
;
3143 printf("starting browse test\n");
3145 if (!torture_open_connection(&cli
, 0)) {
3149 printf("domain list:\n");
3150 cli_NetServerEnum(cli
, cli
->server_domain
,
3151 SV_TYPE_DOMAIN_ENUM
,
3152 browse_callback
, NULL
);
3154 printf("machine list:\n");
3155 cli_NetServerEnum(cli
, cli
->server_domain
,
3157 browse_callback
, NULL
);
3159 if (!torture_close_connection(cli
)) {
3163 printf("browse test finished\n");
3169 static bool check_attributes(struct cli_state
*cli
,
3171 uint16_t expected_attrs
)
3174 NTSTATUS status
= cli_getatr(cli
,
3179 if (!NT_STATUS_IS_OK(status
)) {
3180 printf("cli_getatr failed with %s\n",
3184 if (attrs
!= expected_attrs
) {
3185 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3186 (unsigned int)attrs
,
3187 (unsigned int)expected_attrs
);
3194 This checks how the getatr calls works
3196 static bool run_attrtest(int dummy
)
3198 struct cli_state
*cli
;
3201 const char *fname
= "\\attrib123456789.tst";
3202 bool correct
= True
;
3205 printf("starting attrib test\n");
3207 if (!torture_open_connection(&cli
, 0)) {
3211 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3212 cli_openx(cli
, fname
,
3213 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3214 cli_close(cli
, fnum
);
3216 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3217 if (!NT_STATUS_IS_OK(status
)) {
3218 printf("getatr failed (%s)\n", nt_errstr(status
));
3222 if (labs(t
- time(NULL
)) > 60*60*24*10) {
3223 printf("ERROR: SMBgetatr bug. time is %s",
3229 t2
= t
-60*60*24; /* 1 day ago */
3231 status
= cli_setatr(cli
, fname
, 0, t2
);
3232 if (!NT_STATUS_IS_OK(status
)) {
3233 printf("setatr failed (%s)\n", nt_errstr(status
));
3237 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3238 if (!NT_STATUS_IS_OK(status
)) {
3239 printf("getatr failed (%s)\n", nt_errstr(status
));
3244 printf("ERROR: getatr/setatr bug. times are\n%s",
3246 printf("%s", ctime(&t2
));
3250 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3252 /* Check cli_setpathinfo_basic() */
3253 /* Re-create the file. */
3254 status
= cli_openx(cli
, fname
,
3255 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3256 if (!NT_STATUS_IS_OK(status
)) {
3257 printf("Failed to recreate %s (%s)\n",
3258 fname
, nt_errstr(status
));
3261 cli_close(cli
, fnum
);
3263 status
= cli_setpathinfo_basic(cli
,
3269 FILE_ATTRIBUTE_SYSTEM
|
3270 FILE_ATTRIBUTE_HIDDEN
|
3271 FILE_ATTRIBUTE_READONLY
);
3272 if (!NT_STATUS_IS_OK(status
)) {
3273 printf("cli_setpathinfo_basic failed with %s\n",
3278 /* Check attributes are correct. */
3279 correct
= check_attributes(cli
,
3281 FILE_ATTRIBUTE_SYSTEM
|
3282 FILE_ATTRIBUTE_HIDDEN
|
3283 FILE_ATTRIBUTE_READONLY
);
3284 if (correct
== false) {
3288 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3289 status
= cli_setpathinfo_basic(cli
,
3295 FILE_ATTRIBUTE_NORMAL
);
3296 if (!NT_STATUS_IS_OK(status
)) {
3297 printf("cli_setpathinfo_basic failed with %s\n",
3302 /* Check attributes are correct. */
3303 correct
= check_attributes(cli
,
3305 FILE_ATTRIBUTE_SYSTEM
|
3306 FILE_ATTRIBUTE_HIDDEN
|
3307 FILE_ATTRIBUTE_READONLY
);
3308 if (correct
== false) {
3312 /* Setting to (uint16_t)-1 should also be ignored. */
3313 status
= cli_setpathinfo_basic(cli
,
3320 if (!NT_STATUS_IS_OK(status
)) {
3321 printf("cli_setpathinfo_basic failed with %s\n",
3326 /* Check attributes are correct. */
3327 correct
= check_attributes(cli
,
3329 FILE_ATTRIBUTE_SYSTEM
|
3330 FILE_ATTRIBUTE_HIDDEN
|
3331 FILE_ATTRIBUTE_READONLY
);
3332 if (correct
== false) {
3336 /* Setting to 0 should clear them all. */
3337 status
= cli_setpathinfo_basic(cli
,
3344 if (!NT_STATUS_IS_OK(status
)) {
3345 printf("cli_setpathinfo_basic failed with %s\n",
3350 /* Check attributes are correct. */
3351 correct
= check_attributes(cli
,
3353 FILE_ATTRIBUTE_NORMAL
);
3354 if (correct
== false) {
3362 FILE_ATTRIBUTE_SYSTEM
|
3363 FILE_ATTRIBUTE_HIDDEN
|
3364 FILE_ATTRIBUTE_READONLY
);
3366 if (!torture_close_connection(cli
)) {
3370 printf("attrib test finished\n");
3377 This checks a couple of trans2 calls
3379 static bool run_trans2test(int dummy
)
3381 struct cli_state
*cli
;
3384 time_t c_time
, a_time
, m_time
;
3385 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3386 const char *fname
= "\\trans2.tst";
3387 const char *dname
= "\\trans2";
3388 const char *fname2
= "\\trans2\\trans2.tst";
3390 bool correct
= True
;
3394 printf("starting trans2 test\n");
3396 if (!torture_open_connection(&cli
, 0)) {
3400 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3401 if (!NT_STATUS_IS_OK(status
)) {
3402 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3407 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3408 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3409 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3410 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3411 if (!NT_STATUS_IS_OK(status
)) {
3412 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3416 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3417 if (!NT_STATUS_IS_OK(status
)) {
3418 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3421 else if (strcmp(pname
, fname
)) {
3422 printf("qfilename gave different name? [%s] [%s]\n",
3427 cli_close(cli
, fnum
);
3431 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3432 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3434 if (!NT_STATUS_IS_OK(status
)) {
3435 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3438 cli_close(cli
, fnum
);
3440 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3442 if (!NT_STATUS_IS_OK(status
)) {
3443 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3446 time_t t
= time(NULL
);
3448 if (c_time
!= m_time
) {
3449 printf("create time=%s", ctime(&c_time
));
3450 printf("modify time=%s", ctime(&m_time
));
3451 printf("This system appears to have sticky create times\n");
3453 if ((labs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3454 printf("access time=%s", ctime(&a_time
));
3455 printf("This system appears to set a midnight access time\n");
3459 if (labs(m_time
- t
) > 60*60*24*7) {
3460 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3466 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3467 cli_openx(cli
, fname
,
3468 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3469 cli_close(cli
, fnum
);
3470 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3471 &m_time_ts
, &size
, NULL
, NULL
);
3472 if (!NT_STATUS_IS_OK(status
)) {
3473 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3476 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3477 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3478 printf("This system appears to set a initial 0 write time\n");
3483 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3486 /* check if the server updates the directory modification time
3487 when creating a new file */
3488 status
= cli_mkdir(cli
, dname
);
3489 if (!NT_STATUS_IS_OK(status
)) {
3490 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3494 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3495 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3496 if (!NT_STATUS_IS_OK(status
)) {
3497 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3501 cli_openx(cli
, fname2
,
3502 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3503 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3504 cli_close(cli
, fnum
);
3505 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3506 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3507 if (!NT_STATUS_IS_OK(status
)) {
3508 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3511 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3513 printf("This system does not update directory modification times\n");
3517 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3518 cli_rmdir(cli
, dname
);
3520 if (!torture_close_connection(cli
)) {
3524 printf("trans2 test finished\n");
3530 This checks new W2K calls.
3533 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3535 uint8_t *buf
= NULL
;
3539 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3540 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3541 if (!NT_STATUS_IS_OK(status
)) {
3542 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3545 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3546 dump_data(0, (uint8_t *)buf
, len
);
3553 static bool run_w2ktest(int dummy
)
3555 struct cli_state
*cli
;
3557 const char *fname
= "\\w2ktest\\w2k.tst";
3559 bool correct
= True
;
3561 printf("starting w2k test\n");
3563 if (!torture_open_connection(&cli
, 0)) {
3567 cli_openx(cli
, fname
,
3568 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3570 for (level
= 1004; level
< 1040; level
++) {
3571 new_trans(cli
, fnum
, level
);
3574 cli_close(cli
, fnum
);
3576 if (!torture_close_connection(cli
)) {
3580 printf("w2k test finished\n");
3587 this is a harness for some oplock tests
3589 static bool run_oplock1(int dummy
)
3591 struct cli_state
*cli1
;
3592 const char *fname
= "\\lockt1.lck";
3594 bool correct
= True
;
3597 printf("starting oplock test 1\n");
3599 if (!torture_open_connection(&cli1
, 0)) {
3603 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3605 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3607 cli1
->use_oplocks
= True
;
3609 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3611 if (!NT_STATUS_IS_OK(status
)) {
3612 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3616 cli1
->use_oplocks
= False
;
3618 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3619 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3621 status
= cli_close(cli1
, fnum1
);
3622 if (!NT_STATUS_IS_OK(status
)) {
3623 printf("close2 failed (%s)\n", nt_errstr(status
));
3627 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3628 if (!NT_STATUS_IS_OK(status
)) {
3629 printf("unlink failed (%s)\n", nt_errstr(status
));
3633 if (!torture_close_connection(cli1
)) {
3637 printf("finished oplock test 1\n");
3642 static bool run_oplock2(int dummy
)
3644 struct cli_state
*cli1
, *cli2
;
3645 const char *fname
= "\\lockt2.lck";
3646 uint16_t fnum1
, fnum2
;
3647 int saved_use_oplocks
= use_oplocks
;
3649 bool correct
= True
;
3650 volatile bool *shared_correct
;
3654 shared_correct
= (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3655 *shared_correct
= True
;
3657 use_level_II_oplocks
= True
;
3660 printf("starting oplock test 2\n");
3662 if (!torture_open_connection(&cli1
, 0)) {
3663 use_level_II_oplocks
= False
;
3664 use_oplocks
= saved_use_oplocks
;
3668 if (!torture_open_connection(&cli2
, 1)) {
3669 use_level_II_oplocks
= False
;
3670 use_oplocks
= saved_use_oplocks
;
3674 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3676 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3677 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3679 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3681 if (!NT_STATUS_IS_OK(status
)) {
3682 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3686 /* Don't need the globals any more. */
3687 use_level_II_oplocks
= False
;
3688 use_oplocks
= saved_use_oplocks
;
3692 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3693 if (!NT_STATUS_IS_OK(status
)) {
3694 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3695 *shared_correct
= False
;
3701 status
= cli_close(cli2
, fnum2
);
3702 if (!NT_STATUS_IS_OK(status
)) {
3703 printf("close2 failed (%s)\n", nt_errstr(status
));
3704 *shared_correct
= False
;
3712 /* Ensure cli1 processes the break. Empty file should always return 0
3714 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3715 if (!NT_STATUS_IS_OK(status
)) {
3716 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3718 } else if (nread
!= 0) {
3719 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3720 (unsigned long)nread
, 0);
3724 /* Should now be at level II. */
3725 /* Test if sending a write locks causes a break to none. */
3726 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3727 if (!NT_STATUS_IS_OK(status
)) {
3728 printf("lock failed (%s)\n", nt_errstr(status
));
3732 cli_unlock(cli1
, fnum1
, 0, 4);
3736 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3737 if (!NT_STATUS_IS_OK(status
)) {
3738 printf("lock failed (%s)\n", nt_errstr(status
));
3742 cli_unlock(cli1
, fnum1
, 0, 4);
3746 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3748 status
= cli_close(cli1
, fnum1
);
3749 if (!NT_STATUS_IS_OK(status
)) {
3750 printf("close1 failed (%s)\n", nt_errstr(status
));
3756 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3757 if (!NT_STATUS_IS_OK(status
)) {
3758 printf("unlink failed (%s)\n", nt_errstr(status
));
3762 if (!torture_close_connection(cli1
)) {
3766 if (!*shared_correct
) {
3770 printf("finished oplock test 2\n");
3775 struct oplock4_state
{
3776 struct tevent_context
*ev
;
3777 struct cli_state
*cli
;
3782 static void oplock4_got_break(struct tevent_req
*req
);
3783 static void oplock4_got_open(struct tevent_req
*req
);
3785 static bool run_oplock4(int dummy
)
3787 struct tevent_context
*ev
;
3788 struct cli_state
*cli1
, *cli2
;
3789 struct tevent_req
*oplock_req
, *open_req
;
3790 const char *fname
= "\\lockt4.lck";
3791 const char *fname_ln
= "\\lockt4_ln.lck";
3792 uint16_t fnum1
, fnum2
;
3793 int saved_use_oplocks
= use_oplocks
;
3795 bool correct
= true;
3799 struct oplock4_state
*state
;
3801 printf("starting oplock test 4\n");
3803 if (!torture_open_connection(&cli1
, 0)) {
3804 use_level_II_oplocks
= false;
3805 use_oplocks
= saved_use_oplocks
;
3809 if (!torture_open_connection(&cli2
, 1)) {
3810 use_level_II_oplocks
= false;
3811 use_oplocks
= saved_use_oplocks
;
3815 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3816 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3818 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3819 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3821 /* Create the file. */
3822 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3824 if (!NT_STATUS_IS_OK(status
)) {
3825 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3829 status
= cli_close(cli1
, fnum1
);
3830 if (!NT_STATUS_IS_OK(status
)) {
3831 printf("close1 failed (%s)\n", nt_errstr(status
));
3835 /* Now create a hardlink. */
3836 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3837 if (!NT_STATUS_IS_OK(status
)) {
3838 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3842 /* Prove that opening hardlinks cause deny modes to conflict. */
3843 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3844 if (!NT_STATUS_IS_OK(status
)) {
3845 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3849 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3850 if (NT_STATUS_IS_OK(status
)) {
3851 printf("open of %s succeeded - should fail with sharing violation.\n",
3856 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3857 printf("open of %s should fail with sharing violation. Got %s\n",
3858 fname_ln
, nt_errstr(status
));
3862 status
= cli_close(cli1
, fnum1
);
3863 if (!NT_STATUS_IS_OK(status
)) {
3864 printf("close1 failed (%s)\n", nt_errstr(status
));
3868 cli1
->use_oplocks
= true;
3869 cli2
->use_oplocks
= true;
3871 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3872 if (!NT_STATUS_IS_OK(status
)) {
3873 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3877 ev
= samba_tevent_context_init(talloc_tos());
3879 printf("tevent_context_init failed\n");
3883 state
= talloc(ev
, struct oplock4_state
);
3884 if (state
== NULL
) {
3885 printf("talloc failed\n");
3890 state
->got_break
= &got_break
;
3891 state
->fnum2
= &fnum2
;
3893 oplock_req
= cli_smb_oplock_break_waiter_send(
3894 talloc_tos(), ev
, cli1
);
3895 if (oplock_req
== NULL
) {
3896 printf("cli_smb_oplock_break_waiter_send failed\n");
3899 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3901 open_req
= cli_openx_send(
3902 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3903 if (open_req
== NULL
) {
3904 printf("cli_openx_send failed\n");
3907 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3912 while (!got_break
|| fnum2
== 0xffff) {
3914 ret
= tevent_loop_once(ev
);
3916 printf("tevent_loop_once failed: %s\n",
3922 status
= cli_close(cli2
, fnum2
);
3923 if (!NT_STATUS_IS_OK(status
)) {
3924 printf("close2 failed (%s)\n", nt_errstr(status
));
3928 status
= cli_close(cli1
, fnum1
);
3929 if (!NT_STATUS_IS_OK(status
)) {
3930 printf("close1 failed (%s)\n", nt_errstr(status
));
3934 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3935 if (!NT_STATUS_IS_OK(status
)) {
3936 printf("unlink failed (%s)\n", nt_errstr(status
));
3940 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3941 if (!NT_STATUS_IS_OK(status
)) {
3942 printf("unlink failed (%s)\n", nt_errstr(status
));
3946 if (!torture_close_connection(cli1
)) {
3954 printf("finished oplock test 4\n");
3959 static void oplock4_got_break(struct tevent_req
*req
)
3961 struct oplock4_state
*state
= tevent_req_callback_data(
3962 req
, struct oplock4_state
);
3967 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3969 if (!NT_STATUS_IS_OK(status
)) {
3970 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3974 *state
->got_break
= true;
3976 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3979 printf("cli_oplock_ack_send failed\n");
3984 static void oplock4_got_open(struct tevent_req
*req
)
3986 struct oplock4_state
*state
= tevent_req_callback_data(
3987 req
, struct oplock4_state
);
3990 status
= cli_openx_recv(req
, state
->fnum2
);
3991 if (!NT_STATUS_IS_OK(status
)) {
3992 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
3993 *state
->fnum2
= 0xffff;
3998 Test delete on close semantics.
4000 static bool run_deletetest(int dummy
)
4002 struct cli_state
*cli1
= NULL
;
4003 struct cli_state
*cli2
= NULL
;
4004 const char *fname
= "\\delete.file";
4005 uint16_t fnum1
= (uint16_t)-1;
4006 uint16_t fnum2
= (uint16_t)-1;
4007 bool correct
= false;
4010 printf("starting delete test\n");
4012 if (!torture_open_connection(&cli1
, 0)) {
4016 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4018 /* Test 1 - this should delete the file on close. */
4020 cli_setatr(cli1
, fname
, 0, 0);
4021 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4023 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
4024 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4025 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4026 if (!NT_STATUS_IS_OK(status
)) {
4027 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4031 status
= cli_close(cli1
, fnum1
);
4032 if (!NT_STATUS_IS_OK(status
)) {
4033 printf("[1] close failed (%s)\n", nt_errstr(status
));
4037 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
4038 if (NT_STATUS_IS_OK(status
)) {
4039 printf("[1] open of %s succeeded (should fail)\n", fname
);
4043 printf("first delete on close test succeeded.\n");
4045 /* Test 2 - this should delete the file on close. */
4047 cli_setatr(cli1
, fname
, 0, 0);
4048 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4050 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
4051 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4052 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4053 if (!NT_STATUS_IS_OK(status
)) {
4054 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4058 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4059 if (!NT_STATUS_IS_OK(status
)) {
4060 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4064 status
= cli_close(cli1
, fnum1
);
4065 if (!NT_STATUS_IS_OK(status
)) {
4066 printf("[2] close failed (%s)\n", nt_errstr(status
));
4070 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4071 if (NT_STATUS_IS_OK(status
)) {
4072 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
4073 status
= cli_close(cli1
, fnum1
);
4074 if (!NT_STATUS_IS_OK(status
)) {
4075 printf("[2] close failed (%s)\n", nt_errstr(status
));
4077 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4081 printf("second delete on close test succeeded.\n");
4084 cli_setatr(cli1
, fname
, 0, 0);
4085 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4087 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
4088 FILE_ATTRIBUTE_NORMAL
,
4089 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4090 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4091 if (!NT_STATUS_IS_OK(status
)) {
4092 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4096 /* This should fail with a sharing violation - open for delete is only compatible
4097 with SHARE_DELETE. */
4099 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4100 FILE_ATTRIBUTE_NORMAL
,
4101 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4102 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4103 if (NT_STATUS_IS_OK(status
)) {
4104 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4108 /* This should succeed. */
4109 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4110 FILE_ATTRIBUTE_NORMAL
,
4111 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4112 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4113 if (!NT_STATUS_IS_OK(status
)) {
4114 printf("[3] open - 3 of %s failed (%s)\n", fname
, nt_errstr(status
));
4118 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4119 if (!NT_STATUS_IS_OK(status
)) {
4120 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4124 status
= cli_close(cli1
, fnum1
);
4125 if (!NT_STATUS_IS_OK(status
)) {
4126 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
4130 status
= cli_close(cli1
, fnum2
);
4131 if (!NT_STATUS_IS_OK(status
)) {
4132 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
4136 /* This should fail - file should no longer be there. */
4138 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4139 if (NT_STATUS_IS_OK(status
)) {
4140 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4141 status
= cli_close(cli1
, fnum1
);
4142 if (!NT_STATUS_IS_OK(status
)) {
4143 printf("[3] close failed (%s)\n", nt_errstr(status
));
4145 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4149 printf("third delete on close test succeeded.\n");
4152 cli_setatr(cli1
, fname
, 0, 0);
4153 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4155 status
= cli_ntcreate(cli1
, fname
, 0,
4156 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4157 FILE_ATTRIBUTE_NORMAL
,
4158 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4159 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4160 if (!NT_STATUS_IS_OK(status
)) {
4161 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4165 /* This should succeed. */
4166 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4167 FILE_ATTRIBUTE_NORMAL
,
4168 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4169 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4170 if (!NT_STATUS_IS_OK(status
)) {
4171 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4175 status
= cli_close(cli1
, fnum2
);
4176 if (!NT_STATUS_IS_OK(status
)) {
4177 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4181 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4182 if (!NT_STATUS_IS_OK(status
)) {
4183 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4187 /* This should fail - no more opens once delete on close set. */
4188 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4189 FILE_ATTRIBUTE_NORMAL
,
4190 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4191 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4192 if (NT_STATUS_IS_OK(status
)) {
4193 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4197 status
= cli_close(cli1
, fnum1
);
4198 if (!NT_STATUS_IS_OK(status
)) {
4199 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4203 printf("fourth delete on close test succeeded.\n");
4206 cli_setatr(cli1
, fname
, 0, 0);
4207 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4209 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4210 if (!NT_STATUS_IS_OK(status
)) {
4211 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4215 /* This should fail - only allowed on NT opens with DELETE access. */
4217 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4218 if (NT_STATUS_IS_OK(status
)) {
4219 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4223 status
= cli_close(cli1
, fnum1
);
4224 if (!NT_STATUS_IS_OK(status
)) {
4225 printf("[5] close failed (%s)\n", nt_errstr(status
));
4229 printf("fifth delete on close test succeeded.\n");
4232 cli_setatr(cli1
, fname
, 0, 0);
4233 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4235 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4236 FILE_ATTRIBUTE_NORMAL
,
4237 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4238 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4239 if (!NT_STATUS_IS_OK(status
)) {
4240 printf("[6] open of %s failed (%s)\n", fname
,
4245 /* This should fail - only allowed on NT opens with DELETE access. */
4247 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4248 if (NT_STATUS_IS_OK(status
)) {
4249 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4253 status
= cli_close(cli1
, fnum1
);
4254 if (!NT_STATUS_IS_OK(status
)) {
4255 printf("[6] close failed (%s)\n", nt_errstr(status
));
4259 printf("sixth delete on close test succeeded.\n");
4262 cli_setatr(cli1
, fname
, 0, 0);
4263 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4265 status
= cli_ntcreate(cli1
, fname
, 0,
4266 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4267 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4268 0, 0, &fnum1
, NULL
);
4269 if (!NT_STATUS_IS_OK(status
)) {
4270 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4274 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4275 if (!NT_STATUS_IS_OK(status
)) {
4276 printf("[7] setting delete_on_close on file failed !\n");
4280 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4281 if (!NT_STATUS_IS_OK(status
)) {
4282 printf("[7] unsetting delete_on_close on file failed !\n");
4286 status
= cli_close(cli1
, fnum1
);
4287 if (!NT_STATUS_IS_OK(status
)) {
4288 printf("[7] close - 1 failed (%s)\n", nt_errstr(status
));
4292 /* This next open should succeed - we reset the flag. */
4293 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4294 if (!NT_STATUS_IS_OK(status
)) {
4295 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4299 status
= cli_close(cli1
, fnum1
);
4300 if (!NT_STATUS_IS_OK(status
)) {
4301 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4305 printf("seventh delete on close test succeeded.\n");
4308 cli_setatr(cli1
, fname
, 0, 0);
4309 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4311 if (!torture_open_connection(&cli2
, 1)) {
4312 printf("[8] failed to open second connection.\n");
4316 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4318 status
= cli_ntcreate(cli1
, fname
, 0,
4319 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4320 FILE_ATTRIBUTE_NORMAL
,
4321 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4322 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4323 if (!NT_STATUS_IS_OK(status
)) {
4324 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4328 status
= cli_ntcreate(cli2
, fname
, 0,
4329 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4330 FILE_ATTRIBUTE_NORMAL
,
4331 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4332 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4333 if (!NT_STATUS_IS_OK(status
)) {
4334 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4338 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4339 if (!NT_STATUS_IS_OK(status
)) {
4340 printf("[8] setting delete_on_close on file failed !\n");
4344 status
= cli_close(cli1
, fnum1
);
4345 if (!NT_STATUS_IS_OK(status
)) {
4346 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4350 status
= cli_close(cli2
, fnum2
);
4351 if (!NT_STATUS_IS_OK(status
)) {
4352 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4356 /* This should fail.. */
4357 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4358 if (NT_STATUS_IS_OK(status
)) {
4359 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4363 printf("eighth delete on close test succeeded.\n");
4367 /* This should fail - we need to set DELETE_ACCESS. */
4368 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4369 FILE_ATTRIBUTE_NORMAL
,
4372 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4373 if (NT_STATUS_IS_OK(status
)) {
4374 printf("[9] open of %s succeeded should have failed!\n", fname
);
4378 printf("ninth delete on close test succeeded.\n");
4382 status
= cli_ntcreate(cli1
, fname
, 0,
4383 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4384 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4385 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4387 if (!NT_STATUS_IS_OK(status
)) {
4388 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4392 /* This should delete the file. */
4393 status
= cli_close(cli1
, fnum1
);
4394 if (!NT_STATUS_IS_OK(status
)) {
4395 printf("[10] close failed (%s)\n", nt_errstr(status
));
4399 /* This should fail.. */
4400 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4401 if (NT_STATUS_IS_OK(status
)) {
4402 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4406 printf("tenth delete on close test succeeded.\n");
4410 cli_setatr(cli1
, fname
, 0, 0);
4411 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4413 /* Can we open a read-only file with delete access? */
4415 /* Create a readonly file. */
4416 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4417 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4418 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4419 if (!NT_STATUS_IS_OK(status
)) {
4420 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4424 status
= cli_close(cli1
, fnum1
);
4425 if (!NT_STATUS_IS_OK(status
)) {
4426 printf("[11] close failed (%s)\n", nt_errstr(status
));
4430 /* Now try open for delete access. */
4431 status
= cli_ntcreate(cli1
, fname
, 0,
4432 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4434 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4435 FILE_OPEN
, 0, 0, &fnum1
, NULL
);
4436 if (!NT_STATUS_IS_OK(status
)) {
4437 printf("[11] open of %s failed: %s\n", fname
, nt_errstr(status
));
4441 cli_close(cli1
, fnum1
);
4443 printf("eleventh delete on close test succeeded.\n");
4447 * like test 4 but with initial delete on close
4450 cli_setatr(cli1
, fname
, 0, 0);
4451 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4453 status
= cli_ntcreate(cli1
, fname
, 0,
4454 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4455 FILE_ATTRIBUTE_NORMAL
,
4456 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4458 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4459 if (!NT_STATUS_IS_OK(status
)) {
4460 printf("[12] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4464 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4465 FILE_ATTRIBUTE_NORMAL
,
4466 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4467 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4468 if (!NT_STATUS_IS_OK(status
)) {
4469 printf("[12] open 2 of %s failed(%s).\n", fname
, nt_errstr(status
));
4473 status
= cli_close(cli1
, fnum2
);
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 printf("[12] close 1 failed (%s)\n", nt_errstr(status
));
4479 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4480 if (!NT_STATUS_IS_OK(status
)) {
4481 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4485 /* This should fail - no more opens once delete on close set. */
4486 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4487 FILE_ATTRIBUTE_NORMAL
,
4488 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4489 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4490 if (NT_STATUS_IS_OK(status
)) {
4491 printf("[12] open 3 of %s succeeded - should fail).\n", fname
);
4495 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4496 if (!NT_STATUS_IS_OK(status
)) {
4497 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status
));
4501 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4502 FILE_ATTRIBUTE_NORMAL
,
4503 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4504 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4505 if (!NT_STATUS_IS_OK(status
)) {
4506 printf("[12] open 4 of %s failed (%s)\n", fname
, nt_errstr(status
));
4510 status
= cli_close(cli1
, fnum2
);
4511 if (!NT_STATUS_IS_OK(status
)) {
4512 printf("[12] close 2 failed (%s)\n", nt_errstr(status
));
4516 status
= cli_close(cli1
, fnum1
);
4517 if (!NT_STATUS_IS_OK(status
)) {
4518 printf("[12] close 3 failed (%s)\n", nt_errstr(status
));
4523 * setting delete on close on the handle does
4524 * not unset the initial delete on close...
4526 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4527 FILE_ATTRIBUTE_NORMAL
,
4528 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4529 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4530 if (NT_STATUS_IS_OK(status
)) {
4531 printf("[12] open 5 of %s succeeded - should fail).\n", fname
);
4533 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4534 printf("ntcreate returned %s, expected "
4535 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4540 printf("twelfth delete on close test succeeded.\n");
4543 printf("finished delete test\n");
4548 /* FIXME: This will crash if we aborted before cli2 got
4549 * intialized, because these functions don't handle
4550 * uninitialized connections. */
4552 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4553 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4554 cli_setatr(cli1
, fname
, 0, 0);
4555 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4557 if (cli1
&& !torture_close_connection(cli1
)) {
4560 if (cli2
&& !torture_close_connection(cli2
)) {
4567 Exercise delete on close semantics - use on the PRINT1 share in torture
4570 static bool run_delete_print_test(int dummy
)
4572 struct cli_state
*cli1
= NULL
;
4573 const char *fname
= "print_delete.file";
4574 uint16_t fnum1
= (uint16_t)-1;
4575 bool correct
= false;
4576 const char *buf
= "print file data\n";
4579 printf("starting print delete test\n");
4581 if (!torture_open_connection(&cli1
, 0)) {
4585 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4587 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
4588 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4589 0, 0, &fnum1
, NULL
);
4590 if (!NT_STATUS_IS_OK(status
)) {
4591 printf("open of %s failed (%s)\n",
4597 status
= cli_writeall(cli1
,
4600 (const uint8_t *)buf
,
4602 strlen(buf
), /* size */
4604 if (!NT_STATUS_IS_OK(status
)) {
4605 printf("writing print file data failed (%s)\n",
4610 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4611 if (!NT_STATUS_IS_OK(status
)) {
4612 printf("setting delete_on_close failed (%s)\n",
4617 status
= cli_close(cli1
, fnum1
);
4618 if (!NT_STATUS_IS_OK(status
)) {
4619 printf("close failed (%s)\n", nt_errstr(status
));
4623 printf("finished print delete test\n");
4629 if (fnum1
!= (uint16_t)-1) {
4630 cli_close(cli1
, fnum1
);
4633 if (cli1
&& !torture_close_connection(cli1
)) {
4640 Test wildcard delete.
4642 static bool run_wild_deletetest(int dummy
)
4644 struct cli_state
*cli
= NULL
;
4645 const char *dname
= "\\WTEST";
4646 const char *fname
= "\\WTEST\\A";
4647 const char *wunlink_name
= "\\WTEST\\*";
4648 uint16_t fnum1
= (uint16_t)-1;
4649 bool correct
= false;
4652 printf("starting wildcard delete test\n");
4654 if (!torture_open_connection(&cli
, 0)) {
4658 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4660 cli_unlink(cli
, fname
, 0);
4661 cli_rmdir(cli
, dname
);
4662 status
= cli_mkdir(cli
, dname
);
4663 if (!NT_STATUS_IS_OK(status
)) {
4664 printf("mkdir of %s failed %s!\n", dname
, nt_errstr(status
));
4667 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDONLY
, DENY_NONE
, &fnum1
);
4668 if (!NT_STATUS_IS_OK(status
)) {
4669 printf("open of %s failed %s!\n", fname
, nt_errstr(status
));
4672 status
= cli_close(cli
, fnum1
);
4676 * Note the unlink attribute-type of zero. This should
4677 * map into FILE_ATTRIBUTE_NORMAL at the server even
4678 * on a wildcard delete.
4681 status
= cli_unlink(cli
, wunlink_name
, 0);
4682 if (!NT_STATUS_IS_OK(status
)) {
4683 printf("unlink of %s failed %s!\n",
4684 wunlink_name
, nt_errstr(status
));
4688 printf("finished wildcard delete test\n");
4694 if (fnum1
!= (uint16_t)-1) cli_close(cli
, fnum1
);
4695 cli_unlink(cli
, fname
, 0);
4696 cli_rmdir(cli
, dname
);
4698 if (cli
&& !torture_close_connection(cli
)) {
4704 static bool run_deletetest_ln(int dummy
)
4706 struct cli_state
*cli
;
4707 const char *fname
= "\\delete1";
4708 const char *fname_ln
= "\\delete1_ln";
4712 bool correct
= true;
4715 printf("starting deletetest-ln\n");
4717 if (!torture_open_connection(&cli
, 0)) {
4721 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4722 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4724 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4726 /* Create the file. */
4727 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4728 if (!NT_STATUS_IS_OK(status
)) {
4729 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4733 status
= cli_close(cli
, fnum
);
4734 if (!NT_STATUS_IS_OK(status
)) {
4735 printf("close1 failed (%s)\n", nt_errstr(status
));
4739 /* Now create a hardlink. */
4740 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4741 if (!NT_STATUS_IS_OK(status
)) {
4742 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4746 /* Open the original file. */
4747 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4748 FILE_ATTRIBUTE_NORMAL
,
4749 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4750 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4751 if (!NT_STATUS_IS_OK(status
)) {
4752 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4756 /* Unlink the hard link path. */
4757 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4758 FILE_ATTRIBUTE_NORMAL
,
4759 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4760 FILE_OPEN_IF
, 0, 0, &fnum1
, NULL
);
4761 if (!NT_STATUS_IS_OK(status
)) {
4762 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4765 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4766 if (!NT_STATUS_IS_OK(status
)) {
4767 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4768 __location__
, fname_ln
, nt_errstr(status
));
4772 status
= cli_close(cli
, fnum1
);
4773 if (!NT_STATUS_IS_OK(status
)) {
4774 printf("close %s failed (%s)\n",
4775 fname_ln
, nt_errstr(status
));
4779 status
= cli_close(cli
, fnum
);
4780 if (!NT_STATUS_IS_OK(status
)) {
4781 printf("close %s failed (%s)\n",
4782 fname
, nt_errstr(status
));
4786 /* Ensure the original file is still there. */
4787 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4788 if (!NT_STATUS_IS_OK(status
)) {
4789 printf("%s getatr on file %s failed (%s)\n",
4796 /* Ensure the link path is gone. */
4797 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4798 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4799 printf("%s, getatr for file %s returned wrong error code %s "
4800 "- should have been deleted\n",
4802 fname_ln
, nt_errstr(status
));
4806 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4807 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4809 if (!torture_close_connection(cli
)) {
4813 printf("finished deletetest-ln\n");
4819 print out server properties
4821 static bool run_properties(int dummy
)
4823 struct cli_state
*cli
;
4824 bool correct
= True
;
4826 printf("starting properties test\n");
4830 if (!torture_open_connection(&cli
, 0)) {
4834 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4836 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
4838 if (!torture_close_connection(cli
)) {
4847 /* FIRST_DESIRED_ACCESS 0xf019f */
4848 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4849 FILE_READ_EA| /* 0xf */ \
4850 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4851 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4852 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4853 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4854 /* SECOND_DESIRED_ACCESS 0xe0080 */
4855 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4856 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4857 WRITE_OWNER_ACCESS /* 0xe0000 */
4860 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4861 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4863 WRITE_OWNER_ACCESS /* */
4867 Test ntcreate calls made by xcopy
4869 static bool run_xcopy(int dummy
)
4871 static struct cli_state
*cli1
;
4872 const char *fname
= "\\test.txt";
4873 bool correct
= True
;
4874 uint16_t fnum1
, fnum2
;
4877 printf("starting xcopy test\n");
4879 if (!torture_open_connection(&cli1
, 0)) {
4883 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4884 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4885 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
, NULL
);
4886 if (!NT_STATUS_IS_OK(status
)) {
4887 printf("First open failed - %s\n", nt_errstr(status
));
4891 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4892 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4893 FILE_OPEN
, 0x200000, 0, &fnum2
, NULL
);
4894 if (!NT_STATUS_IS_OK(status
)) {
4895 printf("second open failed - %s\n", nt_errstr(status
));
4899 if (!torture_close_connection(cli1
)) {
4907 Test rename on files open with share delete and no share delete.
4909 static bool run_rename(int dummy
)
4911 static struct cli_state
*cli1
;
4912 const char *fname
= "\\test.txt";
4913 const char *fname1
= "\\test1.txt";
4914 bool correct
= True
;
4919 printf("starting rename test\n");
4921 if (!torture_open_connection(&cli1
, 0)) {
4925 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4926 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4928 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4929 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4930 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4931 if (!NT_STATUS_IS_OK(status
)) {
4932 printf("First open failed - %s\n", nt_errstr(status
));
4936 status
= cli_rename(cli1
, fname
, fname1
, false);
4937 if (!NT_STATUS_IS_OK(status
)) {
4938 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4940 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4944 status
= cli_close(cli1
, fnum1
);
4945 if (!NT_STATUS_IS_OK(status
)) {
4946 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4950 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4951 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4952 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4954 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4956 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4958 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4959 if (!NT_STATUS_IS_OK(status
)) {
4960 printf("Second open failed - %s\n", nt_errstr(status
));
4964 status
= cli_rename(cli1
, fname
, fname1
, false);
4965 if (!NT_STATUS_IS_OK(status
)) {
4966 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4969 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4972 status
= cli_close(cli1
, fnum1
);
4973 if (!NT_STATUS_IS_OK(status
)) {
4974 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4978 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4979 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4981 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4982 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4983 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4984 if (!NT_STATUS_IS_OK(status
)) {
4985 printf("Third open failed - %s\n", nt_errstr(status
));
4994 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4995 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
, NULL
))) {
4996 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4999 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
5000 printf("[8] setting delete_on_close on file failed !\n");
5004 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
5005 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
5011 status
= cli_rename(cli1
, fname
, fname1
, false);
5012 if (!NT_STATUS_IS_OK(status
)) {
5013 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
5016 printf("Third rename succeeded (SHARE_NONE)\n");
5019 status
= cli_close(cli1
, fnum1
);
5020 if (!NT_STATUS_IS_OK(status
)) {
5021 printf("close - 3 failed (%s)\n", nt_errstr(status
));
5025 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5026 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5030 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5031 FILE_ATTRIBUTE_NORMAL
,
5032 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
5033 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5034 if (!NT_STATUS_IS_OK(status
)) {
5035 printf("Fourth open failed - %s\n", nt_errstr(status
));
5039 status
= cli_rename(cli1
, fname
, fname1
, false);
5040 if (!NT_STATUS_IS_OK(status
)) {
5041 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
5043 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
5047 status
= cli_close(cli1
, fnum1
);
5048 if (!NT_STATUS_IS_OK(status
)) {
5049 printf("close - 4 failed (%s)\n", nt_errstr(status
));
5053 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5054 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5058 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5059 FILE_ATTRIBUTE_NORMAL
,
5060 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
5061 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5062 if (!NT_STATUS_IS_OK(status
)) {
5063 printf("Fifth open failed - %s\n", nt_errstr(status
));
5067 status
= cli_rename(cli1
, fname
, fname1
, false);
5068 if (!NT_STATUS_IS_OK(status
)) {
5069 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
5072 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
5076 * Now check if the first name still exists ...
5079 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5080 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5081 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5082 printf("Opening original file after rename of open file fails: %s\n",
5086 printf("Opening original file after rename of open file works ...\n");
5087 (void)cli_close(cli1, fnum2);
5091 status
= cli_close(cli1
, fnum1
);
5092 if (!NT_STATUS_IS_OK(status
)) {
5093 printf("close - 5 failed (%s)\n", nt_errstr(status
));
5097 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5098 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
5099 if (!NT_STATUS_IS_OK(status
)) {
5100 printf("getatr on file %s failed - %s ! \n",
5101 fname1
, nt_errstr(status
));
5104 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
5105 printf("Renamed file %s has wrong attr 0x%x "
5106 "(should be 0x%x)\n",
5109 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
5112 printf("Renamed file %s has archive bit set\n", fname1
);
5116 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5117 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5119 if (!torture_close_connection(cli1
)) {
5127 Test rename into a directory with an ACL denying it.
5129 static bool run_rename_access(int dummy
)
5131 static struct cli_state
*cli
= NULL
;
5132 static struct cli_state
*posix_cli
= NULL
;
5133 const char *src
= "test.txt";
5134 const char *dname
= "dir";
5135 const char *dst
= "dir\\test.txt";
5136 const char *dsrc
= "test.dir";
5137 const char *ddst
= "dir\\test.dir";
5138 uint16_t fnum
= (uint16_t)-1;
5139 struct security_descriptor
*sd
= NULL
;
5140 struct security_descriptor
*newsd
= NULL
;
5142 TALLOC_CTX
*frame
= NULL
;
5144 frame
= talloc_stackframe();
5145 printf("starting rename access test\n");
5147 /* Windows connection. */
5148 if (!torture_open_connection(&cli
, 0)) {
5152 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5154 /* Posix connection. */
5155 if (!torture_open_connection(&posix_cli
, 0)) {
5159 smbXcli_conn_set_sockopt(posix_cli
->conn
, sockops
);
5161 status
= torture_setup_unix_extensions(posix_cli
);
5162 if (!NT_STATUS_IS_OK(status
)) {
5166 /* Start with a clean slate. */
5167 cli_unlink(cli
, src
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5168 cli_unlink(cli
, dst
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5169 cli_rmdir(cli
, dsrc
);
5170 cli_rmdir(cli
, ddst
);
5171 cli_rmdir(cli
, dname
);
5174 * Setup the destination directory with a DENY ACE to
5175 * prevent new files within it.
5177 status
= cli_ntcreate(cli
,
5180 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
|
5181 WRITE_DAC_ACCESS
|FILE_READ_DATA
|
5183 FILE_ATTRIBUTE_DIRECTORY
,
5184 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5186 FILE_DIRECTORY_FILE
,
5190 if (!NT_STATUS_IS_OK(status
)) {
5191 printf("Create of %s - %s\n", dname
, nt_errstr(status
));
5195 status
= cli_query_secdesc(cli
,
5199 if (!NT_STATUS_IS_OK(status
)) {
5200 printf("cli_query_secdesc failed for %s (%s)\n",
5201 dname
, nt_errstr(status
));
5205 newsd
= security_descriptor_dacl_create(frame
,
5210 SEC_ACE_TYPE_ACCESS_DENIED
,
5211 SEC_DIR_ADD_FILE
|SEC_DIR_ADD_SUBDIR
,
5214 if (newsd
== NULL
) {
5217 sd
->dacl
= security_acl_concatenate(frame
,
5220 if (sd
->dacl
== NULL
) {
5223 status
= cli_set_secdesc(cli
, fnum
, sd
);
5224 if (!NT_STATUS_IS_OK(status
)) {
5225 printf("cli_set_secdesc failed for %s (%s)\n",
5226 dname
, nt_errstr(status
));
5229 status
= cli_close(cli
, fnum
);
5230 if (!NT_STATUS_IS_OK(status
)) {
5231 printf("close failed for %s (%s)\n",
5232 dname
, nt_errstr(status
));
5235 /* Now go around the back and chmod to 777 via POSIX. */
5236 status
= cli_posix_chmod(posix_cli
, dname
, 0777);
5237 if (!NT_STATUS_IS_OK(status
)) {
5238 printf("cli_posix_chmod failed for %s (%s)\n",
5239 dname
, nt_errstr(status
));
5243 /* Check we can't create a file within dname via Windows. */
5244 status
= cli_openx(cli
, dst
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5245 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5246 cli_close(posix_cli
, fnum
);
5247 printf("Create of %s should be ACCESS denied, was %s\n",
5248 dst
, nt_errstr(status
));
5252 /* Make the sample file/directory. */
5253 status
= cli_openx(cli
, src
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5254 if (!NT_STATUS_IS_OK(status
)) {
5255 printf("open of %s failed (%s)\n", src
, nt_errstr(status
));
5258 status
= cli_close(cli
, fnum
);
5259 if (!NT_STATUS_IS_OK(status
)) {
5260 printf("cli_close failed (%s)\n", nt_errstr(status
));
5264 status
= cli_mkdir(cli
, dsrc
);
5265 if (!NT_STATUS_IS_OK(status
)) {
5266 printf("cli_mkdir of %s failed (%s)\n",
5267 dsrc
, nt_errstr(status
));
5272 * OK - renames of the new file and directory into the
5273 * dst directory should fail.
5276 status
= cli_rename(cli
, src
, dst
, false);
5277 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5278 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5279 src
, dst
, nt_errstr(status
));
5282 status
= cli_rename(cli
, dsrc
, ddst
, false);
5283 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5284 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5285 src
, dst
, nt_errstr(status
));
5295 torture_close_connection(posix_cli
);
5299 if (fnum
!= (uint16_t)-1) {
5300 cli_close(cli
, fnum
);
5302 cli_unlink(cli
, src
,
5303 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5304 cli_unlink(cli
, dst
,
5305 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5306 cli_rmdir(cli
, dsrc
);
5307 cli_rmdir(cli
, ddst
);
5308 cli_rmdir(cli
, dname
);
5310 torture_close_connection(cli
);
5318 Test owner rights ACE.
5320 static bool run_owner_rights(int dummy
)
5322 static struct cli_state
*cli
= NULL
;
5323 const char *fname
= "owner_rights.txt";
5324 uint16_t fnum
= (uint16_t)-1;
5325 struct security_descriptor
*sd
= NULL
;
5326 struct security_descriptor
*newsd
= NULL
;
5328 TALLOC_CTX
*frame
= NULL
;
5330 frame
= talloc_stackframe();
5331 printf("starting owner rights test\n");
5333 /* Windows connection. */
5334 if (!torture_open_connection(&cli
, 0)) {
5338 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5340 /* Start with a clean slate. */
5341 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5343 /* Create the test file. */
5344 /* Now try and open for read and write-dac. */
5345 status
= cli_ntcreate(cli
,
5349 FILE_ATTRIBUTE_NORMAL
,
5350 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5357 if (!NT_STATUS_IS_OK(status
)) {
5358 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5362 /* Get the original SD. */
5363 status
= cli_query_secdesc(cli
,
5367 if (!NT_STATUS_IS_OK(status
)) {
5368 printf("cli_query_secdesc failed for %s (%s)\n",
5369 fname
, nt_errstr(status
));
5374 * Add an "owner-rights" ACE denying WRITE_DATA,
5375 * and an "owner-rights" ACE allowing READ_DATA.
5378 newsd
= security_descriptor_dacl_create(frame
,
5383 SEC_ACE_TYPE_ACCESS_DENIED
,
5387 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5391 if (newsd
== NULL
) {
5394 sd
->dacl
= security_acl_concatenate(frame
,
5397 if (sd
->dacl
== NULL
) {
5400 status
= cli_set_secdesc(cli
, fnum
, sd
);
5401 if (!NT_STATUS_IS_OK(status
)) {
5402 printf("cli_set_secdesc failed for %s (%s)\n",
5403 fname
, nt_errstr(status
));
5406 status
= cli_close(cli
, fnum
);
5407 if (!NT_STATUS_IS_OK(status
)) {
5408 printf("close failed for %s (%s)\n",
5409 fname
, nt_errstr(status
));
5412 fnum
= (uint16_t)-1;
5414 /* Try and open for FILE_WRITE_DATA */
5415 status
= cli_ntcreate(cli
,
5419 FILE_ATTRIBUTE_NORMAL
,
5420 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5427 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5428 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5432 /* Now try and open for FILE_READ_DATA */
5433 status
= cli_ntcreate(cli
,
5437 FILE_ATTRIBUTE_NORMAL
,
5438 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5445 if (!NT_STATUS_IS_OK(status
)) {
5446 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5450 status
= cli_close(cli
, fnum
);
5451 if (!NT_STATUS_IS_OK(status
)) {
5452 printf("close failed for %s (%s)\n",
5453 fname
, nt_errstr(status
));
5457 /* Restore clean slate. */
5459 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5461 /* Create the test file. */
5462 status
= cli_ntcreate(cli
,
5466 FILE_ATTRIBUTE_NORMAL
,
5467 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5474 if (!NT_STATUS_IS_OK(status
)) {
5475 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5479 /* Get the original SD. */
5480 status
= cli_query_secdesc(cli
,
5484 if (!NT_STATUS_IS_OK(status
)) {
5485 printf("cli_query_secdesc failed for %s (%s)\n",
5486 fname
, nt_errstr(status
));
5491 * Add an "owner-rights ACE denying WRITE_DATA,
5492 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5495 newsd
= security_descriptor_dacl_create(frame
,
5500 SEC_ACE_TYPE_ACCESS_DENIED
,
5504 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5505 FILE_READ_DATA
|FILE_WRITE_DATA
,
5508 if (newsd
== NULL
) {
5511 sd
->dacl
= security_acl_concatenate(frame
,
5514 if (sd
->dacl
== NULL
) {
5517 status
= cli_set_secdesc(cli
, fnum
, sd
);
5518 if (!NT_STATUS_IS_OK(status
)) {
5519 printf("cli_set_secdesc failed for %s (%s)\n",
5520 fname
, nt_errstr(status
));
5523 status
= cli_close(cli
, fnum
);
5524 if (!NT_STATUS_IS_OK(status
)) {
5525 printf("close failed for %s (%s)\n",
5526 fname
, nt_errstr(status
));
5529 fnum
= (uint16_t)-1;
5531 /* Try and open for FILE_WRITE_DATA */
5532 status
= cli_ntcreate(cli
,
5536 FILE_ATTRIBUTE_NORMAL
,
5537 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5544 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5545 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5549 /* Now try and open for FILE_READ_DATA */
5550 status
= cli_ntcreate(cli
,
5554 FILE_ATTRIBUTE_NORMAL
,
5555 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5562 if (!NT_STATUS_IS_OK(status
)) {
5563 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5567 status
= cli_close(cli
, fnum
);
5568 if (!NT_STATUS_IS_OK(status
)) {
5569 printf("close failed for %s (%s)\n",
5570 fname
, nt_errstr(status
));
5574 /* Restore clean slate. */
5576 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5579 /* Create the test file. */
5580 status
= cli_ntcreate(cli
,
5584 FILE_ATTRIBUTE_NORMAL
,
5585 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5592 if (!NT_STATUS_IS_OK(status
)) {
5593 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
5597 /* Get the original SD. */
5598 status
= cli_query_secdesc(cli
,
5602 if (!NT_STATUS_IS_OK(status
)) {
5603 printf("cli_query_secdesc failed for %s (%s)\n",
5604 fname
, nt_errstr(status
));
5609 * Add an "authenticated users" ACE allowing READ_DATA,
5610 * add an "owner-rights" denying READ_DATA,
5611 * and an "authenticated users" ACE allowing WRITE_DATA.
5614 newsd
= security_descriptor_dacl_create(frame
,
5618 SID_NT_AUTHENTICATED_USERS
,
5619 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5623 SEC_ACE_TYPE_ACCESS_DENIED
,
5626 SID_NT_AUTHENTICATED_USERS
,
5627 SEC_ACE_TYPE_ACCESS_ALLOWED
,
5631 if (newsd
== NULL
) {
5632 printf("newsd == NULL\n");
5635 sd
->dacl
= security_acl_concatenate(frame
,
5638 if (sd
->dacl
== NULL
) {
5639 printf("sd->dacl == NULL\n");
5642 status
= cli_set_secdesc(cli
, fnum
, sd
);
5643 if (!NT_STATUS_IS_OK(status
)) {
5644 printf("cli_set_secdesc failed for %s (%s)\n",
5645 fname
, nt_errstr(status
));
5648 status
= cli_close(cli
, fnum
);
5649 if (!NT_STATUS_IS_OK(status
)) {
5650 printf("close failed for %s (%s)\n",
5651 fname
, nt_errstr(status
));
5654 fnum
= (uint16_t)-1;
5656 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5657 status
= cli_ntcreate(cli
,
5660 FILE_READ_DATA
|FILE_WRITE_DATA
,
5661 FILE_ATTRIBUTE_NORMAL
,
5662 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5669 if (!NT_STATUS_IS_OK(status
)) {
5670 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
5674 status
= cli_close(cli
, fnum
);
5675 if (!NT_STATUS_IS_OK(status
)) {
5676 printf("close failed for %s (%s)\n",
5677 fname
, nt_errstr(status
));
5681 cli_unlink(cli
, fname
,
5682 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5690 if (fnum
!= (uint16_t)-1) {
5691 cli_close(cli
, fnum
);
5693 cli_unlink(cli
, fname
,
5694 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5695 torture_close_connection(cli
);
5702 static bool run_pipe_number(int dummy
)
5704 struct cli_state
*cli1
;
5705 const char *pipe_name
= "\\SPOOLSS";
5710 printf("starting pipenumber test\n");
5711 if (!torture_open_connection(&cli1
, 0)) {
5715 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5717 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
5718 FILE_ATTRIBUTE_NORMAL
,
5719 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5720 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
5721 if (!NT_STATUS_IS_OK(status
)) {
5722 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
5726 printf("\r%6d", num_pipes
);
5729 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
5730 torture_close_connection(cli1
);
5735 Test open mode returns on read-only files.
5737 static bool run_opentest(int dummy
)
5739 static struct cli_state
*cli1
;
5740 static struct cli_state
*cli2
;
5741 const char *fname
= "\\readonly.file";
5742 uint16_t fnum1
, fnum2
;
5745 bool correct
= True
;
5749 printf("starting open test\n");
5751 if (!torture_open_connection(&cli1
, 0)) {
5755 cli_setatr(cli1
, fname
, 0, 0);
5756 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5758 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5760 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
5761 if (!NT_STATUS_IS_OK(status
)) {
5762 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5766 status
= cli_close(cli1
, fnum1
);
5767 if (!NT_STATUS_IS_OK(status
)) {
5768 printf("close2 failed (%s)\n", nt_errstr(status
));
5772 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
5773 if (!NT_STATUS_IS_OK(status
)) {
5774 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
5778 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
5779 if (!NT_STATUS_IS_OK(status
)) {
5780 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5784 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5785 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
5787 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
5788 NT_STATUS_ACCESS_DENIED
)) {
5789 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5792 printf("finished open test 1\n");
5794 cli_close(cli1
, fnum1
);
5796 /* Now try not readonly and ensure ERRbadshare is returned. */
5798 cli_setatr(cli1
, fname
, 0, 0);
5800 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
5801 if (!NT_STATUS_IS_OK(status
)) {
5802 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5806 /* This will fail - but the error should be ERRshare. */
5807 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
5809 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
5810 NT_STATUS_SHARING_VIOLATION
)) {
5811 printf("correct error code ERRDOS/ERRbadshare returned\n");
5814 status
= cli_close(cli1
, fnum1
);
5815 if (!NT_STATUS_IS_OK(status
)) {
5816 printf("close2 failed (%s)\n", nt_errstr(status
));
5820 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5822 printf("finished open test 2\n");
5824 /* Test truncate open disposition on file opened for read. */
5825 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
5826 if (!NT_STATUS_IS_OK(status
)) {
5827 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
5831 /* write 20 bytes. */
5833 memset(buf
, '\0', 20);
5835 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
5836 if (!NT_STATUS_IS_OK(status
)) {
5837 printf("write failed (%s)\n", nt_errstr(status
));
5841 status
= cli_close(cli1
, fnum1
);
5842 if (!NT_STATUS_IS_OK(status
)) {
5843 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
5847 /* Ensure size == 20. */
5848 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5849 if (!NT_STATUS_IS_OK(status
)) {
5850 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5855 printf("(3) file size != 20\n");
5859 /* Now test if we can truncate a file opened for readonly. */
5860 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
5861 if (!NT_STATUS_IS_OK(status
)) {
5862 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
5866 status
= cli_close(cli1
, fnum1
);
5867 if (!NT_STATUS_IS_OK(status
)) {
5868 printf("close2 failed (%s)\n", nt_errstr(status
));
5872 /* Ensure size == 0. */
5873 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5874 if (!NT_STATUS_IS_OK(status
)) {
5875 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5880 printf("(3) file size != 0\n");
5883 printf("finished open test 3\n");
5885 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5887 printf("Do ctemp tests\n");
5888 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
5889 if (!NT_STATUS_IS_OK(status
)) {
5890 printf("ctemp failed (%s)\n", nt_errstr(status
));
5894 printf("ctemp gave path %s\n", tmp_path
);
5895 status
= cli_close(cli1
, fnum1
);
5896 if (!NT_STATUS_IS_OK(status
)) {
5897 printf("close of temp failed (%s)\n", nt_errstr(status
));
5900 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5901 if (!NT_STATUS_IS_OK(status
)) {
5902 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5905 /* Test the non-io opens... */
5907 if (!torture_open_connection(&cli2
, 1)) {
5911 cli_setatr(cli2
, fname
, 0, 0);
5912 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5914 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
5916 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5917 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5918 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5919 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5920 if (!NT_STATUS_IS_OK(status
)) {
5921 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5925 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5926 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5927 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5928 if (!NT_STATUS_IS_OK(status
)) {
5929 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5933 status
= cli_close(cli1
, fnum1
);
5934 if (!NT_STATUS_IS_OK(status
)) {
5935 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5939 status
= cli_close(cli2
, fnum2
);
5940 if (!NT_STATUS_IS_OK(status
)) {
5941 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5945 printf("non-io open test #1 passed.\n");
5947 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5949 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5951 status
= cli_ntcreate(cli1
, fname
, 0,
5952 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5953 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5954 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5955 if (!NT_STATUS_IS_OK(status
)) {
5956 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5960 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5961 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5962 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5963 if (!NT_STATUS_IS_OK(status
)) {
5964 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5968 status
= cli_close(cli1
, fnum1
);
5969 if (!NT_STATUS_IS_OK(status
)) {
5970 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5974 status
= cli_close(cli2
, fnum2
);
5975 if (!NT_STATUS_IS_OK(status
)) {
5976 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5980 printf("non-io open test #2 passed.\n");
5982 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5984 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5986 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5987 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5988 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5989 if (!NT_STATUS_IS_OK(status
)) {
5990 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5994 status
= cli_ntcreate(cli2
, fname
, 0,
5995 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5996 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5997 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5998 if (!NT_STATUS_IS_OK(status
)) {
5999 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6003 status
= cli_close(cli1
, fnum1
);
6004 if (!NT_STATUS_IS_OK(status
)) {
6005 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6009 status
= cli_close(cli2
, fnum2
);
6010 if (!NT_STATUS_IS_OK(status
)) {
6011 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6015 printf("non-io open test #3 passed.\n");
6017 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6019 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
6021 status
= cli_ntcreate(cli1
, fname
, 0,
6022 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
6023 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
6024 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6025 if (!NT_STATUS_IS_OK(status
)) {
6026 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6030 status
= cli_ntcreate(cli2
, fname
, 0,
6031 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
6032 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
6033 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
6034 if (NT_STATUS_IS_OK(status
)) {
6035 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
6039 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
6041 status
= cli_close(cli1
, fnum1
);
6042 if (!NT_STATUS_IS_OK(status
)) {
6043 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6047 printf("non-io open test #4 passed.\n");
6049 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6051 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
6053 status
= cli_ntcreate(cli1
, fname
, 0,
6054 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
6055 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
6056 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6057 if (!NT_STATUS_IS_OK(status
)) {
6058 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6062 status
= cli_ntcreate(cli2
, fname
, 0,
6063 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
6064 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
6065 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
6066 if (!NT_STATUS_IS_OK(status
)) {
6067 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6071 status
= cli_close(cli1
, fnum1
);
6072 if (!NT_STATUS_IS_OK(status
)) {
6073 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6077 status
= cli_close(cli2
, fnum2
);
6078 if (!NT_STATUS_IS_OK(status
)) {
6079 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6083 printf("non-io open test #5 passed.\n");
6085 printf("TEST #6 testing 1 non-io open, one io open\n");
6087 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6089 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
6090 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
6091 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6092 if (!NT_STATUS_IS_OK(status
)) {
6093 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6097 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
6098 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6099 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
6100 if (!NT_STATUS_IS_OK(status
)) {
6101 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6105 status
= cli_close(cli1
, fnum1
);
6106 if (!NT_STATUS_IS_OK(status
)) {
6107 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6111 status
= cli_close(cli2
, fnum2
);
6112 if (!NT_STATUS_IS_OK(status
)) {
6113 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
6117 printf("non-io open test #6 passed.\n");
6119 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6121 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6123 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
6124 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
6125 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6126 if (!NT_STATUS_IS_OK(status
)) {
6127 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6131 status
= cli_ntcreate(cli2
, fname
, 0,
6132 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
6133 FILE_ATTRIBUTE_NORMAL
,
6134 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
6135 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
6136 if (NT_STATUS_IS_OK(status
)) {
6137 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
6141 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
6143 status
= cli_close(cli1
, fnum1
);
6144 if (!NT_STATUS_IS_OK(status
)) {
6145 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
6149 printf("non-io open test #7 passed.\n");
6151 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6153 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6154 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
6155 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6156 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6157 if (!NT_STATUS_IS_OK(status
)) {
6158 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
6163 /* Write to ensure we have to update the file time. */
6164 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6166 if (!NT_STATUS_IS_OK(status
)) {
6167 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
6172 status
= cli_close(cli1
, fnum1
);
6173 if (!NT_STATUS_IS_OK(status
)) {
6174 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
6180 if (!torture_close_connection(cli1
)) {
6183 if (!torture_close_connection(cli2
)) {
6190 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
6192 uint16_t major
, minor
;
6193 uint32_t caplow
, caphigh
;
6196 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
6197 printf("Server doesn't support UNIX CIFS extensions.\n");
6198 return NT_STATUS_NOT_SUPPORTED
;
6201 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
6203 if (!NT_STATUS_IS_OK(status
)) {
6204 printf("Server didn't return UNIX CIFS extensions: %s\n",
6209 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
6211 if (!NT_STATUS_IS_OK(status
)) {
6212 printf("Server doesn't support setting UNIX CIFS extensions: "
6213 "%s.\n", nt_errstr(status
));
6217 return NT_STATUS_OK
;
6221 Test POSIX open /mkdir calls.
6223 static bool run_simple_posix_open_test(int dummy
)
6225 static struct cli_state
*cli1
;
6226 const char *fname
= "posix:file";
6227 const char *hname
= "posix:hlink";
6228 const char *sname
= "posix:symlink";
6229 const char *dname
= "posix:dir";
6232 uint16_t fnum1
= (uint16_t)-1;
6233 SMB_STRUCT_STAT sbuf
;
6234 bool correct
= false;
6237 const char *fname_windows
= "windows_file";
6238 uint16_t fnum2
= (uint16_t)-1;
6240 printf("Starting simple POSIX open test\n");
6242 if (!torture_open_connection(&cli1
, 0)) {
6246 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6248 status
= torture_setup_unix_extensions(cli1
);
6249 if (!NT_STATUS_IS_OK(status
)) {
6253 cli_setatr(cli1
, fname
, 0, 0);
6254 cli_posix_unlink(cli1
, fname
);
6255 cli_setatr(cli1
, dname
, 0, 0);
6256 cli_posix_rmdir(cli1
, dname
);
6257 cli_setatr(cli1
, hname
, 0, 0);
6258 cli_posix_unlink(cli1
, hname
);
6259 cli_setatr(cli1
, sname
, 0, 0);
6260 cli_posix_unlink(cli1
, sname
);
6261 cli_setatr(cli1
, fname_windows
, 0, 0);
6262 cli_posix_unlink(cli1
, fname_windows
);
6264 /* Create a directory. */
6265 status
= cli_posix_mkdir(cli1
, dname
, 0777);
6266 if (!NT_STATUS_IS_OK(status
)) {
6267 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
6271 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6273 if (!NT_STATUS_IS_OK(status
)) {
6274 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6278 /* Test ftruncate - set file size. */
6279 status
= cli_ftruncate(cli1
, fnum1
, 1000);
6280 if (!NT_STATUS_IS_OK(status
)) {
6281 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6285 /* Ensure st_size == 1000 */
6286 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6287 if (!NT_STATUS_IS_OK(status
)) {
6288 printf("stat failed (%s)\n", nt_errstr(status
));
6292 if (sbuf
.st_ex_size
!= 1000) {
6293 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
6297 /* Ensure st_mode == 0600 */
6298 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
6299 printf("posix_open - bad permissions 0%o != 0600\n",
6300 (unsigned int)(sbuf
.st_ex_mode
& 07777));
6304 /* Test ftruncate - set file size back to zero. */
6305 status
= cli_ftruncate(cli1
, fnum1
, 0);
6306 if (!NT_STATUS_IS_OK(status
)) {
6307 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6311 status
= cli_close(cli1
, fnum1
);
6312 if (!NT_STATUS_IS_OK(status
)) {
6313 printf("close failed (%s)\n", nt_errstr(status
));
6317 /* Now open the file again for read only. */
6318 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
6319 if (!NT_STATUS_IS_OK(status
)) {
6320 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
6324 /* Now unlink while open. */
6325 status
= cli_posix_unlink(cli1
, fname
);
6326 if (!NT_STATUS_IS_OK(status
)) {
6327 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
6331 status
= cli_close(cli1
, fnum1
);
6332 if (!NT_STATUS_IS_OK(status
)) {
6333 printf("close(2) failed (%s)\n", nt_errstr(status
));
6337 /* Ensure the file has gone. */
6338 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
6339 if (NT_STATUS_IS_OK(status
)) {
6340 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
6344 /* Create again to test open with O_TRUNC. */
6345 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
6346 if (!NT_STATUS_IS_OK(status
)) {
6347 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6351 /* Test ftruncate - set file size. */
6352 status
= cli_ftruncate(cli1
, fnum1
, 1000);
6353 if (!NT_STATUS_IS_OK(status
)) {
6354 printf("ftruncate failed (%s)\n", nt_errstr(status
));
6358 /* Ensure st_size == 1000 */
6359 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6360 if (!NT_STATUS_IS_OK(status
)) {
6361 printf("stat failed (%s)\n", nt_errstr(status
));
6365 if (sbuf
.st_ex_size
!= 1000) {
6366 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
6370 status
= cli_close(cli1
, fnum1
);
6371 if (!NT_STATUS_IS_OK(status
)) {
6372 printf("close(2) failed (%s)\n", nt_errstr(status
));
6376 /* Re-open with O_TRUNC. */
6377 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
6378 if (!NT_STATUS_IS_OK(status
)) {
6379 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6383 /* Ensure st_size == 0 */
6384 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
6385 if (!NT_STATUS_IS_OK(status
)) {
6386 printf("stat failed (%s)\n", nt_errstr(status
));
6390 if (sbuf
.st_ex_size
!= 0) {
6391 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
6395 status
= cli_close(cli1
, fnum1
);
6396 if (!NT_STATUS_IS_OK(status
)) {
6397 printf("close failed (%s)\n", nt_errstr(status
));
6401 status
= cli_posix_unlink(cli1
, fname
);
6402 if (!NT_STATUS_IS_OK(status
)) {
6403 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
6407 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
6408 if (!NT_STATUS_IS_OK(status
)) {
6409 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6410 dname
, nt_errstr(status
));
6414 cli_close(cli1
, fnum1
);
6416 /* What happens when we try and POSIX open a directory for write ? */
6417 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
6418 if (NT_STATUS_IS_OK(status
)) {
6419 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
6422 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
6423 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
6428 /* Create the file. */
6429 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
6431 if (!NT_STATUS_IS_OK(status
)) {
6432 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
6436 /* Write some data into it. */
6437 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6439 if (!NT_STATUS_IS_OK(status
)) {
6440 printf("cli_write failed: %s\n", nt_errstr(status
));
6444 cli_close(cli1
, fnum1
);
6446 /* Now create a hardlink. */
6447 status
= cli_posix_hardlink(cli1
, fname
, hname
);
6448 if (!NT_STATUS_IS_OK(status
)) {
6449 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
6453 /* Now create a symlink. */
6454 status
= cli_posix_symlink(cli1
, fname
, sname
);
6455 if (!NT_STATUS_IS_OK(status
)) {
6456 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
6460 /* Open the hardlink for read. */
6461 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
6462 if (!NT_STATUS_IS_OK(status
)) {
6463 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
6467 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
6468 if (!NT_STATUS_IS_OK(status
)) {
6469 printf("POSIX read of %s failed (%s)\n", hname
,
6472 } else if (nread
!= 10) {
6473 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6474 hname
, (unsigned long)nread
, 10);
6478 if (memcmp(buf
, "TEST DATA\n", 10)) {
6479 printf("invalid data read from hardlink\n");
6483 /* Do a POSIX lock/unlock. */
6484 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
6485 if (!NT_STATUS_IS_OK(status
)) {
6486 printf("POSIX lock failed %s\n", nt_errstr(status
));
6490 /* Punch a hole in the locked area. */
6491 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
6492 if (!NT_STATUS_IS_OK(status
)) {
6493 printf("POSIX unlock failed %s\n", nt_errstr(status
));
6497 cli_close(cli1
, fnum1
);
6499 /* Open the symlink for read - this should fail. A POSIX
6500 client should not be doing opens on a symlink. */
6501 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
6502 if (NT_STATUS_IS_OK(status
)) {
6503 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
6506 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6507 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
6508 printf("POSIX open of %s should have failed "
6509 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6510 "failed with %s instead.\n",
6511 sname
, nt_errstr(status
));
6516 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
6517 if (!NT_STATUS_IS_OK(status
)) {
6518 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
6522 if (strcmp(namebuf
, fname
) != 0) {
6523 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6524 sname
, fname
, namebuf
);
6528 status
= cli_posix_rmdir(cli1
, dname
);
6529 if (!NT_STATUS_IS_OK(status
)) {
6530 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
6534 /* Check directory opens with a specific permission. */
6535 status
= cli_posix_mkdir(cli1
, dname
, 0700);
6536 if (!NT_STATUS_IS_OK(status
)) {
6537 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
6541 /* Ensure st_mode == 0700 */
6542 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
6543 if (!NT_STATUS_IS_OK(status
)) {
6544 printf("stat failed (%s)\n", nt_errstr(status
));
6548 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
6549 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6550 (unsigned int)(sbuf
.st_ex_mode
& 07777));
6555 * Now create a Windows file, and attempt a POSIX unlink.
6556 * This should fail with a sharing violation but due to:
6558 * [Bug 9571] Unlink after open causes smbd to panic
6560 * ensure we've fixed the lock ordering violation.
6563 status
= cli_ntcreate(cli1
, fname_windows
, 0,
6564 FILE_READ_DATA
|FILE_WRITE_DATA
, 0,
6565 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6567 0x0, 0x0, &fnum2
, NULL
);
6568 if (!NT_STATUS_IS_OK(status
)) {
6569 printf("Windows create of %s failed (%s)\n", fname_windows
,
6574 /* Now try posix_unlink. */
6575 status
= cli_posix_unlink(cli1
, fname_windows
);
6576 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6577 printf("POSIX unlink of %s should fail "
6578 "with NT_STATUS_SHARING_VIOLATION "
6579 "got %s instead !\n",
6585 cli_close(cli1
, fnum2
);
6587 printf("Simple POSIX open test passed\n");
6592 if (fnum1
!= (uint16_t)-1) {
6593 cli_close(cli1
, fnum1
);
6594 fnum1
= (uint16_t)-1;
6597 if (fnum2
!= (uint16_t)-1) {
6598 cli_close(cli1
, fnum2
);
6599 fnum2
= (uint16_t)-1;
6602 cli_setatr(cli1
, sname
, 0, 0);
6603 cli_posix_unlink(cli1
, sname
);
6604 cli_setatr(cli1
, hname
, 0, 0);
6605 cli_posix_unlink(cli1
, hname
);
6606 cli_setatr(cli1
, fname
, 0, 0);
6607 cli_posix_unlink(cli1
, fname
);
6608 cli_setatr(cli1
, dname
, 0, 0);
6609 cli_posix_rmdir(cli1
, dname
);
6610 cli_setatr(cli1
, fname_windows
, 0, 0);
6611 cli_posix_unlink(cli1
, fname_windows
);
6613 if (!torture_close_connection(cli1
)) {
6621 Test POSIX and Windows ACLs are rejected on symlinks.
6623 static bool run_acl_symlink_test(int dummy
)
6625 static struct cli_state
*cli
;
6626 const char *fname
= "posix_file";
6627 const char *sname
= "posix_symlink";
6628 uint16_t fnum
= (uint16_t)-1;
6629 bool correct
= false;
6631 char *posix_acl
= NULL
;
6632 size_t posix_acl_len
= 0;
6633 char *posix_acl_sym
= NULL
;
6634 size_t posix_acl_len_sym
= 0;
6635 struct security_descriptor
*sd
= NULL
;
6636 struct security_descriptor
*sd_sym
= NULL
;
6637 TALLOC_CTX
*frame
= NULL
;
6639 frame
= talloc_stackframe();
6641 printf("Starting acl symlink test\n");
6643 if (!torture_open_connection(&cli
, 0)) {
6648 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6650 status
= torture_setup_unix_extensions(cli
);
6651 if (!NT_STATUS_IS_OK(status
)) {
6656 cli_setatr(cli
, fname
, 0, 0);
6657 cli_posix_unlink(cli
, fname
);
6658 cli_setatr(cli
, sname
, 0, 0);
6659 cli_posix_unlink(cli
, sname
);
6661 status
= cli_ntcreate(cli
,
6664 READ_CONTROL_ACCESS
,
6666 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6673 if (!NT_STATUS_IS_OK(status
)) {
6674 printf("cli_ntcreate of %s failed (%s)\n",
6680 /* Get the Windows ACL on the file. */
6681 status
= cli_query_secdesc(cli
,
6685 if (!NT_STATUS_IS_OK(status
)) {
6686 printf("cli_query_secdesc failed (%s)\n",
6691 /* Get the POSIX ACL on the file. */
6692 status
= cli_posix_getacl(cli
,
6698 if (!NT_STATUS_IS_OK(status
)) {
6699 printf("cli_posix_getacl failed (%s)\n",
6704 status
= cli_close(cli
, fnum
);
6705 if (!NT_STATUS_IS_OK(status
)) {
6706 printf("close failed (%s)\n", nt_errstr(status
));
6709 fnum
= (uint16_t)-1;
6711 /* Now create a symlink. */
6712 status
= cli_posix_symlink(cli
, fname
, sname
);
6713 if (!NT_STATUS_IS_OK(status
)) {
6714 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6721 /* Open a handle on the symlink. */
6722 status
= cli_ntcreate(cli
,
6725 READ_CONTROL_ACCESS
|SEC_STD_WRITE_DAC
,
6727 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6734 if (!NT_STATUS_IS_OK(status
)) {
6735 printf("cli_posix_open of %s failed (%s)\n",
6741 /* Get the Windows ACL on the symlink handle. Should fail */
6742 status
= cli_query_secdesc(cli
,
6747 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6748 printf("cli_query_secdesc on a symlink gave %s. "
6749 "Should be NT_STATUS_ACCESS_DENIED.\n",
6754 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6755 status
= cli_posix_getacl(cli
,
6761 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6762 printf("cli_posix_getacl on a symlink gave %s. "
6763 "Should be NT_STATUS_ACCESS_DENIED.\n",
6768 /* Set the Windows ACL on the symlink handle. Should fail */
6769 status
= cli_set_security_descriptor(cli
,
6774 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6775 printf("cli_query_secdesc on a symlink gave %s. "
6776 "Should be NT_STATUS_ACCESS_DENIED.\n",
6781 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6782 status
= cli_posix_setacl(cli
,
6787 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6788 printf("cli_posix_getacl on a symlink gave %s. "
6789 "Should be NT_STATUS_ACCESS_DENIED.\n",
6794 printf("ACL symlink test passed\n");
6799 if (fnum
!= (uint16_t)-1) {
6800 cli_close(cli
, fnum
);
6801 fnum
= (uint16_t)-1;
6804 cli_setatr(cli
, sname
, 0, 0);
6805 cli_posix_unlink(cli
, sname
);
6806 cli_setatr(cli
, fname
, 0, 0);
6807 cli_posix_unlink(cli
, fname
);
6809 if (!torture_close_connection(cli
)) {
6818 Test POSIX can delete a file containing streams.
6820 static bool run_posix_stream_delete(int dummy
)
6822 struct cli_state
*cli1
= NULL
;
6823 struct cli_state
*cli2
= NULL
;
6824 const char *fname
= "streamfile";
6825 const char *stream_fname
= "streamfile:Zone.Identifier:$DATA";
6826 uint16_t fnum1
= (uint16_t)-1;
6827 bool correct
= false;
6829 TALLOC_CTX
*frame
= NULL
;
6831 frame
= talloc_stackframe();
6833 printf("Starting POSIX stream delete test\n");
6835 if (!torture_open_connection(&cli1
, 0) ||
6836 !torture_open_connection(&cli2
, 1)) {
6841 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6842 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
6844 status
= torture_setup_unix_extensions(cli2
);
6845 if (!NT_STATUS_IS_OK(status
)) {
6849 cli_setatr(cli1
, fname
, 0, 0);
6850 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6852 /* Create the file. */
6853 status
= cli_ntcreate(cli1
,
6856 READ_CONTROL_ACCESS
,
6858 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6865 if (!NT_STATUS_IS_OK(status
)) {
6866 printf("cli_ntcreate of %s failed (%s)\n",
6872 status
= cli_close(cli1
, fnum1
);
6873 if (!NT_STATUS_IS_OK(status
)) {
6874 printf("cli_close of %s failed (%s)\n",
6879 fnum1
= (uint16_t)-1;
6881 /* Now create the stream. */
6882 status
= cli_ntcreate(cli1
,
6887 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6894 if (!NT_STATUS_IS_OK(status
)) {
6895 printf("cli_ntcreate of %s failed (%s)\n",
6901 /* Leave the stream handle open... */
6903 /* POSIX unlink should fail. */
6904 status
= cli_posix_unlink(cli2
, fname
);
6905 if (NT_STATUS_IS_OK(status
)) {
6906 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6911 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6912 printf("cli_posix_unlink of %s failed with (%s) "
6913 "should have been NT_STATUS_SHARING_VIOLATION\n",
6919 /* Close the stream handle. */
6920 status
= cli_close(cli1
, fnum1
);
6921 if (!NT_STATUS_IS_OK(status
)) {
6922 printf("cli_close of %s failed (%s)\n",
6927 fnum1
= (uint16_t)-1;
6929 /* POSIX unlink after stream handle closed should succeed. */
6930 status
= cli_posix_unlink(cli2
, fname
);
6931 if (!NT_STATUS_IS_OK(status
)) {
6932 printf("cli_posix_unlink of %s failed (%s)\n",
6938 printf("POSIX stream delete test passed\n");
6943 if (fnum1
!= (uint16_t)-1) {
6944 cli_close(cli1
, fnum1
);
6945 fnum1
= (uint16_t)-1;
6948 cli_setatr(cli1
, fname
, 0, 0);
6949 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6951 if (!torture_close_connection(cli1
)) {
6954 if (!torture_close_connection(cli2
)) {
6963 Test setting EA's are rejected on symlinks.
6965 static bool run_ea_symlink_test(int dummy
)
6967 static struct cli_state
*cli
;
6968 const char *fname
= "posix_file_ea";
6969 const char *sname
= "posix_symlink_ea";
6970 const char *ea_name
= "testea_name";
6971 const char *ea_value
= "testea_value";
6972 uint16_t fnum
= (uint16_t)-1;
6973 bool correct
= false;
6976 struct ea_struct
*eas
= NULL
;
6977 TALLOC_CTX
*frame
= NULL
;
6979 frame
= talloc_stackframe();
6981 printf("Starting EA symlink test\n");
6983 if (!torture_open_connection(&cli
, 0)) {
6988 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6990 status
= torture_setup_unix_extensions(cli
);
6991 if (!NT_STATUS_IS_OK(status
)) {
6996 cli_setatr(cli
, fname
, 0, 0);
6997 cli_posix_unlink(cli
, fname
);
6998 cli_setatr(cli
, sname
, 0, 0);
6999 cli_posix_unlink(cli
, sname
);
7001 status
= cli_ntcreate(cli
,
7004 READ_CONTROL_ACCESS
,
7006 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
7013 if (!NT_STATUS_IS_OK(status
)) {
7014 printf("cli_ntcreate of %s failed (%s)\n",
7020 status
= cli_close(cli
, fnum
);
7021 if (!NT_STATUS_IS_OK(status
)) {
7022 printf("close failed (%s)\n",
7026 fnum
= (uint16_t)-1;
7028 /* Set an EA on the path. */
7029 status
= cli_set_ea_path(cli
,
7033 strlen(ea_value
)+1);
7035 if (!NT_STATUS_IS_OK(status
)) {
7036 printf("cli_set_ea_path failed (%s)\n",
7041 /* Now create a symlink. */
7042 status
= cli_posix_symlink(cli
, fname
, sname
);
7043 if (!NT_STATUS_IS_OK(status
)) {
7044 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
7051 /* Get the EA list on the path. Should return value set. */
7052 status
= cli_get_ea_list_path(cli
,
7058 if (!NT_STATUS_IS_OK(status
)) {
7059 printf("cli_get_ea_list_path failed (%s)\n",
7064 /* Ensure the EA we set is there. */
7065 for (i
=0; i
<num_eas
; i
++) {
7066 if (strcmp(eas
[i
].name
, ea_name
) == 0 &&
7067 eas
[i
].value
.length
== strlen(ea_value
)+1 &&
7068 memcmp(eas
[i
].value
.data
,
7070 eas
[i
].value
.length
) == 0) {
7076 printf("Didn't find EA on pathname %s\n",
7084 /* Get the EA list on the symlink. Should return empty list. */
7085 status
= cli_get_ea_list_path(cli
,
7091 if (!NT_STATUS_IS_OK(status
)) {
7092 printf("cli_get_ea_list_path failed (%s)\n",
7098 printf("cli_get_ea_list_path failed (%s)\n",
7103 /* Set an EA on the symlink. Should fail. */
7104 status
= cli_set_ea_path(cli
,
7108 strlen(ea_value
)+1);
7110 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
7111 printf("cli_set_ea_path on a symlink gave %s. "
7112 "Should be NT_STATUS_ACCESS_DENIED.\n",
7117 printf("EA symlink test passed\n");
7122 if (fnum
!= (uint16_t)-1) {
7123 cli_close(cli
, fnum
);
7124 fnum
= (uint16_t)-1;
7127 cli_setatr(cli
, sname
, 0, 0);
7128 cli_posix_unlink(cli
, sname
);
7129 cli_setatr(cli
, fname
, 0, 0);
7130 cli_posix_unlink(cli
, fname
);
7132 if (!torture_close_connection(cli
)) {
7141 Test POSIX locks are OFD-locks.
7143 static bool run_posix_ofd_lock_test(int dummy
)
7145 static struct cli_state
*cli
;
7146 const char *fname
= "posix_file";
7147 uint16_t fnum1
= (uint16_t)-1;
7148 uint16_t fnum2
= (uint16_t)-1;
7149 bool correct
= false;
7151 TALLOC_CTX
*frame
= NULL
;
7153 frame
= talloc_stackframe();
7155 printf("Starting POSIX ofd-lock test\n");
7157 if (!torture_open_connection(&cli
, 0)) {
7162 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7164 status
= torture_setup_unix_extensions(cli
);
7165 if (!NT_STATUS_IS_OK(status
)) {
7170 cli_setatr(cli
, fname
, 0, 0);
7171 cli_posix_unlink(cli
, fname
);
7173 /* Open the file twice. */
7174 status
= cli_posix_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
7176 if (!NT_STATUS_IS_OK(status
)) {
7177 printf("First POSIX open of %s failed\n", fname
);
7181 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum2
);
7182 if (!NT_STATUS_IS_OK(status
)) {
7183 printf("First POSIX open of %s failed\n", fname
);
7187 /* Set a 0-50 lock on fnum1. */
7188 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
7189 if (!NT_STATUS_IS_OK(status
)) {
7190 printf("POSIX lock (1) failed %s\n", nt_errstr(status
));
7194 /* Set a 60-100 lock on fnum2. */
7195 status
= cli_posix_lock(cli
, fnum2
, 60, 100, false, WRITE_LOCK
);
7196 if (!NT_STATUS_IS_OK(status
)) {
7197 printf("POSIX lock (2) failed %s\n", nt_errstr(status
));
7201 /* close fnum1 - 0-50 lock should go away. */
7202 status
= cli_close(cli
, fnum1
);
7203 if (!NT_STATUS_IS_OK(status
)) {
7204 printf("close failed (%s)\n",
7208 fnum1
= (uint16_t)-1;
7210 /* Change the lock context. */
7211 cli_setpid(cli
, cli_getpid(cli
) + 1);
7213 /* Re-open fnum1. */
7214 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum1
);
7215 if (!NT_STATUS_IS_OK(status
)) {
7216 printf("Third POSIX open of %s failed\n", fname
);
7220 /* 60-100 lock should still be there. */
7221 status
= cli_posix_lock(cli
, fnum1
, 60, 100, false, WRITE_LOCK
);
7222 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
7223 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status
));
7227 /* 0-50 lock should be gone. */
7228 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
7229 if (!NT_STATUS_IS_OK(status
)) {
7230 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status
));
7234 printf("POSIX OFD lock test passed\n");
7239 if (fnum1
!= (uint16_t)-1) {
7240 cli_close(cli
, fnum1
);
7241 fnum1
= (uint16_t)-1;
7243 if (fnum2
!= (uint16_t)-1) {
7244 cli_close(cli
, fnum2
);
7245 fnum2
= (uint16_t)-1;
7248 cli_setatr(cli
, fname
, 0, 0);
7249 cli_posix_unlink(cli
, fname
);
7251 if (!torture_close_connection(cli
)) {
7259 static uint32_t open_attrs_table
[] = {
7260 FILE_ATTRIBUTE_NORMAL
,
7261 FILE_ATTRIBUTE_ARCHIVE
,
7262 FILE_ATTRIBUTE_READONLY
,
7263 FILE_ATTRIBUTE_HIDDEN
,
7264 FILE_ATTRIBUTE_SYSTEM
,
7266 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
7267 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
7268 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
7269 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
7270 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
7271 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
7273 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
7274 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
7275 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
7276 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
7279 struct trunc_open_results
{
7282 uint32_t trunc_attr
;
7283 uint32_t result_attr
;
7286 static struct trunc_open_results attr_results
[] = {
7287 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
7288 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
7289 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
7290 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
7291 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
7292 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
7293 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7294 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7295 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
7296 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7297 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7298 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
7299 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7300 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7301 { 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
},
7302 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7303 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7304 { 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
},
7305 { 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
},
7306 { 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
},
7307 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7308 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
7309 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
7310 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7311 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
7312 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
7315 static bool run_openattrtest(int dummy
)
7317 static struct cli_state
*cli1
;
7318 const char *fname
= "\\openattr.file";
7320 bool correct
= True
;
7322 unsigned int i
, j
, k
, l
;
7325 printf("starting open attr test\n");
7327 if (!torture_open_connection(&cli1
, 0)) {
7331 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7333 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32_t); i
++) {
7334 cli_setatr(cli1
, fname
, 0, 0);
7335 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7337 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
7338 open_attrs_table
[i
], FILE_SHARE_NONE
,
7339 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7340 if (!NT_STATUS_IS_OK(status
)) {
7341 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
7345 status
= cli_close(cli1
, fnum1
);
7346 if (!NT_STATUS_IS_OK(status
)) {
7347 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
7351 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32_t); j
++) {
7352 status
= cli_ntcreate(cli1
, fname
, 0,
7353 FILE_READ_DATA
|FILE_WRITE_DATA
,
7354 open_attrs_table
[j
],
7355 FILE_SHARE_NONE
, FILE_OVERWRITE
,
7356 0, 0, &fnum1
, NULL
);
7357 if (!NT_STATUS_IS_OK(status
)) {
7358 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
7359 if (attr_results
[l
].num
== k
) {
7360 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7361 k
, open_attrs_table
[i
],
7362 open_attrs_table
[j
],
7363 fname
, NT_STATUS_V(status
), nt_errstr(status
));
7368 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
7369 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7370 k
, open_attrs_table
[i
], open_attrs_table
[j
],
7375 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
7381 status
= cli_close(cli1
, fnum1
);
7382 if (!NT_STATUS_IS_OK(status
)) {
7383 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
7387 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
7388 if (!NT_STATUS_IS_OK(status
)) {
7389 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
7394 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7395 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
7398 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
7399 if (attr_results
[l
].num
== k
) {
7400 if (attr
!= attr_results
[l
].result_attr
||
7401 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
7402 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
7403 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7404 open_attrs_table
[i
],
7405 open_attrs_table
[j
],
7407 attr_results
[l
].result_attr
);
7417 cli_setatr(cli1
, fname
, 0, 0);
7418 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7420 printf("open attr test %s.\n", correct
? "passed" : "failed");
7422 if (!torture_close_connection(cli1
)) {
7428 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
7429 const char *name
, void *state
)
7431 int *matched
= (int *)state
;
7432 if (matched
!= NULL
) {
7435 return NT_STATUS_OK
;
7439 test directory listing speed
7441 static bool run_dirtest(int dummy
)
7444 static struct cli_state
*cli
;
7446 struct timeval core_start
;
7447 bool correct
= True
;
7450 printf("starting directory test\n");
7452 if (!torture_open_connection(&cli
, 0)) {
7456 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7459 for (i
=0;i
<torture_numops
;i
++) {
7461 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
7462 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
7463 fprintf(stderr
,"Failed to open %s\n", fname
);
7466 cli_close(cli
, fnum
);
7469 core_start
= timeval_current();
7472 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
7473 printf("Matched %d\n", matched
);
7476 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
7477 printf("Matched %d\n", matched
);
7480 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
7481 printf("Matched %d\n", matched
);
7483 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
7486 for (i
=0;i
<torture_numops
;i
++) {
7488 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
7489 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7492 if (!torture_close_connection(cli
)) {
7496 printf("finished dirtest\n");
7501 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
7504 struct cli_state
*pcli
= (struct cli_state
*)state
;
7506 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
7508 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7509 return NT_STATUS_OK
;
7511 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7512 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
7513 printf("del_fn: failed to rmdir %s\n,", fname
);
7515 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
7516 printf("del_fn: failed to unlink %s\n,", fname
);
7518 return NT_STATUS_OK
;
7523 sees what IOCTLs are supported
7525 bool torture_ioctl_test(int dummy
)
7527 static struct cli_state
*cli
;
7528 uint16_t device
, function
;
7530 const char *fname
= "\\ioctl.dat";
7534 if (!torture_open_connection(&cli
, 0)) {
7538 printf("starting ioctl test\n");
7540 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7542 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7543 if (!NT_STATUS_IS_OK(status
)) {
7544 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
7548 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
7549 printf("ioctl device info: %s\n", nt_errstr(status
));
7551 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
7552 printf("ioctl job info: %s\n", nt_errstr(status
));
7554 for (device
=0;device
<0x100;device
++) {
7555 printf("ioctl test with device = 0x%x\n", device
);
7556 for (function
=0;function
<0x100;function
++) {
7557 uint32_t code
= (device
<<16) | function
;
7559 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
7561 if (NT_STATUS_IS_OK(status
)) {
7562 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
7564 data_blob_free(&blob
);
7569 if (!torture_close_connection(cli
)) {
7578 tries varients of chkpath
7580 bool torture_chkpath_test(int dummy
)
7582 static struct cli_state
*cli
;
7587 if (!torture_open_connection(&cli
, 0)) {
7591 printf("starting chkpath test\n");
7593 /* cleanup from an old run */
7594 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
7595 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7596 cli_rmdir(cli
, "\\chkpath.dir");
7598 status
= cli_mkdir(cli
, "\\chkpath.dir");
7599 if (!NT_STATUS_IS_OK(status
)) {
7600 printf("mkdir1 failed : %s\n", nt_errstr(status
));
7604 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
7605 if (!NT_STATUS_IS_OK(status
)) {
7606 printf("mkdir2 failed : %s\n", nt_errstr(status
));
7610 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
7612 if (!NT_STATUS_IS_OK(status
)) {
7613 printf("open1 failed (%s)\n", nt_errstr(status
));
7616 cli_close(cli
, fnum
);
7618 status
= cli_chkpath(cli
, "\\chkpath.dir");
7619 if (!NT_STATUS_IS_OK(status
)) {
7620 printf("chkpath1 failed: %s\n", nt_errstr(status
));
7624 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
7625 if (!NT_STATUS_IS_OK(status
)) {
7626 printf("chkpath2 failed: %s\n", nt_errstr(status
));
7630 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
7631 if (!NT_STATUS_IS_OK(status
)) {
7632 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
7633 NT_STATUS_NOT_A_DIRECTORY
);
7635 printf("* chkpath on a file should fail\n");
7639 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
7640 if (!NT_STATUS_IS_OK(status
)) {
7641 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
7642 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
7644 printf("* chkpath on a non existent file should fail\n");
7648 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
7649 if (!NT_STATUS_IS_OK(status
)) {
7650 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
7651 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
7653 printf("* chkpath on a non existent component should fail\n");
7657 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
7658 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7659 cli_rmdir(cli
, "\\chkpath.dir");
7661 if (!torture_close_connection(cli
)) {
7668 static bool run_eatest(int dummy
)
7670 static struct cli_state
*cli
;
7671 const char *fname
= "\\eatest.txt";
7672 bool correct
= True
;
7676 struct ea_struct
*ea_list
= NULL
;
7677 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
7680 printf("starting eatest\n");
7682 if (!torture_open_connection(&cli
, 0)) {
7683 talloc_destroy(mem_ctx
);
7687 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7689 status
= cli_ntcreate(cli
, fname
, 0,
7690 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
7691 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
7692 0x4044, 0, &fnum
, NULL
);
7693 if (!NT_STATUS_IS_OK(status
)) {
7694 printf("open failed - %s\n", nt_errstr(status
));
7695 talloc_destroy(mem_ctx
);
7699 for (i
= 0; i
< 10; i
++) {
7700 fstring ea_name
, ea_val
;
7702 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
7703 memset(ea_val
, (char)i
+1, i
+1);
7704 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
7705 if (!NT_STATUS_IS_OK(status
)) {
7706 printf("ea_set of name %s failed - %s\n", ea_name
,
7708 talloc_destroy(mem_ctx
);
7713 cli_close(cli
, fnum
);
7714 for (i
= 0; i
< 10; i
++) {
7715 fstring ea_name
, ea_val
;
7717 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
7718 memset(ea_val
, (char)i
+1, i
+1);
7719 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
7720 if (!NT_STATUS_IS_OK(status
)) {
7721 printf("ea_set of name %s failed - %s\n", ea_name
,
7723 talloc_destroy(mem_ctx
);
7728 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
7729 if (!NT_STATUS_IS_OK(status
)) {
7730 printf("ea_get list failed - %s\n", nt_errstr(status
));
7734 printf("num_eas = %d\n", (int)num_eas
);
7736 if (num_eas
!= 20) {
7737 printf("Should be 20 EA's stored... failing.\n");
7741 for (i
= 0; i
< num_eas
; i
++) {
7742 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
7743 dump_data(0, ea_list
[i
].value
.data
,
7744 ea_list
[i
].value
.length
);
7747 /* Setting EA's to zero length deletes them. Test this */
7748 printf("Now deleting all EA's - case indepenent....\n");
7751 cli_set_ea_path(cli
, fname
, "", "", 0);
7753 for (i
= 0; i
< 20; i
++) {
7755 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
7756 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
7757 if (!NT_STATUS_IS_OK(status
)) {
7758 printf("ea_set of name %s failed - %s\n", ea_name
,
7760 talloc_destroy(mem_ctx
);
7766 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
7767 if (!NT_STATUS_IS_OK(status
)) {
7768 printf("ea_get list failed - %s\n", nt_errstr(status
));
7772 printf("num_eas = %d\n", (int)num_eas
);
7773 for (i
= 0; i
< num_eas
; i
++) {
7774 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
7775 dump_data(0, ea_list
[i
].value
.data
,
7776 ea_list
[i
].value
.length
);
7780 printf("deleting EA's failed.\n");
7784 /* Try and delete a non existent EA. */
7785 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
7786 if (!NT_STATUS_IS_OK(status
)) {
7787 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7792 talloc_destroy(mem_ctx
);
7793 if (!torture_close_connection(cli
)) {
7800 static bool run_dirtest1(int dummy
)
7803 static struct cli_state
*cli
;
7806 bool correct
= True
;
7808 printf("starting directory test\n");
7810 if (!torture_open_connection(&cli
, 0)) {
7814 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7816 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7817 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7818 cli_rmdir(cli
, "\\LISTDIR");
7819 cli_mkdir(cli
, "\\LISTDIR");
7821 /* Create 1000 files and 1000 directories. */
7822 for (i
=0;i
<1000;i
++) {
7824 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
7825 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
7826 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
7827 0, 0, &fnum
, NULL
))) {
7828 fprintf(stderr
,"Failed to open %s\n", fname
);
7831 cli_close(cli
, fnum
);
7833 for (i
=0;i
<1000;i
++) {
7835 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
7836 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
7837 fprintf(stderr
,"Failed to open %s\n", fname
);
7842 /* Now ensure that doing an old list sees both files and directories. */
7844 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7845 printf("num_seen = %d\n", num_seen
);
7846 /* We should see 100 files + 1000 directories + . and .. */
7847 if (num_seen
!= 2002)
7850 /* Ensure if we have the "must have" bits we only see the
7854 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7855 printf("num_seen = %d\n", num_seen
);
7856 if (num_seen
!= 1002)
7860 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
7861 printf("num_seen = %d\n", num_seen
);
7862 if (num_seen
!= 1000)
7865 /* Delete everything. */
7866 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
7867 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
7868 cli_rmdir(cli
, "\\LISTDIR");
7871 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
7872 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
7873 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
7876 if (!torture_close_connection(cli
)) {
7880 printf("finished dirtest1\n");
7885 static bool run_error_map_extract(int dummy
) {
7887 static struct cli_state
*c_dos
;
7888 static struct cli_state
*c_nt
;
7900 /* NT-Error connection */
7902 disable_spnego
= true;
7903 if (!(c_nt
= open_nbt_connection())) {
7904 disable_spnego
= false;
7907 disable_spnego
= false;
7909 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
7912 if (!NT_STATUS_IS_OK(status
)) {
7913 printf("%s rejected the NT-error negprot (%s)\n", host
,
7919 status
= cli_session_setup_anon(c_nt
);
7920 if (!NT_STATUS_IS_OK(status
)) {
7921 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
7925 /* DOS-Error connection */
7927 disable_spnego
= true;
7928 force_dos_errors
= true;
7929 if (!(c_dos
= open_nbt_connection())) {
7930 disable_spnego
= false;
7931 force_dos_errors
= false;
7934 disable_spnego
= false;
7935 force_dos_errors
= false;
7937 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
7939 if (!NT_STATUS_IS_OK(status
)) {
7940 printf("%s rejected the DOS-error negprot (%s)\n", host
,
7942 cli_shutdown(c_dos
);
7946 status
= cli_session_setup_anon(c_dos
);
7947 if (!NT_STATUS_IS_OK(status
)) {
7948 printf("%s rejected the DOS-error initial session setup (%s)\n",
7949 host
, nt_errstr(status
));
7953 c_nt
->map_dos_errors
= false;
7954 c_dos
->map_dos_errors
= false;
7956 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
7957 struct cli_credentials
*user_creds
= NULL
;
7959 fstr_sprintf(user
, "%X", error
);
7961 user_creds
= cli_session_creds_init(talloc_tos(),
7966 false, /* use_kerberos */
7967 false, /* fallback_after_kerberos */
7968 false, /* use_ccache */
7969 false); /* password_is_nt_hash */
7970 if (user_creds
== NULL
) {
7971 printf("cli_session_creds_init(%s) failed\n", user
);
7975 status
= cli_session_setup_creds(c_nt
, user_creds
);
7976 if (NT_STATUS_IS_OK(status
)) {
7977 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7980 /* Case #1: 32-bit NT errors */
7981 if (!NT_STATUS_IS_DOS(status
)) {
7984 printf("/** Dos error on NT connection! (%s) */\n",
7986 nt_status
= NT_STATUS(0xc0000000);
7989 status
= cli_session_setup_creds(c_dos
, user_creds
);
7990 if (NT_STATUS_IS_OK(status
)) {
7991 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7994 /* Case #1: 32-bit NT errors */
7995 if (NT_STATUS_IS_DOS(status
)) {
7996 printf("/** NT error on DOS connection! (%s) */\n",
7998 errnum
= errclass
= 0;
8000 errclass
= NT_STATUS_DOS_CLASS(status
);
8001 errnum
= NT_STATUS_DOS_CODE(status
);
8004 if (NT_STATUS_V(nt_status
) != error
) {
8005 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
8006 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
8007 get_nt_error_c_code(talloc_tos(), nt_status
));
8010 printf("\t{%s,\t%s,\t%s},\n",
8011 smb_dos_err_class(errclass
),
8012 smb_dos_err_name(errclass
, errnum
),
8013 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
8015 TALLOC_FREE(user_creds
);
8020 static bool run_sesssetup_bench(int dummy
)
8022 static struct cli_state
*c
;
8023 const char *fname
= "\\file.dat";
8028 if (!torture_open_connection(&c
, 0)) {
8032 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
8033 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8034 FILE_DELETE_ON_CLOSE
, 0, &fnum
, NULL
);
8035 if (!NT_STATUS_IS_OK(status
)) {
8036 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8040 for (i
=0; i
<torture_numops
; i
++) {
8041 status
= cli_session_setup_creds(c
, torture_creds
);
8042 if (!NT_STATUS_IS_OK(status
)) {
8043 d_printf("(%s) cli_session_setup_creds failed: %s\n",
8044 __location__
, nt_errstr(status
));
8048 d_printf("\r%d ", (int)cli_state_get_uid(c
));
8050 status
= cli_ulogoff(c
);
8051 if (!NT_STATUS_IS_OK(status
)) {
8052 d_printf("(%s) cli_ulogoff failed: %s\n",
8053 __location__
, nt_errstr(status
));
8061 static bool subst_test(const char *str
, const char *user
, const char *domain
,
8062 uid_t uid
, gid_t gid
, const char *expected
)
8067 subst
= talloc_sub_specified(talloc_tos(), str
, user
, NULL
, domain
, uid
, gid
);
8069 if (strcmp(subst
, expected
) != 0) {
8070 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
8071 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
8080 static void chain1_open_completion(struct tevent_req
*req
)
8084 status
= cli_openx_recv(req
, &fnum
);
8087 d_printf("cli_openx_recv returned %s: %d\n",
8089 NT_STATUS_IS_OK(status
) ? fnum
: -1);
8092 static void chain1_write_completion(struct tevent_req
*req
)
8096 status
= cli_write_andx_recv(req
, &written
);
8099 d_printf("cli_write_andx_recv returned %s: %d\n",
8101 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
8104 static void chain1_close_completion(struct tevent_req
*req
)
8107 bool *done
= (bool *)tevent_req_callback_data_void(req
);
8109 status
= cli_close_recv(req
);
8114 d_printf("cli_close returned %s\n", nt_errstr(status
));
8117 static bool run_chain1(int dummy
)
8119 struct cli_state
*cli1
;
8120 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
8121 struct tevent_req
*reqs
[3], *smbreqs
[3];
8123 const char *str
= "foobar";
8124 const char *fname
= "\\test_chain";
8127 printf("starting chain1 test\n");
8128 if (!torture_open_connection(&cli1
, 0)) {
8132 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
8134 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8136 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, fname
,
8137 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
8138 if (reqs
[0] == NULL
) return false;
8139 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
8142 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
8143 (const uint8_t *)str
, 0, strlen(str
)+1,
8144 smbreqs
, 1, &smbreqs
[1]);
8145 if (reqs
[1] == NULL
) return false;
8146 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
8148 reqs
[2] = cli_smb1_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
8149 if (reqs
[2] == NULL
) return false;
8150 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
8152 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
8153 if (!NT_STATUS_IS_OK(status
)) {
8158 tevent_loop_once(evt
);
8161 torture_close_connection(cli1
);
8165 static void chain2_sesssetup_completion(struct tevent_req
*req
)
8168 status
= cli_session_setup_guest_recv(req
);
8169 d_printf("sesssetup returned %s\n", nt_errstr(status
));
8172 static void chain2_tcon_completion(struct tevent_req
*req
)
8174 bool *done
= (bool *)tevent_req_callback_data_void(req
);
8176 status
= cli_tcon_andx_recv(req
);
8177 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
8181 static bool run_chain2(int dummy
)
8183 struct cli_state
*cli1
;
8184 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
8185 struct tevent_req
*reqs
[2], *smbreqs
[2];
8188 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
8190 printf("starting chain2 test\n");
8191 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
8192 port_to_use
, SMB_SIGNING_DEFAULT
, flags
);
8193 if (!NT_STATUS_IS_OK(status
)) {
8197 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
8199 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
8201 if (reqs
[0] == NULL
) return false;
8202 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
8204 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
8205 "?????", NULL
, 0, &smbreqs
[1]);
8206 if (reqs
[1] == NULL
) return false;
8207 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
8209 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
8210 if (!NT_STATUS_IS_OK(status
)) {
8215 tevent_loop_once(evt
);
8218 torture_close_connection(cli1
);
8223 struct torture_createdel_state
{
8224 struct tevent_context
*ev
;
8225 struct cli_state
*cli
;
8228 static void torture_createdel_created(struct tevent_req
*subreq
);
8229 static void torture_createdel_closed(struct tevent_req
*subreq
);
8231 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
8232 struct tevent_context
*ev
,
8233 struct cli_state
*cli
,
8236 struct tevent_req
*req
, *subreq
;
8237 struct torture_createdel_state
*state
;
8239 req
= tevent_req_create(mem_ctx
, &state
,
8240 struct torture_createdel_state
);
8247 subreq
= cli_ntcreate_send(
8248 state
, ev
, cli
, name
, 0,
8249 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
8250 FILE_ATTRIBUTE_NORMAL
,
8251 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8252 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
8254 if (tevent_req_nomem(subreq
, req
)) {
8255 return tevent_req_post(req
, ev
);
8257 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
8261 static void torture_createdel_created(struct tevent_req
*subreq
)
8263 struct tevent_req
*req
= tevent_req_callback_data(
8264 subreq
, struct tevent_req
);
8265 struct torture_createdel_state
*state
= tevent_req_data(
8266 req
, struct torture_createdel_state
);
8270 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
8271 TALLOC_FREE(subreq
);
8272 if (tevent_req_nterror(req
, status
)) {
8273 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8274 nt_errstr(status
)));
8278 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
8279 if (tevent_req_nomem(subreq
, req
)) {
8282 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
8285 static void torture_createdel_closed(struct tevent_req
*subreq
)
8287 struct tevent_req
*req
= tevent_req_callback_data(
8288 subreq
, struct tevent_req
);
8291 status
= cli_close_recv(subreq
);
8292 if (tevent_req_nterror(req
, status
)) {
8293 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
8296 tevent_req_done(req
);
8299 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
8301 return tevent_req_simple_recv_ntstatus(req
);
8304 struct torture_createdels_state
{
8305 struct tevent_context
*ev
;
8306 struct cli_state
*cli
;
8307 const char *base_name
;
8311 struct tevent_req
**reqs
;
8314 static void torture_createdels_done(struct tevent_req
*subreq
);
8316 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
8317 struct tevent_context
*ev
,
8318 struct cli_state
*cli
,
8319 const char *base_name
,
8323 struct tevent_req
*req
;
8324 struct torture_createdels_state
*state
;
8327 req
= tevent_req_create(mem_ctx
, &state
,
8328 struct torture_createdels_state
);
8334 state
->base_name
= talloc_strdup(state
, base_name
);
8335 if (tevent_req_nomem(state
->base_name
, req
)) {
8336 return tevent_req_post(req
, ev
);
8338 state
->num_files
= MAX(num_parallel
, num_files
);
8340 state
->received
= 0;
8342 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
8343 if (tevent_req_nomem(state
->reqs
, req
)) {
8344 return tevent_req_post(req
, ev
);
8347 for (i
=0; i
<num_parallel
; i
++) {
8350 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
8352 if (tevent_req_nomem(name
, req
)) {
8353 return tevent_req_post(req
, ev
);
8355 state
->reqs
[i
] = torture_createdel_send(
8356 state
->reqs
, state
->ev
, state
->cli
, name
);
8357 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
8358 return tevent_req_post(req
, ev
);
8360 name
= talloc_move(state
->reqs
[i
], &name
);
8361 tevent_req_set_callback(state
->reqs
[i
],
8362 torture_createdels_done
, req
);
8368 static void torture_createdels_done(struct tevent_req
*subreq
)
8370 struct tevent_req
*req
= tevent_req_callback_data(
8371 subreq
, struct tevent_req
);
8372 struct torture_createdels_state
*state
= tevent_req_data(
8373 req
, struct torture_createdels_state
);
8374 size_t num_parallel
= talloc_array_length(state
->reqs
);
8379 status
= torture_createdel_recv(subreq
);
8380 if (!NT_STATUS_IS_OK(status
)){
8381 DEBUG(10, ("torture_createdel_recv returned %s\n",
8382 nt_errstr(status
)));
8383 TALLOC_FREE(subreq
);
8384 tevent_req_nterror(req
, status
);
8388 for (i
=0; i
<num_parallel
; i
++) {
8389 if (subreq
== state
->reqs
[i
]) {
8393 if (i
== num_parallel
) {
8394 DEBUG(10, ("received something we did not send\n"));
8395 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
8398 TALLOC_FREE(state
->reqs
[i
]);
8400 if (state
->sent
>= state
->num_files
) {
8401 tevent_req_done(req
);
8405 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
8407 if (tevent_req_nomem(name
, req
)) {
8410 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
8412 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
8415 name
= talloc_move(state
->reqs
[i
], &name
);
8416 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
8420 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
8422 return tevent_req_simple_recv_ntstatus(req
);
8425 struct swallow_notify_state
{
8426 struct tevent_context
*ev
;
8427 struct cli_state
*cli
;
8429 uint32_t completion_filter
;
8431 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
8435 static void swallow_notify_done(struct tevent_req
*subreq
);
8437 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
8438 struct tevent_context
*ev
,
8439 struct cli_state
*cli
,
8441 uint32_t completion_filter
,
8443 bool (*fn
)(uint32_t action
,
8448 struct tevent_req
*req
, *subreq
;
8449 struct swallow_notify_state
*state
;
8451 req
= tevent_req_create(mem_ctx
, &state
,
8452 struct swallow_notify_state
);
8459 state
->completion_filter
= completion_filter
;
8460 state
->recursive
= recursive
;
8464 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
8465 0xffff, state
->completion_filter
,
8467 if (tevent_req_nomem(subreq
, req
)) {
8468 return tevent_req_post(req
, ev
);
8470 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
8474 static void swallow_notify_done(struct tevent_req
*subreq
)
8476 struct tevent_req
*req
= tevent_req_callback_data(
8477 subreq
, struct tevent_req
);
8478 struct swallow_notify_state
*state
= tevent_req_data(
8479 req
, struct swallow_notify_state
);
8481 uint32_t i
, num_changes
;
8482 struct notify_change
*changes
;
8484 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
8485 TALLOC_FREE(subreq
);
8486 if (!NT_STATUS_IS_OK(status
)) {
8487 DEBUG(10, ("cli_notify_recv returned %s\n",
8488 nt_errstr(status
)));
8489 tevent_req_nterror(req
, status
);
8493 for (i
=0; i
<num_changes
; i
++) {
8494 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
8496 TALLOC_FREE(changes
);
8498 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
8499 0xffff, state
->completion_filter
,
8501 if (tevent_req_nomem(subreq
, req
)) {
8504 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
8507 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
8509 if (DEBUGLEVEL
> 5) {
8510 d_printf("%d %s\n", (int)action
, name
);
8515 static void notify_bench_done(struct tevent_req
*req
)
8517 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
8521 static bool run_notify_bench(int dummy
)
8523 const char *dname
= "\\notify-bench";
8524 struct tevent_context
*ev
;
8527 struct tevent_req
*req1
;
8528 struct tevent_req
*req2
= NULL
;
8529 int i
, num_unc_names
;
8530 int num_finished
= 0;
8532 printf("starting notify-bench test\n");
8534 if (use_multishare_conn
) {
8536 unc_list
= file_lines_load(multishare_conn_fname
,
8537 &num_unc_names
, 0, NULL
);
8538 if (!unc_list
|| num_unc_names
<= 0) {
8539 d_printf("Failed to load unc names list from '%s'\n",
8540 multishare_conn_fname
);
8543 TALLOC_FREE(unc_list
);
8548 ev
= samba_tevent_context_init(talloc_tos());
8550 d_printf("tevent_context_init failed\n");
8554 for (i
=0; i
<num_unc_names
; i
++) {
8555 struct cli_state
*cli
;
8558 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8560 if (base_fname
== NULL
) {
8564 if (!torture_open_connection(&cli
, i
)) {
8568 status
= cli_ntcreate(cli
, dname
, 0,
8569 MAXIMUM_ALLOWED_ACCESS
,
8570 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
8572 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
8575 if (!NT_STATUS_IS_OK(status
)) {
8576 d_printf("Could not create %s: %s\n", dname
,
8581 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
8582 FILE_NOTIFY_CHANGE_FILE_NAME
|
8583 FILE_NOTIFY_CHANGE_DIR_NAME
|
8584 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
8585 FILE_NOTIFY_CHANGE_LAST_WRITE
,
8586 false, print_notifies
, NULL
);
8588 d_printf("Could not create notify request\n");
8592 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
8593 base_fname
, 10, torture_numops
);
8595 d_printf("Could not create createdels request\n");
8598 TALLOC_FREE(base_fname
);
8600 tevent_req_set_callback(req2
, notify_bench_done
,
8604 while (num_finished
< num_unc_names
) {
8606 ret
= tevent_loop_once(ev
);
8608 d_printf("tevent_loop_once failed\n");
8613 if (!tevent_req_poll(req2
, ev
)) {
8614 d_printf("tevent_req_poll failed\n");
8617 status
= torture_createdels_recv(req2
);
8618 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
8623 static bool run_mangle1(int dummy
)
8625 struct cli_state
*cli
;
8626 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
8630 time_t change_time
, access_time
, write_time
;
8634 printf("starting mangle1 test\n");
8635 if (!torture_open_connection(&cli
, 0)) {
8639 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8641 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
8642 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8644 if (!NT_STATUS_IS_OK(status
)) {
8645 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8648 cli_close(cli
, fnum
);
8650 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
8651 if (!NT_STATUS_IS_OK(status
)) {
8652 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8656 d_printf("alt_name: %s\n", alt_name
);
8658 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
8659 if (!NT_STATUS_IS_OK(status
)) {
8660 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
8664 cli_close(cli
, fnum
);
8666 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
8667 &write_time
, &size
, &mode
);
8668 if (!NT_STATUS_IS_OK(status
)) {
8669 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
8677 static NTSTATUS
mangle_illegal_list_shortname_fn(const char *mntpoint
,
8678 struct file_info
*f
,
8682 if (f
->short_name
== NULL
) {
8683 return NT_STATUS_OK
;
8686 if (strlen(f
->short_name
) == 0) {
8687 return NT_STATUS_OK
;
8690 printf("unexpected shortname: %s\n", f
->short_name
);
8692 return NT_STATUS_OBJECT_NAME_INVALID
;
8695 static NTSTATUS
mangle_illegal_list_name_fn(const char *mntpoint
,
8696 struct file_info
*f
,
8702 printf("name: %s\n", f
->name
);
8703 fstrcpy(name
, f
->name
);
8704 return NT_STATUS_OK
;
8707 static bool run_mangle_illegal(int dummy
)
8709 struct cli_state
*cli
= NULL
;
8710 struct cli_state
*cli_posix
= NULL
;
8711 const char *fname
= "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8712 const char *illegal_fname
= "MANGLE_ILLEGAL/foo:bar";
8713 char *mangled_path
= NULL
;
8719 printf("starting mangle-illegal test\n");
8721 if (!torture_open_connection(&cli
, 0)) {
8725 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8727 if (!torture_open_connection(&cli_posix
, 0)) {
8731 smbXcli_conn_set_sockopt(cli_posix
->conn
, sockops
);
8733 status
= torture_setup_unix_extensions(cli_posix
);
8734 if (!NT_STATUS_IS_OK(status
)) {
8738 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
8739 status
= cli_mkdir(cli
, "\\MANGLE_ILLEGAL");
8740 if (!NT_STATUS_IS_OK(status
)) {
8741 printf("mkdir1 failed : %s\n", nt_errstr(status
));
8746 * Create a file with illegal NTFS characters and test that we
8747 * get a usable mangled name
8750 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
8751 cli_posix_unlink(cli_posix
, illegal_fname
);
8753 status
= cli_posix_open(cli_posix
, illegal_fname
, O_RDWR
|O_CREAT
|O_EXCL
,
8755 if (!NT_STATUS_IS_OK(status
)) {
8756 printf("POSIX create of %s failed (%s)\n",
8757 illegal_fname
, nt_errstr(status
));
8761 status
= cli_close(cli_posix
, fnum
);
8762 if (!NT_STATUS_IS_OK(status
)) {
8763 printf("close failed (%s)\n", nt_errstr(status
));
8767 status
= cli_list(cli
, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn
, &name
);
8768 if (!NT_STATUS_IS_OK(status
)) {
8769 d_printf("cli_list failed: %s\n", nt_errstr(status
));
8773 mangled_path
= talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name
);
8774 if (mangled_path
== NULL
) {
8778 status
= cli_openx(cli
, mangled_path
, O_RDONLY
, DENY_NONE
, &fnum
);
8779 if (!NT_STATUS_IS_OK(status
)) {
8780 d_printf("cli_openx(%s) failed: %s\n", mangled_path
, nt_errstr(status
));
8781 TALLOC_FREE(mangled_path
);
8784 TALLOC_FREE(mangled_path
);
8785 cli_close(cli
, fnum
);
8787 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
8788 cli_posix_unlink(cli_posix
, illegal_fname
);
8791 * Create a file with a long name and check that we got *no* short name.
8794 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
8795 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
8797 if (!NT_STATUS_IS_OK(status
)) {
8798 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
8801 cli_close(cli
, fnum
);
8803 status
= cli_list(cli
, fname
, 0, mangle_illegal_list_shortname_fn
, &alt_name
);
8804 if (!NT_STATUS_IS_OK(status
)) {
8805 d_printf("cli_list failed\n");
8809 cli_unlink(cli
, fname
, 0);
8810 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
8812 if (!torture_close_connection(cli_posix
)) {
8816 if (!torture_close_connection(cli
)) {
8823 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
8825 size_t *to_pull
= (size_t *)priv
;
8826 size_t thistime
= *to_pull
;
8828 thistime
= MIN(thistime
, n
);
8829 if (thistime
== 0) {
8833 memset(buf
, 0, thistime
);
8834 *to_pull
-= thistime
;
8838 static bool run_windows_write(int dummy
)
8840 struct cli_state
*cli1
;
8844 const char *fname
= "\\writetest.txt";
8845 struct timeval start_time
;
8850 printf("starting windows_write test\n");
8851 if (!torture_open_connection(&cli1
, 0)) {
8855 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
8856 if (!NT_STATUS_IS_OK(status
)) {
8857 printf("open failed (%s)\n", nt_errstr(status
));
8861 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
8863 start_time
= timeval_current();
8865 for (i
=0; i
<torture_numops
; i
++) {
8867 off_t start
= i
* torture_blocksize
;
8868 size_t to_pull
= torture_blocksize
- 1;
8870 status
= cli_writeall(cli1
, fnum
, 0, &c
,
8871 start
+ torture_blocksize
- 1, 1, NULL
);
8872 if (!NT_STATUS_IS_OK(status
)) {
8873 printf("cli_write failed: %s\n", nt_errstr(status
));
8877 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
8878 null_source
, &to_pull
);
8879 if (!NT_STATUS_IS_OK(status
)) {
8880 printf("cli_push returned: %s\n", nt_errstr(status
));
8885 seconds
= timeval_elapsed(&start_time
);
8886 kbytes
= (double)torture_blocksize
* torture_numops
;
8889 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
8890 (double)seconds
, (int)(kbytes
/seconds
));
8894 cli_close(cli1
, fnum
);
8895 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8896 torture_close_connection(cli1
);
8900 static size_t calc_expected_return(struct cli_state
*cli
, size_t len_requested
)
8902 size_t max_pdu
= 0x1FFFF;
8904 if (cli
->server_posix_capabilities
& CIFS_UNIX_LARGE_READ_CAP
) {
8908 if (smb1cli_conn_signing_is_active(cli
->conn
)) {
8912 if (smb1cli_conn_encryption_on(cli
->conn
)) {
8913 max_pdu
= CLI_BUFFER_SIZE
;
8916 if ((len_requested
& 0xFFFF0000) == 0xFFFF0000) {
8917 len_requested
&= 0xFFFF;
8920 return MIN(len_requested
,
8921 max_pdu
- (MIN_SMB_SIZE
+ VWV(12) + 1 /* padding byte */));
8924 static bool check_read_call(struct cli_state
*cli
,
8927 size_t len_requested
)
8930 struct tevent_req
*subreq
= NULL
;
8931 ssize_t len_read
= 0;
8932 size_t len_expected
= 0;
8933 struct tevent_context
*ev
= NULL
;
8935 ev
= samba_tevent_context_init(talloc_tos());
8940 subreq
= cli_read_andx_send(talloc_tos(),
8947 if (!tevent_req_poll_ntstatus(subreq
, ev
, &status
)) {
8951 status
= cli_read_andx_recv(subreq
, &len_read
, &buf
);
8952 if (!NT_STATUS_IS_OK(status
)) {
8953 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status
));
8957 TALLOC_FREE(subreq
);
8960 len_expected
= calc_expected_return(cli
, len_requested
);
8962 if (len_expected
> 0x10000 && len_read
== 0x10000) {
8963 /* Windows servers only return a max of 0x10000,
8964 doesn't matter if you set CAP_LARGE_READX in
8965 the client sessionsetupX call or not. */
8966 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8967 (unsigned int)len_requested
);
8968 } else if (len_read
!= len_expected
) {
8969 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8970 (unsigned int)len_requested
,
8971 (unsigned int)len_read
,
8972 (unsigned int)len_expected
);
8975 d_printf("Correct read reply.\n");
8981 /* Test large readX variants. */
8982 static bool large_readx_tests(struct cli_state
*cli
,
8986 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8987 if (check_read_call(cli
, fnum
, buf
, 0xFFFF0001) == false) {
8990 /* A read of 0x10000 should return 0x10000 bytes. */
8991 if (check_read_call(cli
, fnum
, buf
, 0x10000) == false) {
8994 /* A read of 0x10000 should return 0x10001 bytes. */
8995 if (check_read_call(cli
, fnum
, buf
, 0x10001) == false) {
8998 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8999 the requested number of bytes. */
9000 if (check_read_call(cli
, fnum
, buf
, 0x1FFFF - (MIN_SMB_SIZE
+ VWV(12))) == false) {
9003 /* A read of 1MB should return 1MB bytes (on Samba). */
9004 if (check_read_call(cli
, fnum
, buf
, 0x100000) == false) {
9008 if (check_read_call(cli
, fnum
, buf
, 0x20001) == false) {
9011 if (check_read_call(cli
, fnum
, buf
, 0x22000001) == false) {
9014 if (check_read_call(cli
, fnum
, buf
, 0xFFFE0001) == false) {
9020 static bool run_large_readx(int dummy
)
9022 uint8_t *buf
= NULL
;
9023 struct cli_state
*cli1
= NULL
;
9024 struct cli_state
*cli2
= NULL
;
9025 bool correct
= false;
9026 const char *fname
= "\\large_readx.dat";
9028 uint16_t fnum1
= UINT16_MAX
;
9029 uint32_t normal_caps
= 0;
9030 size_t file_size
= 20*1024*1024;
9031 TALLOC_CTX
*frame
= talloc_stackframe();
9035 enum smb_signing_setting signing_setting
;
9036 enum protocol_types protocol
;
9040 .signing_setting
= SMB_SIGNING_IF_REQUIRED
,
9041 .protocol
= PROTOCOL_NT1
,
9043 .name
= "NT1 - SIGNING_REQUIRED",
9044 .signing_setting
= SMB_SIGNING_REQUIRED
,
9045 .protocol
= PROTOCOL_NT1
,
9049 printf("starting large_readx test\n");
9051 if (!torture_open_connection(&cli1
, 0)) {
9055 normal_caps
= smb1cli_conn_capabilities(cli1
->conn
);
9057 if (!(normal_caps
& CAP_LARGE_READX
)) {
9058 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9059 (unsigned int)normal_caps
);
9063 /* Create a file of size 4MB. */
9064 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
9065 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
9066 0, 0, &fnum1
, NULL
);
9068 if (!NT_STATUS_IS_OK(status
)) {
9069 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
9073 /* Write file_size bytes. */
9074 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
9079 status
= cli_writeall(cli1
,
9086 if (!NT_STATUS_IS_OK(status
)) {
9087 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
9091 status
= cli_close(cli1
, fnum1
);
9092 if (!NT_STATUS_IS_OK(status
)) {
9093 d_printf("cli_close failed: %s\n", nt_errstr(status
));
9099 for (i
=0; i
< ARRAY_SIZE(runs
); i
++) {
9100 enum smb_signing_setting saved_signing_setting
= signing_state
;
9101 uint16_t fnum2
= -1;
9104 (runs
[i
].signing_setting
== SMB_SIGNING_REQUIRED
))
9106 d_printf("skip[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
9110 d_printf("run[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
9112 signing_state
= runs
[i
].signing_setting
;
9113 cli2
= open_nbt_connection();
9114 signing_state
= saved_signing_setting
;
9119 status
= smbXcli_negprot(cli2
->conn
,
9123 if (!NT_STATUS_IS_OK(status
)) {
9127 status
= cli_session_setup_creds(cli2
, torture_creds
);
9128 if (!NT_STATUS_IS_OK(status
)) {
9132 status
= cli_tree_connect(cli2
,
9136 if (!NT_STATUS_IS_OK(status
)) {
9140 cli_set_timeout(cli2
, 120000); /* set a really long timeout (2 minutes) */
9142 normal_caps
= smb1cli_conn_capabilities(cli2
->conn
);
9144 if (!(normal_caps
& CAP_LARGE_READX
)) {
9145 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9146 (unsigned int)normal_caps
);
9151 if (force_cli_encryption(cli2
, share
) == false) {
9154 } else if (SERVER_HAS_UNIX_CIFS(cli2
)) {
9155 uint16_t major
, minor
;
9156 uint32_t caplow
, caphigh
;
9158 status
= cli_unix_extensions_version(cli2
,
9161 if (!NT_STATUS_IS_OK(status
)) {
9166 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
,
9167 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
9168 0, 0, &fnum2
, NULL
);
9169 if (!NT_STATUS_IS_OK(status
)) {
9170 d_printf("Second open %s failed: %s\n", fname
, nt_errstr(status
));
9174 /* All reads must return less than file_size bytes. */
9175 if (!large_readx_tests(cli2
, fnum2
, buf
)) {
9179 status
= cli_close(cli2
, fnum2
);
9180 if (!NT_STATUS_IS_OK(status
)) {
9181 d_printf("cli_close failed: %s\n", nt_errstr(status
));
9186 if (!torture_close_connection(cli2
)) {
9193 printf("Success on large_readx test\n");
9198 if (!torture_close_connection(cli2
)) {
9204 if (fnum1
!= UINT16_MAX
) {
9205 status
= cli_close(cli1
, fnum1
);
9206 if (!NT_STATUS_IS_OK(status
)) {
9207 d_printf("cli_close failed: %s\n", nt_errstr(status
));
9212 status
= cli_unlink(cli1
, fname
,
9213 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9214 if (!NT_STATUS_IS_OK(status
)) {
9215 printf("unlink failed (%s)\n", nt_errstr(status
));
9218 if (!torture_close_connection(cli1
)) {
9225 printf("finished large_readx test\n");
9229 static bool run_cli_echo(int dummy
)
9231 struct cli_state
*cli
;
9234 printf("starting cli_echo test\n");
9235 if (!torture_open_connection(&cli
, 0)) {
9238 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9240 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
9242 d_printf("cli_echo returned %s\n", nt_errstr(status
));
9244 torture_close_connection(cli
);
9245 return NT_STATUS_IS_OK(status
);
9248 static int splice_status(off_t written
, void *priv
)
9253 static bool run_cli_splice(int dummy
)
9255 uint8_t *buf
= NULL
;
9256 struct cli_state
*cli1
= NULL
;
9257 bool correct
= false;
9258 const char *fname_src
= "\\splice_src.dat";
9259 const char *fname_dst
= "\\splice_dst.dat";
9261 uint16_t fnum1
= UINT16_MAX
;
9262 uint16_t fnum2
= UINT16_MAX
;
9263 size_t file_size
= 2*1024*1024;
9264 size_t splice_size
= 1*1024*1024 + 713;
9266 uint8_t digest1
[16], digest2
[16];
9269 TALLOC_CTX
*frame
= talloc_stackframe();
9271 printf("starting cli_splice test\n");
9273 if (!torture_open_connection(&cli1
, 0)) {
9277 cli_unlink(cli1
, fname_src
,
9278 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9279 cli_unlink(cli1
, fname_dst
,
9280 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9283 status
= cli_ntcreate(cli1
, fname_src
, 0, GENERIC_ALL_ACCESS
,
9284 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
9285 0, 0, &fnum1
, NULL
);
9287 if (!NT_STATUS_IS_OK(status
)) {
9288 d_printf("open %s failed: %s\n", fname_src
, nt_errstr(status
));
9292 /* Write file_size bytes - must be bigger than splice_size. */
9293 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
9295 d_printf("talloc_fail\n");
9299 /* Fill it with random numbers. */
9300 generate_random_buffer(buf
, file_size
);
9302 /* MD5 the first 1MB + 713 bytes. */
9304 MD5Update(&md5_ctx
, buf
, splice_size
);
9305 MD5Final(digest1
, &md5_ctx
);
9307 status
= cli_writeall(cli1
,
9314 if (!NT_STATUS_IS_OK(status
)) {
9315 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
9319 status
= cli_ntcreate(cli1
, fname_dst
, 0, GENERIC_ALL_ACCESS
,
9320 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
9321 0, 0, &fnum2
, NULL
);
9323 if (!NT_STATUS_IS_OK(status
)) {
9324 d_printf("open %s failed: %s\n", fname_dst
, nt_errstr(status
));
9328 /* Now splice 1MB + 713 bytes. */
9329 status
= cli_splice(cli1
,
9340 if (!NT_STATUS_IS_OK(status
)) {
9341 d_printf("cli_splice failed: %s\n", nt_errstr(status
));
9345 /* Clear the old buffer. */
9346 memset(buf
, '\0', file_size
);
9348 /* Read the new file. */
9349 status
= cli_read(cli1
, fnum2
, (char *)buf
, 0, splice_size
, &nread
);
9350 if (!NT_STATUS_IS_OK(status
)) {
9351 d_printf("cli_read failed: %s\n", nt_errstr(status
));
9354 if (nread
!= splice_size
) {
9355 d_printf("bad read of 0x%x, should be 0x%x\n",
9356 (unsigned int)nread
,
9357 (unsigned int)splice_size
);
9361 /* MD5 the first 1MB + 713 bytes. */
9363 MD5Update(&md5_ctx
, buf
, splice_size
);
9364 MD5Final(digest2
, &md5_ctx
);
9366 /* Must be the same. */
9367 if (memcmp(digest1
, digest2
, 16) != 0) {
9368 d_printf("bad MD5 compare\n");
9373 printf("Success on cli_splice test\n");
9378 if (fnum1
!= UINT16_MAX
) {
9379 cli_close(cli1
, fnum1
);
9381 if (fnum2
!= UINT16_MAX
) {
9382 cli_close(cli1
, fnum2
);
9385 cli_unlink(cli1
, fname_src
,
9386 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9387 cli_unlink(cli1
, fname_dst
,
9388 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9390 if (!torture_close_connection(cli1
)) {
9399 static bool run_uid_regression_test(int dummy
)
9401 static struct cli_state
*cli
;
9404 bool correct
= True
;
9405 struct smbXcli_tcon
*orig_tcon
= NULL
;
9408 printf("starting uid regression test\n");
9410 if (!torture_open_connection(&cli
, 0)) {
9414 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9416 /* Ok - now save then logoff our current user. */
9417 old_vuid
= cli_state_get_uid(cli
);
9419 status
= cli_ulogoff(cli
);
9420 if (!NT_STATUS_IS_OK(status
)) {
9421 d_printf("(%s) cli_ulogoff failed: %s\n",
9422 __location__
, nt_errstr(status
));
9427 cli_state_set_uid(cli
, old_vuid
);
9429 /* Try an operation. */
9430 status
= cli_mkdir(cli
, "\\uid_reg_test");
9431 if (NT_STATUS_IS_OK(status
)) {
9432 d_printf("(%s) cli_mkdir succeeded\n",
9437 /* Should be bad uid. */
9438 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
9439 NT_STATUS_USER_SESSION_DELETED
)) {
9445 old_cnum
= cli_state_get_tid(cli
);
9446 orig_tcon
= cli_state_save_tcon(cli
);
9447 if (orig_tcon
== NULL
) {
9452 /* Now try a SMBtdis with the invald vuid set to zero. */
9453 cli_state_set_uid(cli
, 0);
9455 /* This should succeed. */
9456 status
= cli_tdis(cli
);
9458 if (NT_STATUS_IS_OK(status
)) {
9459 d_printf("First tdis with invalid vuid should succeed.\n");
9461 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
9463 cli_state_restore_tcon(cli
, orig_tcon
);
9467 cli_state_restore_tcon(cli
, orig_tcon
);
9468 cli_state_set_uid(cli
, old_vuid
);
9469 cli_state_set_tid(cli
, old_cnum
);
9471 /* This should fail. */
9472 status
= cli_tdis(cli
);
9473 if (NT_STATUS_IS_OK(status
)) {
9474 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9478 /* Should be bad tid. */
9479 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
9480 NT_STATUS_NETWORK_NAME_DELETED
)) {
9486 cli_rmdir(cli
, "\\uid_reg_test");
9495 static const char *illegal_chars
= "*\\/?<>|\":";
9496 static char force_shortname_chars
[] = " +,.[];=\177";
9498 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
9499 const char *mask
, void *state
)
9501 struct cli_state
*pcli
= (struct cli_state
*)state
;
9503 NTSTATUS status
= NT_STATUS_OK
;
9505 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
9507 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
9508 return NT_STATUS_OK
;
9510 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
9511 status
= cli_rmdir(pcli
, fname
);
9512 if (!NT_STATUS_IS_OK(status
)) {
9513 printf("del_fn: failed to rmdir %s\n,", fname
);
9516 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9517 if (!NT_STATUS_IS_OK(status
)) {
9518 printf("del_fn: failed to unlink %s\n,", fname
);
9530 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
9531 const char *name
, void *state
)
9533 struct sn_state
*s
= (struct sn_state
*)state
;
9537 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9538 i
, finfo
->name
, finfo
->short_name
);
9541 if (strchr(force_shortname_chars
, i
)) {
9542 if (!finfo
->short_name
) {
9543 /* Shortname not created when it should be. */
9544 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9545 __location__
, finfo
->name
, i
);
9548 } else if (finfo
->short_name
){
9549 /* Shortname created when it should not be. */
9550 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9551 __location__
, finfo
->short_name
, finfo
->name
);
9555 return NT_STATUS_OK
;
9558 static bool run_shortname_test(int dummy
)
9560 static struct cli_state
*cli
;
9561 bool correct
= True
;
9567 printf("starting shortname test\n");
9569 if (!torture_open_connection(&cli
, 0)) {
9573 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9575 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
9576 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
9577 cli_rmdir(cli
, "\\shortname");
9579 status
= cli_mkdir(cli
, "\\shortname");
9580 if (!NT_STATUS_IS_OK(status
)) {
9581 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9582 __location__
, nt_errstr(status
));
9587 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
9591 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
9598 for (i
= 32; i
< 128; i
++) {
9599 uint16_t fnum
= (uint16_t)-1;
9603 if (strchr(illegal_chars
, i
)) {
9608 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
9609 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
9610 FILE_OVERWRITE_IF
, 0, 0, &fnum
, NULL
);
9611 if (!NT_STATUS_IS_OK(status
)) {
9612 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9613 __location__
, fname
, nt_errstr(status
));
9617 cli_close(cli
, fnum
);
9620 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
9621 shortname_list_fn
, &s
);
9622 if (s
.matched
!= 1) {
9623 d_printf("(%s) failed to list %s: %s\n",
9624 __location__
, fname
, nt_errstr(status
));
9629 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9630 if (!NT_STATUS_IS_OK(status
)) {
9631 d_printf("(%s) failed to delete %s: %s\n",
9632 __location__
, fname
, nt_errstr(status
));
9645 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
9646 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
9647 cli_rmdir(cli
, "\\shortname");
9648 torture_close_connection(cli
);
9652 static void pagedsearch_cb(struct tevent_req
*req
)
9655 struct tldap_message
*msg
;
9658 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
9659 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9660 d_printf("tldap_search_paged_recv failed: %s\n",
9661 tldap_rc2string(rc
));
9664 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
9668 if (!tldap_entry_dn(msg
, &dn
)) {
9669 d_printf("tldap_entry_dn failed\n");
9672 d_printf("%s\n", dn
);
9676 static bool run_tldap(int dummy
)
9678 struct tldap_context
*ld
;
9682 struct sockaddr_storage addr
;
9683 struct tevent_context
*ev
;
9684 struct tevent_req
*req
;
9688 if (!resolve_name(host
, &addr
, 0, false)) {
9689 d_printf("could not find host %s\n", host
);
9692 status
= open_socket_out(&addr
, 389, 9999, &fd
);
9693 if (!NT_STATUS_IS_OK(status
)) {
9694 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
9698 ld
= tldap_context_create(talloc_tos(), fd
);
9701 d_printf("tldap_context_create failed\n");
9705 rc
= tldap_fetch_rootdse(ld
);
9706 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9707 d_printf("tldap_fetch_rootdse failed: %s\n",
9708 tldap_errstr(talloc_tos(), ld
, rc
));
9712 basedn
= tldap_talloc_single_attribute(
9713 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
9714 if (basedn
== NULL
) {
9715 d_printf("no defaultNamingContext\n");
9718 d_printf("defaultNamingContext: %s\n", basedn
);
9720 ev
= samba_tevent_context_init(talloc_tos());
9722 d_printf("tevent_context_init failed\n");
9726 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
9727 TLDAP_SCOPE_SUB
, "(objectclass=*)",
9729 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
9731 d_printf("tldap_search_paged_send failed\n");
9734 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
9736 tevent_req_poll(req
, ev
);
9740 /* test search filters against rootDSE */
9741 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9742 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9744 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
9745 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
9746 talloc_tos(), NULL
);
9747 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
9748 d_printf("tldap_search with complex filter failed: %s\n",
9749 tldap_errstr(talloc_tos(), ld
, rc
));
9757 /* Torture test to ensure no regression of :
9758 https://bugzilla.samba.org/show_bug.cgi?id=7084
9761 static bool run_dir_createtime(int dummy
)
9763 struct cli_state
*cli
;
9764 const char *dname
= "\\testdir_createtime";
9765 const char *fname
= "\\testdir_createtime\\testfile";
9767 struct timespec create_time
;
9768 struct timespec create_time1
;
9772 if (!torture_open_connection(&cli
, 0)) {
9776 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9777 cli_rmdir(cli
, dname
);
9779 status
= cli_mkdir(cli
, dname
);
9780 if (!NT_STATUS_IS_OK(status
)) {
9781 printf("mkdir failed: %s\n", nt_errstr(status
));
9785 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
9787 if (!NT_STATUS_IS_OK(status
)) {
9788 printf("cli_qpathinfo2 returned %s\n",
9793 /* Sleep 3 seconds, then create a file. */
9796 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
9798 if (!NT_STATUS_IS_OK(status
)) {
9799 printf("cli_openx failed: %s\n", nt_errstr(status
));
9803 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
9805 if (!NT_STATUS_IS_OK(status
)) {
9806 printf("cli_qpathinfo2 (2) returned %s\n",
9811 if (timespec_compare(&create_time1
, &create_time
)) {
9812 printf("run_dir_createtime: create time was updated (error)\n");
9814 printf("run_dir_createtime: create time was not updated (correct)\n");
9820 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9821 cli_rmdir(cli
, dname
);
9822 if (!torture_close_connection(cli
)) {
9829 static bool run_streamerror(int dummy
)
9831 struct cli_state
*cli
;
9832 const char *dname
= "\\testdir_streamerror";
9833 const char *streamname
=
9834 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9836 time_t change_time
, access_time
, write_time
;
9838 uint16_t mode
, fnum
;
9841 if (!torture_open_connection(&cli
, 0)) {
9845 cli_unlink(cli
, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9846 cli_rmdir(cli
, dname
);
9848 status
= cli_mkdir(cli
, dname
);
9849 if (!NT_STATUS_IS_OK(status
)) {
9850 printf("mkdir failed: %s\n", nt_errstr(status
));
9854 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
9855 &write_time
, &size
, &mode
);
9856 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
9857 printf("pathinfo returned %s, expected "
9858 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9863 status
= cli_ntcreate(cli
, streamname
, 0x16,
9864 FILE_READ_DATA
|FILE_READ_EA
|
9865 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
9866 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
9867 FILE_OPEN
, 0, 0, &fnum
, NULL
);
9869 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
9870 printf("ntcreate returned %s, expected "
9871 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9877 cli_rmdir(cli
, dname
);
9881 struct pidtest_state
{
9887 static void pid_echo_done(struct tevent_req
*subreq
);
9889 static struct tevent_req
*pid_echo_send(TALLOC_CTX
*mem_ctx
,
9890 struct tevent_context
*ev
,
9891 struct cli_state
*cli
)
9893 struct tevent_req
*req
, *subreq
;
9894 struct pidtest_state
*state
;
9896 req
= tevent_req_create(mem_ctx
, &state
, struct pidtest_state
);
9901 SSVAL(state
->vwv
, 0, 1);
9902 state
->data
= data_blob_const("hello", 5);
9904 subreq
= smb1cli_req_send(state
,
9909 0, 0, /* *_flags2 */
9911 0xDEADBEEF, /* pid */
9914 ARRAY_SIZE(state
->vwv
), state
->vwv
,
9915 state
->data
.length
, state
->data
.data
);
9917 if (tevent_req_nomem(subreq
, req
)) {
9918 return tevent_req_post(req
, ev
);
9920 tevent_req_set_callback(subreq
, pid_echo_done
, req
);
9924 static void pid_echo_done(struct tevent_req
*subreq
)
9926 struct tevent_req
*req
= tevent_req_callback_data(
9927 subreq
, struct tevent_req
);
9928 struct pidtest_state
*state
= tevent_req_data(
9929 req
, struct pidtest_state
);
9932 uint8_t *bytes
= NULL
;
9933 struct iovec
*recv_iov
= NULL
;
9934 uint8_t *phdr
= NULL
;
9935 uint16_t pidlow
= 0;
9936 uint16_t pidhigh
= 0;
9937 struct smb1cli_req_expected_response expected
[] = {
9939 .status
= NT_STATUS_OK
,
9944 status
= smb1cli_req_recv(subreq
, state
,
9949 NULL
, /* pvwv_offset */
9952 NULL
, /* pbytes_offset */
9954 expected
, ARRAY_SIZE(expected
));
9956 TALLOC_FREE(subreq
);
9958 if (!NT_STATUS_IS_OK(status
)) {
9959 tevent_req_nterror(req
, status
);
9963 if (num_bytes
!= state
->data
.length
) {
9964 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9968 if (memcmp(bytes
, state
->data
.data
, num_bytes
) != 0) {
9969 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9973 /* Check pid low/high == DEADBEEF */
9974 pidlow
= SVAL(phdr
, HDR_PID
);
9975 if (pidlow
!= 0xBEEF){
9976 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9977 (unsigned int)pidlow
);
9978 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9981 pidhigh
= SVAL(phdr
, HDR_PIDHIGH
);
9982 if (pidhigh
!= 0xDEAD){
9983 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9984 (unsigned int)pidhigh
);
9985 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
9989 tevent_req_done(req
);
9992 static NTSTATUS
pid_echo_recv(struct tevent_req
*req
)
9994 return tevent_req_simple_recv_ntstatus(req
);
9997 static bool run_pidhigh(int dummy
)
9999 bool success
= false;
10000 struct cli_state
*cli
= NULL
;
10002 struct tevent_context
*ev
= NULL
;
10003 struct tevent_req
*req
= NULL
;
10004 TALLOC_CTX
*frame
= talloc_stackframe();
10006 printf("starting pid high test\n");
10007 if (!torture_open_connection(&cli
, 0)) {
10010 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
10012 ev
= samba_tevent_context_init(frame
);
10017 req
= pid_echo_send(frame
, ev
, cli
);
10022 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
10026 status
= pid_echo_recv(req
);
10027 if (NT_STATUS_IS_OK(status
)) {
10028 printf("pid high test ok\n");
10034 TALLOC_FREE(frame
);
10035 torture_close_connection(cli
);
10040 Test Windows open on a bad POSIX symlink.
10042 static bool run_symlink_open_test(int dummy
)
10044 static struct cli_state
*cli
;
10045 const char *fname
= "non_existant_file";
10046 const char *sname
= "dangling_symlink";
10047 uint16_t fnum
= (uint16_t)-1;
10048 bool correct
= false;
10050 TALLOC_CTX
*frame
= NULL
;
10052 frame
= talloc_stackframe();
10054 printf("Starting Windows bad symlink open test\n");
10056 if (!torture_open_connection(&cli
, 0)) {
10057 TALLOC_FREE(frame
);
10061 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
10063 status
= torture_setup_unix_extensions(cli
);
10064 if (!NT_STATUS_IS_OK(status
)) {
10065 TALLOC_FREE(frame
);
10069 /* Ensure nothing exists. */
10070 cli_setatr(cli
, fname
, 0, 0);
10071 cli_posix_unlink(cli
, fname
);
10072 cli_setatr(cli
, sname
, 0, 0);
10073 cli_posix_unlink(cli
, sname
);
10075 /* Create a symlink pointing nowhere. */
10076 status
= cli_posix_symlink(cli
, fname
, sname
);
10077 if (!NT_STATUS_IS_OK(status
)) {
10078 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
10081 nt_errstr(status
));
10085 /* Now ensure that a Windows open doesn't hang. */
10086 status
= cli_ntcreate(cli
,
10089 FILE_READ_DATA
|FILE_WRITE_DATA
,
10091 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
10099 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
10100 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
10101 * we use O_NOFOLLOW on the server or not.
10103 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) ||
10104 NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
))
10108 printf("cli_ntcreate of %s returned %s - should return"
10109 " either (%s) or (%s)\n",
10112 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND
),
10113 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND
));
10121 if (fnum
!= (uint16_t)-1) {
10122 cli_close(cli
, fnum
);
10123 fnum
= (uint16_t)-1;
10126 cli_setatr(cli
, sname
, 0, 0);
10127 cli_posix_unlink(cli
, sname
);
10128 cli_setatr(cli
, fname
, 0, 0);
10129 cli_posix_unlink(cli
, fname
);
10131 if (!torture_close_connection(cli
)) {
10135 TALLOC_FREE(frame
);
10140 * Only testing minimal time strings, as the others
10141 * need (locale-dependent) guessing at what strftime does and
10142 * even may differ in builds.
10144 static bool timesubst_test(void)
10146 TALLOC_CTX
*ctx
= NULL
;
10147 /* Sa 23. Dez 04:33:20 CET 2017 */
10148 const struct timeval tv
= { 1514000000, 123 };
10149 const char* expect_minimal
= "20171223_033320";
10150 const char* expect_minus
= "20171223_033320_000123";
10152 char *env_tz
, *orig_tz
= NULL
;
10153 bool result
= true;
10155 ctx
= talloc_new(NULL
);
10157 env_tz
= getenv("TZ");
10159 orig_tz
= talloc_strdup(ctx
, env_tz
);
10161 setenv("TZ", "UTC", 1);
10163 s
= minimal_timeval_string(ctx
, &tv
, false);
10165 if(!s
|| strcmp(s
, expect_minimal
)) {
10166 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
10167 "[%s]\n", s
? s
: "<nil>", expect_minimal
);
10171 s
= minimal_timeval_string(ctx
, &tv
, true);
10172 if(!s
|| strcmp(s
, expect_minus
)) {
10173 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
10174 "[%s]\n", s
? s
: "<nil>", expect_minus
);
10180 setenv("TZ", orig_tz
, 1);
10187 static bool run_local_substitute(int dummy
)
10191 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
10192 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
10193 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
10194 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
10195 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
10196 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
10197 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
10198 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
10199 ok
&= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
10200 /* Substitution depends on current time, so better test the underlying
10201 formatting function. At least covers %t. */
10202 ok
&= timesubst_test();
10204 /* Different captialization rules in sub_basic... */
10206 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
10212 static bool run_local_base64(int dummy
)
10217 for (i
=1; i
<2000; i
++) {
10218 DATA_BLOB blob1
, blob2
;
10221 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
10223 generate_random_buffer(blob1
.data
, blob1
.length
);
10225 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
10227 d_fprintf(stderr
, "base64_encode_data_blob failed "
10228 "for %d bytes\n", i
);
10231 blob2
= base64_decode_data_blob(b64
);
10234 if (data_blob_cmp(&blob1
, &blob2
)) {
10235 d_fprintf(stderr
, "data_blob_cmp failed for %d "
10239 TALLOC_FREE(blob1
.data
);
10240 data_blob_free(&blob2
);
10245 static void parse_fn(const struct gencache_timeout
*t
,
10247 void *private_data
)
10252 static bool run_local_gencache(int dummy
)
10258 struct memcache
*mem
;
10261 mem
= memcache_init(NULL
, 0);
10263 d_printf("%s: memcache_init failed\n", __location__
);
10266 memcache_set_global(mem
);
10268 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
10269 d_printf("%s: gencache_set() failed\n", __location__
);
10273 if (!gencache_get("foo", NULL
, NULL
, NULL
)) {
10274 d_printf("%s: gencache_get() failed\n", __location__
);
10278 for (i
=0; i
<1000000; i
++) {
10279 gencache_parse("foo", parse_fn
, NULL
);
10282 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
10283 d_printf("%s: gencache_get() failed\n", __location__
);
10288 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
10289 d_printf("%s: gencache_get() failed\n", __location__
);
10293 if (strcmp(val
, "bar") != 0) {
10294 d_printf("%s: gencache_get() returned %s, expected %s\n",
10295 __location__
, val
, "bar");
10302 if (!gencache_del("foo")) {
10303 d_printf("%s: gencache_del() failed\n", __location__
);
10306 if (gencache_del("foo")) {
10307 d_printf("%s: second gencache_del() succeeded\n",
10312 if (gencache_get("foo", talloc_tos(), &val
, &tm
)) {
10313 d_printf("%s: gencache_get() on deleted entry "
10314 "succeeded\n", __location__
);
10318 blob
= data_blob_string_const_null("bar");
10319 tm
= time(NULL
) + 60;
10321 if (!gencache_set_data_blob("foo", blob
, tm
)) {
10322 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
10326 if (!gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
10327 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
10331 if (strcmp((const char *)blob
.data
, "bar") != 0) {
10332 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10333 __location__
, (const char *)blob
.data
, "bar");
10334 data_blob_free(&blob
);
10338 data_blob_free(&blob
);
10340 if (!gencache_del("foo")) {
10341 d_printf("%s: gencache_del() failed\n", __location__
);
10344 if (gencache_del("foo")) {
10345 d_printf("%s: second gencache_del() succeeded\n",
10350 if (gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
10351 d_printf("%s: gencache_get_data_blob() on deleted entry "
10352 "succeeded\n", __location__
);
10357 blob
.data
= (uint8_t *)&v
;
10358 blob
.length
= sizeof(v
);
10360 if (!gencache_set_data_blob("blob", blob
, tm
)) {
10361 d_printf("%s: gencache_set_data_blob() failed\n",
10365 if (gencache_get("blob", talloc_tos(), &val
, &tm
)) {
10366 d_printf("%s: gencache_get succeeded\n", __location__
);
10373 static bool rbt_testval(struct db_context
*db
, const char *key
,
10376 struct db_record
*rec
;
10377 TDB_DATA data
= string_tdb_data(value
);
10382 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
10384 d_fprintf(stderr
, "fetch_locked failed\n");
10387 status
= dbwrap_record_store(rec
, data
, 0);
10388 if (!NT_STATUS_IS_OK(status
)) {
10389 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
10394 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
10396 d_fprintf(stderr
, "second fetch_locked failed\n");
10400 dbvalue
= dbwrap_record_get_value(rec
);
10401 if ((dbvalue
.dsize
!= data
.dsize
)
10402 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
10403 d_fprintf(stderr
, "Got wrong data back\n");
10413 static int local_rbtree_traverse_read(struct db_record
*rec
, void *private_data
)
10415 int *count2
= (int *)private_data
;
10420 static int local_rbtree_traverse_delete(struct db_record
*rec
, void *private_data
)
10422 int *count2
= (int *)private_data
;
10424 dbwrap_record_delete(rec
);
10428 static bool run_local_rbtree(int dummy
)
10430 struct db_context
*db
;
10437 db
= db_open_rbt(NULL
);
10440 d_fprintf(stderr
, "db_open_rbt failed\n");
10444 for (i
=0; i
<1000; i
++) {
10447 if (asprintf(&key
, "key%ld", random()) == -1) {
10450 if (asprintf(&value
, "value%ld", random()) == -1) {
10455 if (!rbt_testval(db
, key
, value
)) {
10462 if (asprintf(&value
, "value%ld", random()) == -1) {
10467 if (!rbt_testval(db
, key
, value
)) {
10478 count
= 0; count2
= 0;
10479 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
10481 printf("%s: read1: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10482 if ((count
!= count2
) || (count
!= 1000)) {
10485 count
= 0; count2
= 0;
10486 status
= dbwrap_traverse(db
, local_rbtree_traverse_delete
,
10488 printf("%s: delete: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10489 if ((count
!= count2
) || (count
!= 1000)) {
10492 count
= 0; count2
= 0;
10493 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
10495 printf("%s: read2: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
10496 if ((count
!= count2
) || (count
!= 0)) {
10507 local test for character set functions
10509 This is a very simple test for the functionality in convert_string_error()
10511 static bool run_local_convert_string(int dummy
)
10513 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
10514 const char *test_strings
[2] = { "March", "M\303\244rz" };
10518 for (i
=0; i
<2; i
++) {
10519 const char *str
= test_strings
[i
];
10520 int len
= strlen(str
);
10521 size_t converted_size
;
10524 memset(dst
, 'X', sizeof(dst
));
10526 /* first try with real source length */
10527 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
10532 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
10536 if (converted_size
!= len
) {
10537 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
10538 str
, len
, (int)converted_size
);
10542 if (strncmp(str
, dst
, converted_size
) != 0) {
10543 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
10547 if (strlen(str
) != converted_size
) {
10548 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
10549 (int)strlen(str
), (int)converted_size
);
10553 if (dst
[converted_size
] != 'X') {
10554 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
10558 /* now with srclen==-1, this causes the nul to be
10560 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
10565 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
10569 if (converted_size
!= len
+1) {
10570 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
10571 str
, len
, (int)converted_size
);
10575 if (strncmp(str
, dst
, converted_size
) != 0) {
10576 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
10580 if (len
+1 != converted_size
) {
10581 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
10582 len
+1, (int)converted_size
);
10586 if (dst
[converted_size
] != 'X') {
10587 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
10594 TALLOC_FREE(tmp_ctx
);
10597 TALLOC_FREE(tmp_ctx
);
10601 static bool run_local_string_to_sid(int dummy
) {
10602 struct dom_sid sid
;
10604 if (string_to_sid(&sid
, "S--1-5-32-545")) {
10605 printf("allowing S--1-5-32-545\n");
10608 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
10609 printf("allowing S-1-5-32-+545\n");
10612 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")) {
10613 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10616 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
10617 printf("allowing S-1-5-32-545-abc\n");
10620 if (string_to_sid(&sid
, "S-300-5-32-545")) {
10621 printf("allowing S-300-5-32-545\n");
10624 if (string_to_sid(&sid
, "S-1-0xfffffffffffffe-32-545")) {
10625 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10628 if (string_to_sid(&sid
, "S-1-0xffffffffffff-5294967297-545")) {
10629 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10632 if (!string_to_sid(&sid
, "S-1-0xfffffffffffe-32-545")) {
10633 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10636 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
10637 printf("could not parse S-1-5-32-545\n");
10640 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
10641 printf("mis-parsed S-1-5-32-545 as %s\n",
10642 sid_string_tos(&sid
));
10648 static bool sid_to_string_test(const char *expected
) {
10651 struct dom_sid sid
;
10653 if (!string_to_sid(&sid
, expected
)) {
10654 printf("could not parse %s\n", expected
);
10658 str
= dom_sid_string(NULL
, &sid
);
10659 if (strcmp(str
, expected
)) {
10660 printf("Comparison failed (%s != %s)\n", str
, expected
);
10667 static bool run_local_sid_to_string(int dummy
) {
10668 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10670 if (!sid_to_string_test("S-1-545"))
10672 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10677 static bool run_local_binary_to_sid(int dummy
) {
10678 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
10679 static const uint8_t good_binary_sid
[] = {
10680 0x1, /* revision number */
10681 15, /* num auths */
10682 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10683 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10684 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10685 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10686 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10687 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10688 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10689 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10690 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10691 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10692 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10693 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10694 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10695 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10696 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10697 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10700 static const uint8_t long_binary_sid
[] = {
10701 0x1, /* revision number */
10702 15, /* num auths */
10703 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10704 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10705 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10706 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10707 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10708 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10709 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10710 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10711 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10712 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10713 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10714 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10715 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10716 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10717 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10718 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10719 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10720 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10721 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10724 static const uint8_t long_binary_sid2
[] = {
10725 0x1, /* revision number */
10726 32, /* num auths */
10727 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10728 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10729 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10730 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10731 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10732 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10733 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10734 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10735 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10736 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10737 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10738 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10739 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10740 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10741 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10742 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10743 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10744 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10745 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10746 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10747 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10748 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10749 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10750 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10751 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10752 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10753 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10754 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10755 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10756 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10757 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10758 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10759 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10762 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
10765 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
10768 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
10774 /* Split a path name into filename and stream name components. Canonicalise
10775 * such that an implicit $DATA token is always explicit.
10777 * The "specification" of this function can be found in the
10778 * run_local_stream_name() function in torture.c, I've tried those
10779 * combinations against a W2k3 server.
10782 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
10783 char **pbase
, char **pstream
)
10786 char *stream
= NULL
;
10787 char *sname
; /* stream name */
10788 const char *stype
; /* stream type */
10790 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
10792 sname
= strchr_m(fname
, ':');
10794 if (sname
== NULL
) {
10795 if (pbase
!= NULL
) {
10796 base
= talloc_strdup(mem_ctx
, fname
);
10797 NT_STATUS_HAVE_NO_MEMORY(base
);
10802 if (pbase
!= NULL
) {
10803 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
10804 NT_STATUS_HAVE_NO_MEMORY(base
);
10809 stype
= strchr_m(sname
, ':');
10811 if (stype
== NULL
) {
10812 sname
= talloc_strdup(mem_ctx
, sname
);
10816 if (strcasecmp_m(stype
, ":$DATA") != 0) {
10818 * If there is an explicit stream type, so far we only
10819 * allow $DATA. Is there anything else allowed? -- vl
10821 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
10823 return NT_STATUS_OBJECT_NAME_INVALID
;
10825 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
10829 if (sname
== NULL
) {
10831 return NT_STATUS_NO_MEMORY
;
10834 if (sname
[0] == '\0') {
10836 * no stream name, so no stream
10841 if (pstream
!= NULL
) {
10842 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
10843 if (stream
== NULL
) {
10844 TALLOC_FREE(sname
);
10846 return NT_STATUS_NO_MEMORY
;
10849 * upper-case the type field
10851 (void)strupper_m(strchr_m(stream
, ':')+1);
10855 if (pbase
!= NULL
) {
10858 if (pstream
!= NULL
) {
10861 return NT_STATUS_OK
;
10864 static bool test_stream_name(const char *fname
, const char *expected_base
,
10865 const char *expected_stream
,
10866 NTSTATUS expected_status
)
10870 char *stream
= NULL
;
10872 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
10873 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
10877 if (!NT_STATUS_IS_OK(status
)) {
10881 if (base
== NULL
) goto error
;
10883 if (strcmp(expected_base
, base
) != 0) goto error
;
10885 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
10886 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
10888 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
10892 TALLOC_FREE(stream
);
10896 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
10897 fname
, expected_base
? expected_base
: "<NULL>",
10898 expected_stream
? expected_stream
: "<NULL>",
10899 nt_errstr(expected_status
));
10900 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
10901 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
10902 nt_errstr(status
));
10904 TALLOC_FREE(stream
);
10908 static bool run_local_stream_name(int dummy
)
10912 ret
&= test_stream_name(
10913 "bla", "bla", NULL
, NT_STATUS_OK
);
10914 ret
&= test_stream_name(
10915 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
10916 ret
&= test_stream_name(
10917 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10918 ret
&= test_stream_name(
10919 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10920 ret
&= test_stream_name(
10921 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
10922 ret
&= test_stream_name(
10923 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
10924 ret
&= test_stream_name(
10925 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
10926 ret
&= test_stream_name(
10927 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
10932 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
10934 if (a
.length
!= b
.length
) {
10935 printf("a.length=%d != b.length=%d\n",
10936 (int)a
.length
, (int)b
.length
);
10939 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
10940 printf("a.data and b.data differ\n");
10946 static bool run_local_memcache(int dummy
)
10948 struct memcache
*cache
;
10949 DATA_BLOB k1
, k2
, k3
;
10953 TALLOC_CTX
*mem_ctx
;
10958 size_t size1
, size2
;
10961 mem_ctx
= talloc_init("foo");
10962 if (mem_ctx
== NULL
) {
10966 /* STAT_CACHE TESTS */
10968 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
10970 if (cache
== NULL
) {
10971 printf("memcache_init failed\n");
10975 d1
= data_blob_const("d1", 2);
10976 d3
= data_blob_const("d3", 2);
10978 k1
= data_blob_const("d1", 2);
10979 k2
= data_blob_const("d2", 2);
10980 k3
= data_blob_const("d3", 2);
10982 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
10984 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
10985 printf("could not find k1\n");
10988 if (!data_blob_equal(d1
, v1
)) {
10992 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
10994 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
10995 printf("could not find replaced k1\n");
10998 if (!data_blob_equal(d3
, v3
)) {
11002 TALLOC_FREE(cache
);
11004 /* GETWD_CACHE TESTS */
11005 str1
= talloc_strdup(mem_ctx
, "string1");
11006 if (str1
== NULL
) {
11009 ptr2
= str1
; /* Keep an alias for comparison. */
11011 str2
= talloc_strdup(mem_ctx
, "string2");
11012 if (str2
== NULL
) {
11016 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
11017 if (cache
== NULL
) {
11018 printf("memcache_init failed\n");
11022 memcache_add_talloc(cache
, GETWD_CACHE
, k2
, &str1
);
11023 /* str1 == NULL now. */
11024 ptr1
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
11025 if (ptr1
== NULL
) {
11026 printf("could not find k2\n");
11029 if (ptr1
!= ptr2
) {
11030 printf("fetch of k2 got wrong string\n");
11034 /* Add a blob to ensure k2 gets purged. */
11035 d3
= data_blob_talloc_zero(mem_ctx
, 180);
11036 memcache_add(cache
, STAT_CACHE
, k3
, d3
);
11038 ptr2
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
11039 if (ptr2
!= NULL
) {
11040 printf("Did find k2, should have been purged\n");
11044 TALLOC_FREE(cache
);
11045 TALLOC_FREE(mem_ctx
);
11047 mem_ctx
= talloc_init("foo");
11048 if (mem_ctx
== NULL
) {
11052 cache
= memcache_init(NULL
, 0);
11053 if (cache
== NULL
) {
11057 str1
= talloc_strdup(mem_ctx
, "string1");
11058 if (str1
== NULL
) {
11061 str2
= talloc_strdup(mem_ctx
, "string2");
11062 if (str2
== NULL
) {
11065 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
11066 data_blob_string_const("torture"), &str1
);
11067 size1
= talloc_total_size(cache
);
11069 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
11070 data_blob_string_const("torture"), &str2
);
11071 size2
= talloc_total_size(cache
);
11073 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
11075 if (size2
> size1
) {
11076 printf("memcache leaks memory!\n");
11082 TALLOC_FREE(cache
);
11086 static void wbclient_done(struct tevent_req
*req
)
11089 struct winbindd_response
*wb_resp
;
11090 int *i
= (int *)tevent_req_callback_data_void(req
);
11092 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
11095 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
11098 static bool run_wbclient_multi_ping(int dummy
)
11100 struct tevent_context
*ev
;
11101 struct wb_context
**wb_ctx
;
11102 struct winbindd_request wb_req
;
11103 bool result
= false;
11106 BlockSignals(True
, SIGPIPE
);
11108 ev
= tevent_context_init(talloc_tos());
11113 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
11114 if (wb_ctx
== NULL
) {
11118 ZERO_STRUCT(wb_req
);
11119 wb_req
.cmd
= WINBINDD_PING
;
11121 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
11123 for (i
=0; i
<torture_nprocs
; i
++) {
11124 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
11125 if (wb_ctx
[i
] == NULL
) {
11128 for (j
=0; j
<torture_numops
; j
++) {
11129 struct tevent_req
*req
;
11130 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
11131 (j
% 2) == 0, &wb_req
);
11135 tevent_req_set_callback(req
, wbclient_done
, &i
);
11141 while (i
< torture_nprocs
* torture_numops
) {
11142 tevent_loop_once(ev
);
11151 static bool dbtrans_inc(struct db_context
*db
)
11153 struct db_record
*rec
;
11159 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
11161 printf(__location__
"fetch_lock failed\n");
11165 value
= dbwrap_record_get_value(rec
);
11167 if (value
.dsize
!= sizeof(uint32_t)) {
11168 printf(__location__
"value.dsize = %d\n",
11173 memcpy(&val
, value
.dptr
, sizeof(val
));
11176 status
= dbwrap_record_store(
11177 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
11178 if (!NT_STATUS_IS_OK(status
)) {
11179 printf(__location__
"store failed: %s\n",
11180 nt_errstr(status
));
11190 static bool run_local_dbtrans(int dummy
)
11192 struct db_context
*db
;
11193 struct db_record
*rec
;
11199 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
11200 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
,
11203 printf("Could not open transtest.db\n");
11207 res
= dbwrap_transaction_start(db
);
11209 printf(__location__
"transaction_start failed\n");
11213 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
11215 printf(__location__
"fetch_lock failed\n");
11219 value
= dbwrap_record_get_value(rec
);
11221 if (value
.dptr
== NULL
) {
11223 status
= dbwrap_record_store(
11224 rec
, make_tdb_data((uint8_t *)&initial
,
11227 if (!NT_STATUS_IS_OK(status
)) {
11228 printf(__location__
"store returned %s\n",
11229 nt_errstr(status
));
11236 res
= dbwrap_transaction_commit(db
);
11238 printf(__location__
"transaction_commit failed\n");
11243 uint32_t val
, val2
;
11246 res
= dbwrap_transaction_start(db
);
11248 printf(__location__
"transaction_start failed\n");
11252 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val
);
11253 if (!NT_STATUS_IS_OK(status
)) {
11254 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
11255 nt_errstr(status
));
11259 for (i
=0; i
<10; i
++) {
11260 if (!dbtrans_inc(db
)) {
11265 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val2
);
11266 if (!NT_STATUS_IS_OK(status
)) {
11267 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
11268 nt_errstr(status
));
11272 if (val2
!= val
+ 10) {
11273 printf(__location__
"val=%d, val2=%d\n",
11274 (int)val
, (int)val2
);
11278 printf("val2=%d\r", val2
);
11280 res
= dbwrap_transaction_commit(db
);
11282 printf(__location__
"transaction_commit failed\n");
11292 * Just a dummy test to be run under a debugger. There's no real way
11293 * to inspect the tevent_poll specific function from outside of
11297 static bool run_local_tevent_poll(int dummy
)
11299 struct tevent_context
*ev
;
11300 struct tevent_fd
*fd1
, *fd2
;
11301 bool result
= false;
11303 ev
= tevent_context_init_byname(NULL
, "poll");
11305 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
11309 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
11311 d_fprintf(stderr
, "tevent_add_fd failed\n");
11314 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
11316 d_fprintf(stderr
, "tevent_add_fd failed\n");
11321 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
11323 d_fprintf(stderr
, "tevent_add_fd failed\n");
11333 static bool run_local_hex_encode_buf(int dummy
)
11339 for (i
=0; i
<sizeof(src
); i
++) {
11342 hex_encode_buf(buf
, src
, sizeof(src
));
11343 if (strcmp(buf
, "0001020304050607") != 0) {
11346 hex_encode_buf(buf
, NULL
, 0);
11347 if (buf
[0] != '\0') {
11353 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
11375 "1001:1111:1111:1000:0:1111:1111:1111",
11384 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
11398 "1001:1111:1111:1000:0:1111:1111:1111"
11401 static bool run_local_remove_duplicate_addrs2(int dummy
)
11403 struct ip_service test_vector
[28];
11406 /* Construct the sockaddr_storage test vector. */
11407 for (i
= 0; i
< 28; i
++) {
11408 struct addrinfo hints
;
11409 struct addrinfo
*res
= NULL
;
11412 memset(&hints
, '\0', sizeof(hints
));
11413 hints
.ai_flags
= AI_NUMERICHOST
;
11414 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
11419 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
11420 remove_duplicate_addrs2_test_strings_vector
[i
]);
11423 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
11424 memcpy(&test_vector
[i
].ss
,
11430 count
= remove_duplicate_addrs2(test_vector
, i
);
11433 fprintf(stderr
, "count wrong (%d) should be 14\n",
11438 for (i
= 0; i
< count
; i
++) {
11439 char addr
[INET6_ADDRSTRLEN
];
11441 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
11443 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
11444 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
11447 remove_duplicate_addrs2_test_strings_result
[i
]);
11452 printf("run_local_remove_duplicate_addrs2: success\n");
11456 static bool run_local_tdb_opener(int dummy
)
11462 t
= tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST
,
11463 O_RDWR
|O_CREAT
, 0755);
11465 perror("tdb_open failed");
11476 static bool run_local_tdb_writer(int dummy
)
11482 t
= tdb_open("test.tdb", 1000, 0, O_RDWR
|O_CREAT
, 0755);
11484 perror("tdb_open failed");
11488 val
.dptr
= (uint8_t *)&v
;
11489 val
.dsize
= sizeof(v
);
11495 ret
= tdb_store(t
, val
, val
, 0);
11497 printf("%s\n", tdb_errorstr(t
));
11502 data
= tdb_fetch(t
, val
);
11503 if (data
.dptr
!= NULL
) {
11504 SAFE_FREE(data
.dptr
);
11510 static bool run_local_canonicalize_path(int dummy
)
11512 const char *src
[] = {
11519 ".././././../../../boo",
11523 const char *dst
[] = {
11536 for (i
= 0; src
[i
] != NULL
; i
++) {
11537 char *d
= canonicalize_absolute_path(talloc_tos(), src
[i
]);
11539 perror("talloc fail\n");
11542 if (strcmp(d
, dst
[i
]) != 0) {
11544 "canonicalize mismatch %s -> %s != %s",
11545 src
[i
], d
, dst
[i
]);
11553 static bool run_ign_bad_negprot(int dummy
)
11555 struct tevent_context
*ev
;
11556 struct tevent_req
*req
;
11557 struct smbXcli_conn
*conn
;
11558 struct sockaddr_storage ss
;
11563 printf("starting ignore bad negprot\n");
11565 ok
= resolve_name(host
, &ss
, 0x20, true);
11567 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
11571 status
= open_socket_out(&ss
, 445, 10000, &fd
);
11572 if (!NT_STATUS_IS_OK(status
)) {
11573 d_fprintf(stderr
, "open_socket_out failed: %s\n",
11574 nt_errstr(status
));
11578 conn
= smbXcli_conn_create(talloc_tos(), fd
, host
, SMB_SIGNING_OFF
, 0,
11580 if (conn
== NULL
) {
11581 d_fprintf(stderr
, "smbXcli_conn_create failed\n");
11585 status
= smbXcli_negprot(conn
, 0, PROTOCOL_CORE
, PROTOCOL_CORE
);
11586 if (NT_STATUS_IS_OK(status
)) {
11587 d_fprintf(stderr
, "smbXcli_negprot succeeded!\n");
11591 ev
= samba_tevent_context_init(talloc_tos());
11593 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
11597 req
= smb1cli_session_setup_nt1_send(
11598 ev
, ev
, conn
, 0, getpid(), NULL
, 65503, 2, 1, 0, "", "",
11599 data_blob_null
, data_blob_null
, 0x40,
11600 "Windows 2000 2195", "Windows 2000 5.0");
11602 d_fprintf(stderr
, "smb1cli_session_setup_nt1_send failed\n");
11606 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
11608 d_fprintf(stderr
, "tevent_req_poll failed\n");
11612 status
= smb1cli_session_setup_nt1_recv(req
, NULL
, NULL
, NULL
, NULL
,
11614 if (!NT_STATUS_EQUAL(status
, NT_STATUS_CONNECTION_RESET
)) {
11615 d_fprintf(stderr
, "smb1cli_session_setup_nt1_recv returned "
11616 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11617 nt_errstr(status
));
11623 printf("starting ignore bad negprot\n");
11628 static double create_procs(bool (*fn
)(int), bool *result
)
11631 volatile pid_t
*child_status
;
11632 volatile bool *child_status_out
;
11635 struct timeval start
;
11639 child_status
= (volatile pid_t
*)anonymous_shared_allocate(sizeof(pid_t
)*torture_nprocs
);
11640 if (!child_status
) {
11641 printf("Failed to setup shared memory\n");
11645 child_status_out
= (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs
);
11646 if (!child_status_out
) {
11647 printf("Failed to setup result status shared memory\n");
11651 for (i
= 0; i
< torture_nprocs
; i
++) {
11652 child_status
[i
] = 0;
11653 child_status_out
[i
] = True
;
11656 start
= timeval_current();
11658 for (i
=0;i
<torture_nprocs
;i
++) {
11661 pid_t mypid
= getpid();
11662 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
11664 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
11667 if (torture_open_connection(¤t_cli
, i
)) break;
11668 if (tries
-- == 0) {
11669 printf("pid %d failed to start\n", (int)getpid());
11675 child_status
[i
] = getpid();
11677 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
11679 child_status_out
[i
] = fn(i
);
11686 for (i
=0;i
<torture_nprocs
;i
++) {
11687 if (child_status
[i
]) synccount
++;
11689 if (synccount
== torture_nprocs
) break;
11691 } while (timeval_elapsed(&start
) < 30);
11693 if (synccount
!= torture_nprocs
) {
11694 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
11696 return timeval_elapsed(&start
);
11699 /* start the client load */
11700 start
= timeval_current();
11702 for (i
=0;i
<torture_nprocs
;i
++) {
11703 child_status
[i
] = 0;
11706 printf("%d clients started\n", torture_nprocs
);
11708 for (i
=0;i
<torture_nprocs
;i
++) {
11709 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
11714 for (i
=0;i
<torture_nprocs
;i
++) {
11715 if (!child_status_out
[i
]) {
11719 return timeval_elapsed(&start
);
11722 #define FLAG_MULTIPROC 1
11728 } torture_ops
[] = {
11729 {"FDPASS", run_fdpasstest
, 0},
11730 {"LOCK1", run_locktest1
, 0},
11731 {"LOCK2", run_locktest2
, 0},
11732 {"LOCK3", run_locktest3
, 0},
11733 {"LOCK4", run_locktest4
, 0},
11734 {"LOCK5", run_locktest5
, 0},
11735 {"LOCK6", run_locktest6
, 0},
11736 {"LOCK7", run_locktest7
, 0},
11737 {"LOCK8", run_locktest8
, 0},
11738 {"LOCK9", run_locktest9
, 0},
11739 {"UNLINK", run_unlinktest
, 0},
11740 {"BROWSE", run_browsetest
, 0},
11741 {"ATTR", run_attrtest
, 0},
11742 {"TRANS2", run_trans2test
, 0},
11743 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
11744 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
11745 {"RANDOMIPC", run_randomipc
, 0},
11746 {"NEGNOWAIT", run_negprot_nowait
, 0},
11747 {"NBENCH", run_nbench
, 0},
11748 {"NBENCH2", run_nbench2
, 0},
11749 {"OPLOCK1", run_oplock1
, 0},
11750 {"OPLOCK2", run_oplock2
, 0},
11751 {"OPLOCK4", run_oplock4
, 0},
11752 {"DIR", run_dirtest
, 0},
11753 {"DIR1", run_dirtest1
, 0},
11754 {"DIR-CREATETIME", run_dir_createtime
, 0},
11755 {"DENY1", torture_denytest1
, 0},
11756 {"DENY2", torture_denytest2
, 0},
11757 {"TCON", run_tcon_test
, 0},
11758 {"TCONDEV", run_tcon_devtype_test
, 0},
11759 {"RW1", run_readwritetest
, 0},
11760 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
11761 {"RW3", run_readwritelarge
, 0},
11762 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
11763 {"OPEN", run_opentest
, 0},
11764 {"POSIX", run_simple_posix_open_test
, 0},
11765 {"POSIX-APPEND", run_posix_append
, 0},
11766 {"POSIX-SYMLINK-ACL", run_acl_symlink_test
, 0},
11767 {"POSIX-SYMLINK-EA", run_ea_symlink_test
, 0},
11768 {"POSIX-STREAM-DELETE", run_posix_stream_delete
, 0},
11769 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test
, 0},
11770 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test
, 0},
11771 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
11772 {"ASYNC-ECHO", run_async_echo
, 0},
11773 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
11774 { "SHORTNAME-TEST", run_shortname_test
, 0},
11775 { "ADDRCHANGE", run_addrchange
, 0},
11777 {"OPENATTR", run_openattrtest
, 0},
11779 {"XCOPY", run_xcopy
, 0},
11780 {"RENAME", run_rename
, 0},
11781 {"RENAME-ACCESS", run_rename_access
, 0},
11782 {"OWNER-RIGHTS", run_owner_rights
, 0},
11783 {"DELETE", run_deletetest
, 0},
11784 {"DELETE-PRINT", run_delete_print_test
, 0},
11785 {"WILDDELETE", run_wild_deletetest
, 0},
11786 {"DELETE-LN", run_deletetest_ln
, 0},
11787 {"PROPERTIES", run_properties
, 0},
11788 {"MANGLE", torture_mangle
, 0},
11789 {"MANGLE1", run_mangle1
, 0},
11790 {"MANGLE-ILLEGAL", run_mangle_illegal
, 0},
11791 {"W2K", run_w2ktest
, 0},
11792 {"TRANS2SCAN", torture_trans2_scan
, 0},
11793 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
11794 {"UTABLE", torture_utable
, 0},
11795 {"CASETABLE", torture_casetable
, 0},
11796 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
11797 {"PIPE_NUMBER", run_pipe_number
, 0},
11798 {"TCON2", run_tcon2_test
, 0},
11799 {"IOCTL", torture_ioctl_test
, 0},
11800 {"CHKPATH", torture_chkpath_test
, 0},
11801 {"FDSESS", run_fdsesstest
, 0},
11802 { "EATEST", run_eatest
, 0},
11803 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
11804 { "CHAIN1", run_chain1
, 0},
11805 { "CHAIN2", run_chain2
, 0},
11806 { "CHAIN3", run_chain3
, 0},
11807 { "WINDOWS-WRITE", run_windows_write
, 0},
11808 { "LARGE_READX", run_large_readx
, 0},
11809 { "NTTRANS-CREATE", run_nttrans_create
, 0},
11810 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
11811 { "CLI_ECHO", run_cli_echo
, 0},
11812 { "CLI_SPLICE", run_cli_splice
, 0},
11813 { "TLDAP", run_tldap
},
11814 { "STREAMERROR", run_streamerror
},
11815 { "NOTIFY-BENCH", run_notify_bench
},
11816 { "NOTIFY-BENCH2", run_notify_bench2
},
11817 { "NOTIFY-BENCH3", run_notify_bench3
},
11818 { "BAD-NBT-SESSION", run_bad_nbt_session
},
11819 { "IGN-BAD-NEGPROT", run_ign_bad_negprot
},
11820 { "SMB-ANY-CONNECT", run_smb_any_connect
},
11821 { "NOTIFY-ONLINE", run_notify_online
},
11822 { "SMB2-BASIC", run_smb2_basic
},
11823 { "SMB2-NEGPROT", run_smb2_negprot
},
11824 { "SMB2-ANONYMOUS", run_smb2_anonymous
},
11825 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
11826 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
11827 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
11828 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
11829 { "SMB2-FTRUNCATE", run_smb2_ftruncate
},
11830 { "SMB2-DIR-FSYNC", run_smb2_dir_fsync
},
11831 { "CLEANUP1", run_cleanup1
},
11832 { "CLEANUP2", run_cleanup2
},
11833 { "CLEANUP3", run_cleanup3
},
11834 { "CLEANUP4", run_cleanup4
},
11835 { "OPLOCK-CANCEL", run_oplock_cancel
},
11836 { "PIDHIGH", run_pidhigh
},
11837 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
11838 { "LOCAL-GENCACHE", run_local_gencache
, 0},
11839 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
11840 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2
, 0 },
11841 { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1
, 0 },
11842 { "LOCAL-MESSAGING-READ1", run_messaging_read1
, 0 },
11843 { "LOCAL-MESSAGING-READ2", run_messaging_read2
, 0 },
11844 { "LOCAL-MESSAGING-READ3", run_messaging_read3
, 0 },
11845 { "LOCAL-MESSAGING-READ4", run_messaging_read4
, 0 },
11846 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1
, 0 },
11847 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2
, 0 },
11848 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a
, 0 },
11849 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b
, 0 },
11850 { "LOCAL-MESSAGING-SEND-ALL", run_messaging_send_all
, 0 },
11851 { "LOCAL-BASE64", run_local_base64
, 0},
11852 { "LOCAL-RBTREE", run_local_rbtree
, 0},
11853 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
11854 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
11855 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping
, 0},
11856 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
11857 { "LOCAL-sid_to_string", run_local_sid_to_string
, 0},
11858 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
11859 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
11860 { "LOCAL-TEVENT-POLL", run_local_tevent_poll
, 0},
11861 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
11862 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
11863 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
11864 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
11865 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
11866 { "local-tdb-opener", run_local_tdb_opener
, 0 },
11867 { "local-tdb-writer", run_local_tdb_writer
, 0 },
11868 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb
, 0 },
11869 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool
, 0 },
11870 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent
, 0 },
11871 { "LOCAL-G-LOCK1", run_g_lock1
, 0 },
11872 { "LOCAL-G-LOCK2", run_g_lock2
, 0 },
11873 { "LOCAL-G-LOCK3", run_g_lock3
, 0 },
11874 { "LOCAL-G-LOCK4", run_g_lock4
, 0 },
11875 { "LOCAL-G-LOCK5", run_g_lock5
, 0 },
11876 { "LOCAL-G-LOCK6", run_g_lock6
, 0 },
11877 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong
, 0 },
11878 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path
, 0 },
11879 { "LOCAL-NAMEMAP-CACHE1", run_local_namemap_cache1
, 0 },
11880 { "qpathinfo-bufsize", run_qpathinfo_bufsize
, 0 },
11881 { "hide-new-files-timeout", run_hidenewfiles
, 0 },
11884 /****************************************************************************
11885 run a specified test or "ALL"
11886 ****************************************************************************/
11887 static bool run_test(const char *name
)
11890 bool result
= True
;
11891 bool found
= False
;
11894 if (strequal(name
,"ALL")) {
11895 for (i
=0;torture_ops
[i
].name
;i
++) {
11896 run_test(torture_ops
[i
].name
);
11901 for (i
=0;torture_ops
[i
].name
;i
++) {
11902 fstr_sprintf(randomfname
, "\\XX%x",
11903 (unsigned)random());
11905 if (strequal(name
, torture_ops
[i
].name
)) {
11907 printf("Running %s\n", name
);
11908 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
11909 t
= create_procs(torture_ops
[i
].fn
, &result
);
11912 printf("TEST %s FAILED!\n", name
);
11915 struct timeval start
;
11916 start
= timeval_current();
11917 if (!torture_ops
[i
].fn(0)) {
11919 printf("TEST %s FAILED!\n", name
);
11921 t
= timeval_elapsed(&start
);
11923 printf("%s took %g secs\n\n", name
, t
);
11928 printf("Did not find a test named %s\n", name
);
11936 static void usage(void)
11940 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11941 printf("Please use samba4 torture.\n\n");
11943 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11945 printf("\t-d debuglevel\n");
11946 printf("\t-U user%%pass\n");
11947 printf("\t-k use kerberos\n");
11948 printf("\t-N numprocs\n");
11949 printf("\t-n my_netbios_name\n");
11950 printf("\t-W workgroup\n");
11951 printf("\t-o num_operations\n");
11952 printf("\t-O socket_options\n");
11953 printf("\t-m maximum protocol\n");
11954 printf("\t-L use oplocks\n");
11955 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11956 printf("\t-A showall\n");
11957 printf("\t-p port\n");
11958 printf("\t-s seed\n");
11959 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11960 printf("\t-f filename filename to test\n");
11961 printf("\t-e encrypt\n");
11964 printf("tests are:");
11965 for (i
=0;torture_ops
[i
].name
;i
++) {
11966 printf(" %s", torture_ops
[i
].name
);
11970 printf("default test is ALL\n");
11975 /****************************************************************************
11977 ****************************************************************************/
11978 int main(int argc
,char *argv
[])
11984 bool correct
= True
;
11985 TALLOC_CTX
*frame
= talloc_stackframe();
11986 int seed
= time(NULL
);
11988 #ifdef HAVE_SETBUFFER
11989 setbuffer(stdout
, NULL
, 0);
11992 setup_logging("smbtorture", DEBUG_STDOUT
);
11997 if (is_default_dyn_CONFIGFILE()) {
11998 if(getenv("SMB_CONF_PATH")) {
11999 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
12002 lp_load_global(get_dyn_CONFIGFILE());
12009 for(p
= argv
[1]; *p
; p
++)
12013 if (strncmp(argv
[1], "//", 2)) {
12017 fstrcpy(host
, &argv
[1][2]);
12018 p
= strchr_m(&host
[2],'/');
12023 fstrcpy(share
, p
+1);
12025 fstrcpy(myname
, get_myname(talloc_tos()));
12027 fprintf(stderr
, "Failed to get my hostname.\n");
12031 if (*username
== 0 && getenv("LOGNAME")) {
12032 fstrcpy(username
,getenv("LOGNAME"));
12038 fstrcpy(workgroup
, lp_workgroup());
12040 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
12044 port_to_use
= atoi(optarg
);
12047 seed
= atoi(optarg
);
12050 fstrcpy(workgroup
,optarg
);
12053 lp_set_cmdline("client max protocol", optarg
);
12056 torture_nprocs
= atoi(optarg
);
12059 torture_numops
= atoi(optarg
);
12062 lp_set_cmdline("log level", optarg
);
12068 use_oplocks
= True
;
12071 local_path
= optarg
;
12074 torture_showall
= True
;
12077 fstrcpy(myname
, optarg
);
12080 client_txt
= optarg
;
12087 use_kerberos
= True
;
12089 d_printf("No kerberos support compiled in\n");
12095 fstrcpy(username
,optarg
);
12096 p
= strchr_m(username
,'%');
12099 fstrcpy(password
, p
+1);
12104 fstrcpy(multishare_conn_fname
, optarg
);
12105 use_multishare_conn
= True
;
12108 torture_blocksize
= atoi(optarg
);
12111 test_filename
= SMB_STRDUP(optarg
);
12114 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
12119 d_printf("using seed %d\n", seed
);
12123 if(use_kerberos
&& !gotuser
) gotpass
= True
;
12126 char pwd
[256] = {0};
12129 rc
= samba_getpass("Password:", pwd
, sizeof(pwd
), false, false);
12131 fstrcpy(password
, pwd
);
12136 printf("host=%s share=%s user=%s myname=%s\n",
12137 host
, share
, username
, myname
);
12139 torture_creds
= cli_session_creds_init(frame
,
12145 false, /* fallback_after_kerberos */
12146 false, /* use_ccache */
12147 false); /* password_is_nt_hash */
12148 if (torture_creds
== NULL
) {
12149 d_printf("cli_session_creds_init() failed.\n");
12153 if (argc
== optind
) {
12154 correct
= run_test("ALL");
12156 for (i
=optind
;i
<argc
;i
++) {
12157 if (!run_test(argv
[i
])) {
12163 TALLOC_FREE(frame
);