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 "tldap_gensec_bind.h"
30 #include "tldap_tls_connect.h"
31 #include "../librpc/gen_ndr/svcctl.h"
32 #include "../lib/util/memcache.h"
33 #include "nsswitch/winbind_client.h"
34 #include "dbwrap/dbwrap.h"
35 #include "dbwrap/dbwrap_open.h"
36 #include "dbwrap/dbwrap_rbt.h"
37 #include "async_smb.h"
38 #include "libsmb/libsmb.h"
39 #include "libsmb/clirap.h"
41 #include "libsmb/nmblib.h"
42 #include "../lib/util/tevent_ntstatus.h"
44 #include "../libcli/smb/read_smb.h"
45 #include "../libcli/smb/smbXcli_base.h"
46 #include "lib/util/sys_rw_data.h"
47 #include "lib/util/base64.h"
48 #include "lib/util/time.h"
49 #include "lib/gencache.h"
50 #include "lib/util/sys_rw.h"
51 #include "lib/util/asn1.h"
52 #include "lib/util/util_file.h"
53 #include "lib/param/param.h"
54 #include "auth/gensec/gensec.h"
55 #include "lib/util/string_wrappers.h"
56 #include "source3/lib/substitute.h"
59 #include <gnutls/gnutls.h>
60 #include <gnutls/crypto.h>
65 fstring host
, workgroup
, share
, password
, username
, myname
;
66 struct cli_credentials
*torture_creds
;
67 static const char *sockops
="TCP_NODELAY";
69 static int port_to_use
=0;
70 int torture_numops
=100;
71 int torture_blocksize
=1024*1024;
72 static int procnum
; /* records process count number when forking */
73 static struct cli_state
*current_cli
;
74 static fstring randomfname
;
75 static bool use_oplocks
;
76 static bool use_level_II_oplocks
;
77 static const char *client_txt
= "client_oplocks.txt";
78 static bool disable_spnego
;
79 static bool use_kerberos
;
80 static bool force_dos_errors
;
81 static fstring multishare_conn_fname
;
82 static bool use_multishare_conn
= False
;
83 static bool do_encrypt
;
84 static const char *local_path
= NULL
;
85 static enum smb_signing_setting signing_state
= SMB_SIGNING_DEFAULT
;
88 bool torture_showall
= False
;
90 static double create_procs(bool (*fn
)(int), bool *result
);
92 /********************************************************************
93 Ensure a connection is encrypted.
94 ********************************************************************/
96 static bool force_cli_encryption(struct cli_state
*c
,
97 const char *sharename
)
99 uint16_t major
, minor
;
100 uint32_t caplow
, caphigh
;
103 if (!SERVER_HAS_UNIX_CIFS(c
)) {
104 d_printf("Encryption required and "
105 "server that doesn't support "
106 "UNIX extensions - failing connect\n");
110 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
112 if (!NT_STATUS_IS_OK(status
)) {
113 d_printf("Encryption required and "
114 "can't get UNIX CIFS extensions "
115 "version from server: %s\n", nt_errstr(status
));
119 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
120 d_printf("Encryption required and "
121 "share %s doesn't support "
122 "encryption.\n", sharename
);
126 status
= cli_smb1_setup_encryption(c
, torture_creds
);
127 if (!NT_STATUS_IS_OK(status
)) {
128 d_printf("Encryption required and "
129 "setup failed with error %s.\n",
138 static struct cli_state
*open_nbt_connection(void)
144 if (disable_spnego
) {
145 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
149 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
152 if (use_level_II_oplocks
) {
153 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
156 if (force_dos_errors
) {
157 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
160 status
= cli_connect_nb(NULL
,
169 if (!NT_STATUS_IS_OK(status
)) {
170 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
174 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
179 /****************************************************************************
180 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
181 ****************************************************************************/
183 static bool cli_bad_session_request(int fd
,
184 struct nmb_name
*calling
, struct nmb_name
*called
)
193 uint8_t message_type
;
195 struct tevent_context
*ev
;
196 struct tevent_req
*req
;
198 frame
= talloc_stackframe();
200 iov
[0].iov_base
= len_buf
;
201 iov
[0].iov_len
= sizeof(len_buf
);
203 /* put in the destination name */
205 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
207 if (iov
[1].iov_base
== NULL
) {
210 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
211 talloc_get_size(iov
[1].iov_base
));
215 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
217 if (iov
[2].iov_base
== NULL
) {
220 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
221 talloc_get_size(iov
[2].iov_base
));
223 /* Deliberately corrupt the name len (first byte) */
224 *((uint8_t *)iov
[2].iov_base
) = 100;
226 /* send a session request (RFC 1002) */
227 /* setup the packet length
228 * Remove four bytes from the length count, since the length
229 * field in the NBT Session Service header counts the number
230 * of bytes which follow. The cli_send_smb() function knows
231 * about this and accounts for those four bytes.
235 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
236 SCVAL(len_buf
,0,0x81);
238 len
= write_data_iov(fd
, iov
, 3);
243 ev
= samba_tevent_context_init(frame
);
247 req
= read_smb_send(frame
, ev
, fd
);
251 if (!tevent_req_poll(req
, ev
)) {
254 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
261 message_type
= CVAL(inbuf
, 0);
262 if (message_type
!= 0x83) {
263 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
268 if (smb_len(inbuf
) != 1) {
269 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
270 (int)smb_len(inbuf
));
274 error
= CVAL(inbuf
, 4);
276 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
287 /* Insert a NULL at the first separator of the given path and return a pointer
288 * to the remainder of the string.
291 terminate_path_at_separator(char * path
)
299 if ((p
= strchr_m(path
, '/'))) {
304 if ((p
= strchr_m(path
, '\\'))) {
314 parse a //server/share type UNC name
316 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
317 char **hostname
, char **sharename
)
321 *hostname
= *sharename
= NULL
;
323 if (strncmp(unc_name
, "\\\\", 2) &&
324 strncmp(unc_name
, "//", 2)) {
328 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
329 p
= terminate_path_at_separator(*hostname
);
332 *sharename
= talloc_strdup(mem_ctx
, p
);
333 terminate_path_at_separator(*sharename
);
336 if (*hostname
&& *sharename
) {
340 TALLOC_FREE(*hostname
);
341 TALLOC_FREE(*sharename
);
345 static bool torture_open_connection_share(struct cli_state
**c
,
346 const char *hostname
,
347 const char *sharename
,
352 status
= cli_full_connection_creds(NULL
,
362 if (!NT_STATUS_IS_OK(status
)) {
363 printf("failed to open share connection: //%s/%s port:%d - %s\n",
364 hostname
, sharename
, port_to_use
, nt_errstr(status
));
368 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
371 return force_cli_encryption(*c
,
377 bool torture_open_connection_flags(struct cli_state
**c
, int conn_index
, int flags
)
379 char **unc_list
= NULL
;
380 int num_unc_names
= 0;
383 if (use_multishare_conn
==True
) {
385 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
386 if (!unc_list
|| num_unc_names
<= 0) {
387 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
391 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
393 printf("Failed to parse UNC name %s\n",
394 unc_list
[conn_index
% num_unc_names
]);
395 TALLOC_FREE(unc_list
);
399 result
= torture_open_connection_share(c
, h
, s
, flags
);
401 /* h, s were copied earlier */
402 TALLOC_FREE(unc_list
);
406 return torture_open_connection_share(c
, host
, share
, flags
);
409 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
411 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
414 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
416 if (use_level_II_oplocks
) {
417 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
420 return torture_open_connection_flags(c
, conn_index
, flags
);
423 bool torture_init_connection(struct cli_state
**pcli
)
425 struct cli_state
*cli
;
427 cli
= open_nbt_connection();
436 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16_t *new_vuid
)
438 uint16_t old_vuid
= cli_state_get_uid(cli
);
442 cli_state_set_uid(cli
, 0);
443 status
= cli_session_setup_creds(cli
, torture_creds
);
444 ret
= NT_STATUS_IS_OK(status
);
445 *new_vuid
= cli_state_get_uid(cli
);
446 cli_state_set_uid(cli
, old_vuid
);
451 bool torture_close_connection(struct cli_state
*c
)
456 status
= cli_tdis(c
);
457 if (!NT_STATUS_IS_OK(status
)) {
458 printf("tdis failed (%s)\n", nt_errstr(status
));
467 void torture_conn_set_sockopt(struct cli_state
*cli
)
469 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
472 static NTSTATUS
torture_delete_fn(struct file_info
*finfo
,
477 char *filename
= NULL
;
478 char *dirname
= NULL
;
480 TALLOC_CTX
*frame
= talloc_stackframe();
481 struct cli_state
*cli
= (struct cli_state
*)state
;
483 if (ISDOT(finfo
->name
) || ISDOTDOT(finfo
->name
)) {
488 dirname
= talloc_strdup(frame
, pattern
);
489 if (dirname
== NULL
) {
491 return NT_STATUS_NO_MEMORY
;
493 p
= strrchr_m(dirname
, '\\');
495 /* Remove the terminating '\' */
498 if (dirname
[0] != '\0') {
499 filename
= talloc_asprintf(frame
,
504 filename
= talloc_asprintf(frame
,
508 if (filename
== NULL
) {
510 return NT_STATUS_NO_MEMORY
;
512 if (finfo
->attr
& FILE_ATTRIBUTE_DIRECTORY
) {
513 char *subdirname
= talloc_asprintf(frame
,
516 if (subdirname
== NULL
) {
518 return NT_STATUS_NO_MEMORY
;
520 status
= cli_list(cli
,
522 FILE_ATTRIBUTE_DIRECTORY
|
523 FILE_ATTRIBUTE_HIDDEN
|
524 FILE_ATTRIBUTE_SYSTEM
,
527 if (!NT_STATUS_IS_OK(status
)) {
528 printf("torture_delete_fn: cli_list "
529 "of %s failed (%s)\n",
535 status
= cli_rmdir(cli
, filename
);
537 status
= cli_unlink(cli
,
539 FILE_ATTRIBUTE_SYSTEM
|
540 FILE_ATTRIBUTE_HIDDEN
);
542 if (!NT_STATUS_IS_OK(status
)) {
543 if (finfo
->attr
& FILE_ATTRIBUTE_DIRECTORY
) {
544 printf("torture_delete_fn: cli_rmdir"
545 " of %s failed (%s)\n",
549 printf("torture_delete_fn: cli_unlink"
550 " of %s failed (%s)\n",
559 void torture_deltree(struct cli_state
*cli
, const char *dname
)
564 /* It might be a file */
565 (void)cli_unlink(cli
,
567 FILE_ATTRIBUTE_SYSTEM
|
568 FILE_ATTRIBUTE_HIDDEN
);
570 mask
= talloc_asprintf(cli
,
574 printf("torture_deltree: talloc_asprintf failed\n");
578 status
= cli_list(cli
,
580 FILE_ATTRIBUTE_DIRECTORY
|
581 FILE_ATTRIBUTE_HIDDEN
|
582 FILE_ATTRIBUTE_SYSTEM
,
585 if (!NT_STATUS_IS_OK(status
)) {
586 printf("torture_deltree: cli_list of %s failed (%s)\n",
591 status
= cli_rmdir(cli
, dname
);
592 if (!NT_STATUS_IS_OK(status
)) {
593 printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
599 /* check if the server produced the expected dos or nt error code */
600 static bool check_both_error(int line
, NTSTATUS status
,
601 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
603 if (NT_STATUS_IS_DOS(status
)) {
607 /* Check DOS error */
608 cclass
= NT_STATUS_DOS_CLASS(status
);
609 num
= NT_STATUS_DOS_CODE(status
);
611 if (eclass
!= cclass
|| ecode
!= num
) {
612 printf("unexpected error code class=%d code=%d\n",
613 (int)cclass
, (int)num
);
614 printf(" expected %d/%d %s (line=%d)\n",
615 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
620 if (!NT_STATUS_EQUAL(nterr
, status
)) {
621 printf("unexpected error code %s\n",
623 printf(" expected %s (line=%d)\n",
624 nt_errstr(nterr
), line
);
633 /* check if the server produced the expected error code */
634 static bool check_error(int line
, NTSTATUS status
,
635 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
637 if (NT_STATUS_IS_DOS(status
)) {
641 /* Check DOS error */
643 cclass
= NT_STATUS_DOS_CLASS(status
);
644 num
= NT_STATUS_DOS_CODE(status
);
646 if (eclass
!= cclass
|| ecode
!= num
) {
647 printf("unexpected error code class=%d code=%d\n",
648 (int)cclass
, (int)num
);
649 printf(" expected %d/%d %s (line=%d)\n",
650 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
658 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
659 printf("unexpected error code %s\n",
661 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
670 NTSTATUS
cli_qpathinfo1(struct cli_state
*cli
,
678 int timezone
= smb1cli_conn_server_time_zone(cli
->conn
);
679 time_t (*date_fn
)(const void *buf
, int serverzone
) = NULL
;
680 uint8_t *rdata
= NULL
;
684 status
= cli_qpathinfo(talloc_tos(),
692 if (!NT_STATUS_IS_OK(status
)) {
696 date_fn
= make_unix_date
;
698 date_fn
= make_unix_date2
;
702 *change_time
= date_fn(rdata
+ 0, timezone
);
705 *access_time
= date_fn(rdata
+ 4, timezone
);
708 *write_time
= date_fn(rdata
+ 8, timezone
);
711 *size
= PULL_LE_U32(rdata
, 12);
714 *pattr
= PULL_LE_U16(rdata
, l1_attrFile
);
719 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
723 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
725 while (!NT_STATUS_IS_OK(status
)) {
726 if (!check_both_error(__LINE__
, status
, ERRDOS
,
727 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
731 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
738 static bool rw_torture(struct cli_state
*c
)
740 const char *lockfname
= "\\torture.lck";
744 pid_t pid2
, pid
= getpid();
751 memset(buf
, '\0', sizeof(buf
));
753 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
755 if (!NT_STATUS_IS_OK(status
)) {
756 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
758 if (!NT_STATUS_IS_OK(status
)) {
759 printf("open of %s failed (%s)\n",
760 lockfname
, nt_errstr(status
));
764 for (i
=0;i
<torture_numops
;i
++) {
765 unsigned n
= (unsigned)sys_random()%10;
768 printf("%d\r", i
); fflush(stdout
);
770 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
772 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
776 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
778 if (!NT_STATUS_IS_OK(status
)) {
779 printf("open failed (%s)\n", nt_errstr(status
));
784 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
786 if (!NT_STATUS_IS_OK(status
)) {
787 printf("write failed (%s)\n", nt_errstr(status
));
792 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
793 sizeof(pid
)+(j
*sizeof(buf
)),
795 if (!NT_STATUS_IS_OK(status
)) {
796 printf("write failed (%s)\n",
804 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
806 if (!NT_STATUS_IS_OK(status
)) {
807 printf("read failed (%s)\n", nt_errstr(status
));
809 } else if (nread
!= sizeof(pid
)) {
810 printf("read/write compare failed: "
811 "recv %ld req %ld\n", (unsigned long)nread
,
812 (unsigned long)sizeof(pid
));
817 printf("data corruption!\n");
821 status
= cli_close(c
, fnum
);
822 if (!NT_STATUS_IS_OK(status
)) {
823 printf("close failed (%s)\n", nt_errstr(status
));
827 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
828 if (!NT_STATUS_IS_OK(status
)) {
829 printf("unlink failed (%s)\n", nt_errstr(status
));
833 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
834 if (!NT_STATUS_IS_OK(status
)) {
835 printf("unlock failed (%s)\n", nt_errstr(status
));
841 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
848 static bool run_torture(int dummy
)
850 struct cli_state
*cli
;
855 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
857 ret
= rw_torture(cli
);
859 if (!torture_close_connection(cli
)) {
866 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
868 uint16_t fnum
= (uint16_t)-1;
873 unsigned countprev
= 0;
876 NTSTATUS status
= NT_STATUS_OK
;
879 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32_t))
881 SIVAL(buf
, i
, sys_random());
888 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
889 if (!NT_STATUS_IS_OK(status
)) {
890 printf("unlink failed (%s) (normal, this file should "
891 "not exist)\n", nt_errstr(status
));
894 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
896 if (!NT_STATUS_IS_OK(status
)) {
897 printf("first open read/write of %s failed (%s)\n",
898 lockfname
, nt_errstr(status
));
904 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
906 status
= cli_openx(c
, lockfname
, O_RDONLY
,
908 if (NT_STATUS_IS_OK(status
)) {
913 if (!NT_STATUS_IS_OK(status
)) {
914 printf("second open read-only of %s failed (%s)\n",
915 lockfname
, nt_errstr(status
));
921 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
923 if (count
>= countprev
) {
924 printf("%d %8d\r", i
, count
);
927 countprev
+= (sizeof(buf
) / 20);
932 sent
= ((unsigned)sys_random()%(20))+ 1;
933 if (sent
> sizeof(buf
) - count
)
935 sent
= sizeof(buf
) - count
;
938 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
940 if (!NT_STATUS_IS_OK(status
)) {
941 printf("write failed (%s)\n",
948 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
949 sizeof(buf
)-count
, &sent
);
950 if(!NT_STATUS_IS_OK(status
)) {
951 printf("read failed offset:%d size:%ld (%s)\n",
952 count
, (unsigned long)sizeof(buf
)-count
,
956 } else if (sent
> 0) {
957 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
959 printf("read/write compare failed\n");
960 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
969 status
= cli_close(c
, fnum
);
970 if (!NT_STATUS_IS_OK(status
)) {
971 printf("close failed (%s)\n", nt_errstr(status
));
978 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
980 const char *lockfname
= "\\torture2.lck";
990 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
991 if (!NT_STATUS_IS_OK(status
)) {
992 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
995 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
997 if (!NT_STATUS_IS_OK(status
)) {
998 printf("first open read/write of %s failed (%s)\n",
999 lockfname
, nt_errstr(status
));
1003 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
1004 if (!NT_STATUS_IS_OK(status
)) {
1005 printf("second open read-only of %s failed (%s)\n",
1006 lockfname
, nt_errstr(status
));
1007 cli_close(c1
, fnum1
);
1011 for (i
= 0; i
< torture_numops
; i
++)
1013 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
1015 printf("%d\r", i
); fflush(stdout
);
1018 generate_random_buffer((unsigned char *)buf
, buf_size
);
1020 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
1022 if (!NT_STATUS_IS_OK(status
)) {
1023 printf("write failed (%s)\n", nt_errstr(status
));
1028 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
1029 if(!NT_STATUS_IS_OK(status
)) {
1030 printf("read failed (%s)\n", nt_errstr(status
));
1033 } else if (bytes_read
!= buf_size
) {
1034 printf("read failed\n");
1035 printf("read %ld, expected %ld\n",
1036 (unsigned long)bytes_read
,
1037 (unsigned long)buf_size
);
1042 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
1044 printf("read/write compare failed\n");
1050 status
= cli_close(c2
, fnum2
);
1051 if (!NT_STATUS_IS_OK(status
)) {
1052 printf("close failed (%s)\n", nt_errstr(status
));
1056 status
= cli_close(c1
, fnum1
);
1057 if (!NT_STATUS_IS_OK(status
)) {
1058 printf("close failed (%s)\n", nt_errstr(status
));
1062 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1063 if (!NT_STATUS_IS_OK(status
)) {
1064 printf("unlink failed (%s)\n", nt_errstr(status
));
1071 static bool run_readwritetest(int dummy
)
1073 struct cli_state
*cli1
, *cli2
;
1074 bool test1
, test2
= False
;
1076 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1079 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1080 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1082 printf("starting readwritetest\n");
1084 test1
= rw_torture2(cli1
, cli2
);
1085 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
1088 test2
= rw_torture2(cli1
, cli1
);
1089 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
1092 if (!torture_close_connection(cli1
)) {
1096 if (!torture_close_connection(cli2
)) {
1100 return (test1
&& test2
);
1103 static bool run_readwritemulti(int dummy
)
1105 struct cli_state
*cli
;
1110 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1112 printf("run_readwritemulti: fname %s\n", randomfname
);
1113 test
= rw_torture3(cli
, randomfname
);
1115 if (!torture_close_connection(cli
)) {
1122 static bool run_readwritelarge_internal(void)
1124 static struct cli_state
*cli1
;
1126 const char *lockfname
= "\\large.dat";
1129 bool correct
= True
;
1132 if (!torture_open_connection(&cli1
, 0)) {
1135 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1136 memset(buf
,'\0',sizeof(buf
));
1138 printf("starting readwritelarge_internal\n");
1140 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1142 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1144 if (!NT_STATUS_IS_OK(status
)) {
1145 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1149 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
1151 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1153 if (!NT_STATUS_IS_OK(status
)) {
1154 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1158 if (fsize
== sizeof(buf
))
1159 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1160 (unsigned long)fsize
);
1162 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1163 (unsigned long)fsize
);
1167 status
= cli_close(cli1
, fnum1
);
1168 if (!NT_STATUS_IS_OK(status
)) {
1169 printf("close failed (%s)\n", nt_errstr(status
));
1173 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1174 if (!NT_STATUS_IS_OK(status
)) {
1175 printf("unlink failed (%s)\n", nt_errstr(status
));
1179 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1181 if (!NT_STATUS_IS_OK(status
)) {
1182 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1186 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
1188 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1190 if (!NT_STATUS_IS_OK(status
)) {
1191 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1195 if (fsize
== sizeof(buf
))
1196 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1197 (unsigned long)fsize
);
1199 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1200 (unsigned long)fsize
);
1204 status
= cli_close(cli1
, fnum1
);
1205 if (!NT_STATUS_IS_OK(status
)) {
1206 printf("close failed (%s)\n", nt_errstr(status
));
1210 if (!torture_close_connection(cli1
)) {
1216 static bool run_readwritelarge(int dummy
)
1218 return run_readwritelarge_internal();
1221 static bool run_readwritelarge_signtest(int dummy
)
1224 signing_state
= SMB_SIGNING_REQUIRED
;
1225 ret
= run_readwritelarge_internal();
1226 signing_state
= SMB_SIGNING_DEFAULT
;
1233 #define ival(s) strtol(s, NULL, 0)
1235 /* run a test that simulates an approximate netbench client load */
1236 static bool run_netbench(int client
)
1238 struct cli_state
*cli
;
1243 const char *params
[20];
1244 bool correct
= True
;
1250 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1254 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1256 f
= fopen(client_txt
, "r");
1263 while (fgets(line
, sizeof(line
)-1, f
)) {
1267 line
[strlen(line
)-1] = 0;
1269 /* printf("[%d] %s\n", line_count, line); */
1271 all_string_sub(line
,"client1", cname
, sizeof(line
));
1273 /* parse the command parameters */
1274 params
[0] = strtok_r(line
, " ", &saveptr
);
1276 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1280 if (i
< 2) continue;
1282 if (!strncmp(params
[0],"SMB", 3)) {
1283 printf("ERROR: You are using a dbench 1 load file\n");
1287 if (!strcmp(params
[0],"NTCreateX")) {
1288 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1290 } else if (!strcmp(params
[0],"Close")) {
1291 nb_close(ival(params
[1]));
1292 } else if (!strcmp(params
[0],"Rename")) {
1293 nb_rename(params
[1], params
[2]);
1294 } else if (!strcmp(params
[0],"Unlink")) {
1295 nb_unlink(params
[1]);
1296 } else if (!strcmp(params
[0],"Deltree")) {
1297 nb_deltree(params
[1]);
1298 } else if (!strcmp(params
[0],"Rmdir")) {
1299 nb_rmdir(params
[1]);
1300 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1301 nb_qpathinfo(params
[1]);
1302 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1303 nb_qfileinfo(ival(params
[1]));
1304 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1305 nb_qfsinfo(ival(params
[1]));
1306 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1307 nb_findfirst(params
[1]);
1308 } else if (!strcmp(params
[0],"WriteX")) {
1309 nb_writex(ival(params
[1]),
1310 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1311 } else if (!strcmp(params
[0],"ReadX")) {
1312 nb_readx(ival(params
[1]),
1313 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1314 } else if (!strcmp(params
[0],"Flush")) {
1315 nb_flush(ival(params
[1]));
1317 printf("Unknown operation %s\n", params
[0]);
1325 if (!torture_close_connection(cli
)) {
1333 /* run a test that simulates an approximate netbench client load */
1334 static bool run_nbench(int dummy
)
1337 bool correct
= True
;
1339 nbio_shmem(torture_nprocs
);
1343 signal(SIGALRM
, nb_alarm
);
1345 t
= create_procs(run_netbench
, &correct
);
1348 printf("\nThroughput %g MB/sec\n",
1349 1.0e-6 * nbio_total() / t
);
1355 This test checks for two things:
1357 1) correct support for retaining locks over a close (ie. the server
1358 must not use posix semantics)
1359 2) support for lock timeouts
1361 static bool run_locktest1(int dummy
)
1363 struct cli_state
*cli1
, *cli2
;
1364 const char *fname
= "\\lockt1.lck";
1365 uint16_t fnum1
, fnum2
, fnum3
;
1367 unsigned lock_timeout
;
1370 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1373 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1374 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1376 printf("starting locktest1\n");
1378 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1380 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1382 if (!NT_STATUS_IS_OK(status
)) {
1383 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1387 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1388 if (!NT_STATUS_IS_OK(status
)) {
1389 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1393 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1394 if (!NT_STATUS_IS_OK(status
)) {
1395 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1399 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1400 if (!NT_STATUS_IS_OK(status
)) {
1401 printf("lock1 failed (%s)\n", nt_errstr(status
));
1405 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1406 if (NT_STATUS_IS_OK(status
)) {
1407 printf("lock2 succeeded! This is a locking bug\n");
1410 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1411 NT_STATUS_LOCK_NOT_GRANTED
)) {
1416 lock_timeout
= (1 + (random() % 20));
1417 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1419 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1420 if (NT_STATUS_IS_OK(status
)) {
1421 printf("lock3 succeeded! This is a locking bug\n");
1424 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1425 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1431 if (ABS(t2
- t1
) < lock_timeout
-1) {
1432 printf("error: This server appears not to support timed lock requests\n");
1435 printf("server slept for %u seconds for a %u second timeout\n",
1436 (unsigned int)(t2
-t1
), lock_timeout
);
1438 status
= cli_close(cli1
, fnum2
);
1439 if (!NT_STATUS_IS_OK(status
)) {
1440 printf("close1 failed (%s)\n", nt_errstr(status
));
1444 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1445 if (NT_STATUS_IS_OK(status
)) {
1446 printf("lock4 succeeded! This is a locking bug\n");
1449 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1450 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1455 status
= cli_close(cli1
, fnum1
);
1456 if (!NT_STATUS_IS_OK(status
)) {
1457 printf("close2 failed (%s)\n", nt_errstr(status
));
1461 status
= cli_close(cli2
, fnum3
);
1462 if (!NT_STATUS_IS_OK(status
)) {
1463 printf("close3 failed (%s)\n", nt_errstr(status
));
1467 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1468 if (!NT_STATUS_IS_OK(status
)) {
1469 printf("unlink failed (%s)\n", nt_errstr(status
));
1474 if (!torture_close_connection(cli1
)) {
1478 if (!torture_close_connection(cli2
)) {
1482 printf("Passed locktest1\n");
1487 this checks to see if a secondary tconx can use open files from an
1490 static bool run_tcon_test(int dummy
)
1492 static struct cli_state
*cli
;
1493 const char *fname
= "\\tcontest.tmp";
1495 uint32_t cnum1
, cnum2
, cnum3
;
1496 struct smbXcli_tcon
*orig_tcon
= NULL
;
1497 char *orig_share
= NULL
;
1498 uint16_t vuid1
, vuid2
;
1503 memset(buf
, '\0', sizeof(buf
));
1505 if (!torture_open_connection(&cli
, 0)) {
1508 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1510 printf("starting tcontest\n");
1512 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1514 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1515 if (!NT_STATUS_IS_OK(status
)) {
1516 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1520 cnum1
= cli_state_get_tid(cli
);
1521 vuid1
= cli_state_get_uid(cli
);
1523 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1524 if (!NT_STATUS_IS_OK(status
)) {
1525 printf("initial write failed (%s)", nt_errstr(status
));
1529 cli_state_save_tcon_share(cli
, &orig_tcon
, &orig_share
);
1531 status
= cli_tree_connect_creds(cli
, share
, "?????", torture_creds
);
1532 if (!NT_STATUS_IS_OK(status
)) {
1533 printf("%s refused 2nd tree connect (%s)\n", host
,
1535 cli_state_restore_tcon_share(cli
, orig_tcon
, orig_share
);
1540 cnum2
= cli_state_get_tid(cli
);
1541 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1542 vuid2
= cli_state_get_uid(cli
) + 1;
1544 /* try a write with the wrong tid */
1545 cli_state_set_tid(cli
, cnum2
);
1547 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1548 if (NT_STATUS_IS_OK(status
)) {
1549 printf("* server allows write with wrong TID\n");
1552 printf("server fails write with wrong TID : %s\n",
1557 /* try a write with an invalid tid */
1558 cli_state_set_tid(cli
, cnum3
);
1560 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1561 if (NT_STATUS_IS_OK(status
)) {
1562 printf("* server allows write with invalid TID\n");
1565 printf("server fails write with invalid TID : %s\n",
1569 /* try a write with an invalid vuid */
1570 cli_state_set_uid(cli
, vuid2
);
1571 cli_state_set_tid(cli
, cnum1
);
1573 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1574 if (NT_STATUS_IS_OK(status
)) {
1575 printf("* server allows write with invalid VUID\n");
1578 printf("server fails write with invalid VUID : %s\n",
1582 cli_state_set_tid(cli
, cnum1
);
1583 cli_state_set_uid(cli
, vuid1
);
1585 status
= cli_close(cli
, fnum1
);
1586 if (!NT_STATUS_IS_OK(status
)) {
1587 printf("close failed (%s)\n", nt_errstr(status
));
1588 cli_state_restore_tcon_share(cli
, orig_tcon
, orig_share
);
1593 cli_state_set_tid(cli
, cnum2
);
1595 status
= cli_tdis(cli
);
1596 if (!NT_STATUS_IS_OK(status
)) {
1597 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1598 cli_state_restore_tcon_share(cli
, orig_tcon
, orig_share
);
1603 cli_state_restore_tcon_share(cli
, orig_tcon
, orig_share
);
1605 cli_state_set_tid(cli
, cnum1
);
1607 if (!torture_close_connection(cli
)) {
1616 checks for old style tcon support
1618 static bool run_tcon2_test(int dummy
)
1620 static struct cli_state
*cli
;
1621 uint16_t cnum
, max_xmit
;
1625 if (!torture_open_connection(&cli
, 0)) {
1628 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1630 printf("starting tcon2 test\n");
1632 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1636 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1640 if (!NT_STATUS_IS_OK(status
)) {
1641 printf("tcon2 failed : %s\n", nt_errstr(status
));
1643 printf("tcon OK : max_xmit=%d cnum=%d\n",
1644 (int)max_xmit
, (int)cnum
);
1647 if (!torture_close_connection(cli
)) {
1651 printf("Passed tcon2 test\n");
1655 static bool tcon_devtest(struct cli_state
*cli
,
1656 const char *myshare
, const char *devtype
,
1657 const char *return_devtype
,
1658 NTSTATUS expected_error
)
1663 status
= cli_tree_connect_creds(cli
, myshare
, devtype
, torture_creds
);
1665 if (NT_STATUS_IS_OK(expected_error
)) {
1666 if (NT_STATUS_IS_OK(status
)) {
1667 if (return_devtype
!= NULL
&&
1668 strequal(cli
->dev
, return_devtype
)) {
1671 printf("tconX to share %s with type %s "
1672 "succeeded but returned the wrong "
1673 "device type (got [%s] but should have got [%s])\n",
1674 myshare
, devtype
, cli
->dev
, return_devtype
);
1678 printf("tconX to share %s with type %s "
1679 "should have succeeded but failed\n",
1685 if (NT_STATUS_IS_OK(status
)) {
1686 printf("tconx to share %s with type %s "
1687 "should have failed but succeeded\n",
1691 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1694 printf("Returned unexpected error\n");
1703 checks for correct tconX support
1705 static bool run_tcon_devtype_test(int dummy
)
1707 static struct cli_state
*cli1
= NULL
;
1708 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
1712 status
= cli_full_connection_creds(NULL
,
1719 NULL
, /* service_type */
1723 if (!NT_STATUS_IS_OK(status
)) {
1724 printf("could not open connection\n");
1728 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1731 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1734 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1737 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1740 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1743 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1746 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1749 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1752 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1755 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1761 printf("Passed tcondevtest\n");
1768 This test checks that
1770 1) the server supports multiple locking contexts on the one SMB
1771 connection, distinguished by PID.
1773 2) the server correctly fails overlapping locks made by the same PID (this
1774 goes against POSIX behaviour, which is why it is tricky to implement)
1776 3) the server denies unlock requests by an incorrect client PID
1778 static bool run_locktest2(int dummy
)
1780 static struct cli_state
*cli
;
1781 const char *fname
= "\\lockt2.lck";
1782 uint16_t fnum1
, fnum2
, fnum3
;
1783 bool correct
= True
;
1786 if (!torture_open_connection(&cli
, 0)) {
1790 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1792 printf("starting locktest2\n");
1794 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1798 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1799 if (!NT_STATUS_IS_OK(status
)) {
1800 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1804 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1805 if (!NT_STATUS_IS_OK(status
)) {
1806 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1812 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1813 if (!NT_STATUS_IS_OK(status
)) {
1814 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1820 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1821 if (!NT_STATUS_IS_OK(status
)) {
1822 printf("lock1 failed (%s)\n", nt_errstr(status
));
1826 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1827 if (NT_STATUS_IS_OK(status
)) {
1828 printf("WRITE lock1 succeeded! This is a locking bug\n");
1831 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1832 NT_STATUS_LOCK_NOT_GRANTED
)) {
1837 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1838 if (NT_STATUS_IS_OK(status
)) {
1839 printf("WRITE lock2 succeeded! This is a locking bug\n");
1842 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1843 NT_STATUS_LOCK_NOT_GRANTED
)) {
1848 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1849 if (NT_STATUS_IS_OK(status
)) {
1850 printf("READ lock2 succeeded! This is a locking bug\n");
1853 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1854 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1859 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1860 if (!NT_STATUS_IS_OK(status
)) {
1861 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1864 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1865 printf("unlock at 100 succeeded! This is a locking bug\n");
1869 status
= cli_unlock(cli
, fnum1
, 0, 4);
1870 if (NT_STATUS_IS_OK(status
)) {
1871 printf("unlock1 succeeded! This is a locking bug\n");
1874 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1875 NT_STATUS_RANGE_NOT_LOCKED
)) {
1880 status
= cli_unlock(cli
, fnum1
, 0, 8);
1881 if (NT_STATUS_IS_OK(status
)) {
1882 printf("unlock2 succeeded! This is a locking bug\n");
1885 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1886 NT_STATUS_RANGE_NOT_LOCKED
)) {
1891 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1892 if (NT_STATUS_IS_OK(status
)) {
1893 printf("lock3 succeeded! This is a locking bug\n");
1896 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1897 NT_STATUS_LOCK_NOT_GRANTED
)) {
1904 status
= cli_close(cli
, fnum1
);
1905 if (!NT_STATUS_IS_OK(status
)) {
1906 printf("close1 failed (%s)\n", nt_errstr(status
));
1910 status
= cli_close(cli
, fnum2
);
1911 if (!NT_STATUS_IS_OK(status
)) {
1912 printf("close2 failed (%s)\n", nt_errstr(status
));
1916 status
= cli_close(cli
, fnum3
);
1917 if (!NT_STATUS_IS_OK(status
)) {
1918 printf("close3 failed (%s)\n", nt_errstr(status
));
1922 if (!torture_close_connection(cli
)) {
1926 printf("locktest2 finished\n");
1933 This test checks that
1935 1) the server supports the full offset range in lock requests
1937 static bool run_locktest3(int dummy
)
1939 static struct cli_state
*cli1
, *cli2
;
1940 const char *fname
= "\\lockt3.lck";
1941 uint16_t fnum1
, fnum2
;
1944 bool correct
= True
;
1947 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1949 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1952 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1953 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1955 printf("starting locktest3\n");
1957 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1959 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1961 if (!NT_STATUS_IS_OK(status
)) {
1962 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1966 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1967 if (!NT_STATUS_IS_OK(status
)) {
1968 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1972 for (offset
=i
=0;i
<torture_numops
;i
++) {
1975 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1976 if (!NT_STATUS_IS_OK(status
)) {
1977 printf("lock1 %d failed (%s)\n",
1983 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1984 if (!NT_STATUS_IS_OK(status
)) {
1985 printf("lock2 %d failed (%s)\n",
1992 for (offset
=i
=0;i
<torture_numops
;i
++) {
1995 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1996 if (NT_STATUS_IS_OK(status
)) {
1997 printf("error: lock1 %d succeeded!\n", i
);
2001 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
2002 if (NT_STATUS_IS_OK(status
)) {
2003 printf("error: lock2 %d succeeded!\n", i
);
2007 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
2008 if (NT_STATUS_IS_OK(status
)) {
2009 printf("error: lock3 %d succeeded!\n", i
);
2013 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
2014 if (NT_STATUS_IS_OK(status
)) {
2015 printf("error: lock4 %d succeeded!\n", i
);
2020 for (offset
=i
=0;i
<torture_numops
;i
++) {
2023 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
2024 if (!NT_STATUS_IS_OK(status
)) {
2025 printf("unlock1 %d failed (%s)\n",
2031 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
2032 if (!NT_STATUS_IS_OK(status
)) {
2033 printf("unlock2 %d failed (%s)\n",
2040 status
= cli_close(cli1
, fnum1
);
2041 if (!NT_STATUS_IS_OK(status
)) {
2042 printf("close1 failed (%s)\n", nt_errstr(status
));
2046 status
= cli_close(cli2
, fnum2
);
2047 if (!NT_STATUS_IS_OK(status
)) {
2048 printf("close2 failed (%s)\n", nt_errstr(status
));
2052 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2053 if (!NT_STATUS_IS_OK(status
)) {
2054 printf("unlink failed (%s)\n", nt_errstr(status
));
2058 if (!torture_close_connection(cli1
)) {
2062 if (!torture_close_connection(cli2
)) {
2066 printf("finished locktest3\n");
2071 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
2072 char *buf
, off_t offset
, size_t size
,
2073 size_t *nread
, size_t expect
)
2078 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
2080 if(!NT_STATUS_IS_OK(status
)) {
2082 } else if (l_nread
!= expect
) {
2093 #define EXPECTED(ret, v) if ((ret) != (v)) { \
2094 printf("** "); correct = False; \
2098 looks at overlapping locks
2100 static bool run_locktest4(int dummy
)
2102 static struct cli_state
*cli1
, *cli2
;
2103 const char *fname
= "\\lockt4.lck";
2104 uint16_t fnum1
, fnum2
, f
;
2107 bool correct
= True
;
2110 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2114 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2115 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2117 printf("starting locktest4\n");
2119 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2121 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2122 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2124 memset(buf
, 0, sizeof(buf
));
2126 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2128 if (!NT_STATUS_IS_OK(status
)) {
2129 printf("Failed to create file: %s\n", nt_errstr(status
));
2134 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2135 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
2136 EXPECTED(ret
, False
);
2137 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
2139 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
2140 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
2141 EXPECTED(ret
, True
);
2142 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
2144 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
2145 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
2146 EXPECTED(ret
, False
);
2147 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
2149 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
2150 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
2151 EXPECTED(ret
, True
);
2152 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
2154 ret
= (cli_setpid(cli1
, 1),
2155 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
2156 (cli_setpid(cli1
, 2),
2157 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
2158 EXPECTED(ret
, False
);
2159 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
2161 ret
= (cli_setpid(cli1
, 1),
2162 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
2163 (cli_setpid(cli1
, 2),
2164 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
2165 EXPECTED(ret
, True
);
2166 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
2168 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
2169 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
2170 EXPECTED(ret
, True
);
2171 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
2173 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
2174 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
2175 EXPECTED(ret
, False
);
2176 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
2178 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
2179 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
2180 EXPECTED(ret
, False
);
2181 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
2183 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
2184 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
2185 EXPECTED(ret
, True
);
2186 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2188 ret
= (cli_setpid(cli1
, 1),
2189 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2190 (cli_setpid(cli1
, 2),
2191 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2192 EXPECTED(ret
, False
);
2193 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2195 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2196 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2197 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2198 EXPECTED(ret
, False
);
2199 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2202 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2203 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2204 EXPECTED(ret
, False
);
2205 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2207 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2208 ret
= NT_STATUS_IS_OK(status
);
2210 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2212 ret
= NT_STATUS_IS_OK(status
);
2214 EXPECTED(ret
, False
);
2215 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2218 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2219 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2220 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2221 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2222 EXPECTED(ret
, True
);
2223 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2226 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2227 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2228 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2229 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2230 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2232 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2233 EXPECTED(ret
, True
);
2234 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2236 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2237 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2238 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2240 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2241 EXPECTED(ret
, True
);
2242 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2244 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2245 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2246 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2248 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2249 EXPECTED(ret
, True
);
2250 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2252 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2253 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2254 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2255 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2257 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2258 EXPECTED(ret
, True
);
2259 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2261 cli_close(cli1
, fnum1
);
2262 cli_close(cli2
, fnum2
);
2263 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2264 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2265 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2266 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2267 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2268 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2269 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2271 cli_close(cli1
, fnum1
);
2272 EXPECTED(ret
, True
);
2273 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2276 cli_close(cli1
, fnum1
);
2277 cli_close(cli2
, fnum2
);
2278 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2279 torture_close_connection(cli1
);
2280 torture_close_connection(cli2
);
2282 printf("finished locktest4\n");
2287 looks at lock upgrade/downgrade.
2289 static bool run_locktest5(int dummy
)
2291 static struct cli_state
*cli1
, *cli2
;
2292 const char *fname
= "\\lockt5.lck";
2293 uint16_t fnum1
, fnum2
, fnum3
;
2296 bool correct
= True
;
2299 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2303 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2304 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2306 printf("starting locktest5\n");
2308 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2310 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2311 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2312 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2314 memset(buf
, 0, sizeof(buf
));
2316 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2318 if (!NT_STATUS_IS_OK(status
)) {
2319 printf("Failed to create file: %s\n", nt_errstr(status
));
2324 /* Check for NT bug... */
2325 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2326 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2327 cli_close(cli1
, fnum1
);
2328 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2329 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2330 ret
= NT_STATUS_IS_OK(status
);
2331 EXPECTED(ret
, True
);
2332 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2333 cli_close(cli1
, fnum1
);
2334 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2335 cli_unlock(cli1
, fnum3
, 0, 1);
2337 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2338 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2339 EXPECTED(ret
, True
);
2340 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2342 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2343 ret
= NT_STATUS_IS_OK(status
);
2344 EXPECTED(ret
, False
);
2346 printf("a different process %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2348 /* Unlock the process 2 lock. */
2349 cli_unlock(cli2
, fnum2
, 0, 4);
2351 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2352 ret
= NT_STATUS_IS_OK(status
);
2353 EXPECTED(ret
, False
);
2355 printf("the same process on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2357 /* Unlock the process 1 fnum3 lock. */
2358 cli_unlock(cli1
, fnum3
, 0, 4);
2360 /* Stack 2 more locks here. */
2361 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2362 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2364 EXPECTED(ret
, True
);
2365 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2367 /* Unlock the first process lock, then check this was the WRITE lock that was
2370 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2371 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2373 EXPECTED(ret
, True
);
2374 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2376 /* Unlock the process 2 lock. */
2377 cli_unlock(cli2
, fnum2
, 0, 4);
2379 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2381 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2382 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2383 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2385 EXPECTED(ret
, True
);
2386 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2388 /* Ensure the next unlock fails. */
2389 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2390 EXPECTED(ret
, False
);
2391 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2393 /* Ensure connection 2 can get a write lock. */
2394 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2395 ret
= NT_STATUS_IS_OK(status
);
2396 EXPECTED(ret
, True
);
2398 printf("a different process %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2402 cli_close(cli1
, fnum1
);
2403 cli_close(cli2
, fnum2
);
2404 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2405 if (!torture_close_connection(cli1
)) {
2408 if (!torture_close_connection(cli2
)) {
2412 printf("finished locktest5\n");
2418 tries the unusual lockingX locktype bits
2420 static bool run_locktest6(int dummy
)
2422 static struct cli_state
*cli
;
2423 const char *fname
[1] = { "\\lock6.txt" };
2428 if (!torture_open_connection(&cli
, 0)) {
2432 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2434 printf("starting locktest6\n");
2437 printf("Testing %s\n", fname
[i
]);
2439 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2441 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2442 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2443 cli_close(cli
, fnum
);
2444 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2446 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2447 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2448 cli_close(cli
, fnum
);
2449 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2451 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2454 torture_close_connection(cli
);
2456 printf("finished locktest6\n");
2460 static bool run_locktest7(int dummy
)
2462 struct cli_state
*cli1
;
2463 const char *fname
= "\\lockt7.lck";
2466 bool correct
= False
;
2470 if (!torture_open_connection(&cli1
, 0)) {
2474 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2476 printf("starting locktest7\n");
2478 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2480 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2482 memset(buf
, 0, sizeof(buf
));
2484 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2486 if (!NT_STATUS_IS_OK(status
)) {
2487 printf("Failed to create file: %s\n", nt_errstr(status
));
2491 cli_setpid(cli1
, 1);
2493 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2494 if (!NT_STATUS_IS_OK(status
)) {
2495 printf("Unable to apply read lock on range 130:4, "
2496 "error was %s\n", nt_errstr(status
));
2499 printf("pid1 successfully locked range 130:4 for READ\n");
2502 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2503 if (!NT_STATUS_IS_OK(status
)) {
2504 printf("pid1 unable to read the range 130:4, error was %s\n",
2507 } else if (nread
!= 4) {
2508 printf("pid1 unable to read the range 130:4, "
2509 "recv %ld req %d\n", (unsigned long)nread
, 4);
2512 printf("pid1 successfully read the range 130:4\n");
2515 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2516 if (!NT_STATUS_IS_OK(status
)) {
2517 printf("pid1 unable to write to the range 130:4, error was "
2518 "%s\n", nt_errstr(status
));
2519 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2520 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2524 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2528 cli_setpid(cli1
, 2);
2530 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2531 if (!NT_STATUS_IS_OK(status
)) {
2532 printf("pid2 unable to read the range 130:4, error was %s\n",
2535 } else if (nread
!= 4) {
2536 printf("pid2 unable to read the range 130:4, "
2537 "recv %ld req %d\n", (unsigned long)nread
, 4);
2540 printf("pid2 successfully read the range 130:4\n");
2543 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2544 if (!NT_STATUS_IS_OK(status
)) {
2545 printf("pid2 unable to write to the range 130:4, error was "
2546 "%s\n", nt_errstr(status
));
2547 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2548 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2552 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2556 cli_setpid(cli1
, 1);
2557 cli_unlock(cli1
, fnum1
, 130, 4);
2559 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2560 if (!NT_STATUS_IS_OK(status
)) {
2561 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2564 printf("pid1 successfully locked range 130:4 for WRITE\n");
2567 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2568 if (!NT_STATUS_IS_OK(status
)) {
2569 printf("pid1 unable to read the range 130:4, error was %s\n",
2572 } else if (nread
!= 4) {
2573 printf("pid1 unable to read the range 130:4, "
2574 "recv %ld req %d\n", (unsigned long)nread
, 4);
2577 printf("pid1 successfully read the range 130:4\n");
2580 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2581 if (!NT_STATUS_IS_OK(status
)) {
2582 printf("pid1 unable to write to the range 130:4, error was "
2583 "%s\n", nt_errstr(status
));
2586 printf("pid1 successfully wrote to the range 130:4\n");
2589 cli_setpid(cli1
, 2);
2591 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2592 if (!NT_STATUS_IS_OK(status
)) {
2593 printf("pid2 unable to read the range 130:4, error was "
2594 "%s\n", nt_errstr(status
));
2595 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2596 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2600 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2601 (unsigned long)nread
);
2605 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2606 if (!NT_STATUS_IS_OK(status
)) {
2607 printf("pid2 unable to write to the range 130:4, error was "
2608 "%s\n", nt_errstr(status
));
2609 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2610 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2614 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2618 cli_unlock(cli1
, fnum1
, 130, 0);
2622 cli_close(cli1
, fnum1
);
2623 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2624 torture_close_connection(cli1
);
2626 printf("finished locktest7\n");
2631 * This demonstrates a problem with our use of GPFS share modes: A file
2632 * descriptor sitting in the pending close queue holding a GPFS share mode
2633 * blocks opening a file another time. Happens with Word 2007 temp files.
2634 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2635 * open is denied with NT_STATUS_SHARING_VIOLATION.
2638 static bool run_locktest8(int dummy
)
2640 struct cli_state
*cli1
;
2641 const char *fname
= "\\lockt8.lck";
2642 uint16_t fnum1
, fnum2
;
2644 bool correct
= False
;
2647 if (!torture_open_connection(&cli1
, 0)) {
2651 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2653 printf("starting locktest8\n");
2655 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2657 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2659 if (!NT_STATUS_IS_OK(status
)) {
2660 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2664 memset(buf
, 0, sizeof(buf
));
2666 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2667 if (!NT_STATUS_IS_OK(status
)) {
2668 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2673 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2674 if (!NT_STATUS_IS_OK(status
)) {
2675 printf("Unable to apply read lock on range 1:1, error was "
2676 "%s\n", nt_errstr(status
));
2680 status
= cli_close(cli1
, fnum1
);
2681 if (!NT_STATUS_IS_OK(status
)) {
2682 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2686 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2687 if (!NT_STATUS_IS_OK(status
)) {
2688 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2696 cli_close(cli1
, fnum1
);
2697 cli_close(cli1
, fnum2
);
2698 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2699 torture_close_connection(cli1
);
2701 printf("finished locktest8\n");
2706 * This test is designed to be run in conjunction with
2707 * external NFS or POSIX locks taken in the filesystem.
2708 * It checks that the smbd server will block until the
2709 * lock is released and then acquire it. JRA.
2712 static bool got_alarm
;
2713 static struct cli_state
*alarm_cli
;
2715 static void alarm_handler(int dummy
)
2720 static void alarm_handler_parent(int dummy
)
2722 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_LOCAL_DISCONNECT
);
2725 static void do_local_lock(const char *fname
, int read_fd
, int write_fd
)
2730 const char *local_pathname
= NULL
;
2733 local_pathname
= talloc_asprintf(talloc_tos(),
2734 "%s/%s", local_path
, fname
);
2735 if (!local_pathname
) {
2736 printf("child: alloc fail\n");
2740 unlink(local_pathname
);
2741 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2743 printf("child: open of %s failed %s.\n",
2744 local_pathname
, strerror(errno
));
2748 /* Now take a fcntl lock. */
2749 lock
.l_type
= F_WRLCK
;
2750 lock
.l_whence
= SEEK_SET
;
2753 lock
.l_pid
= getpid();
2755 ret
= fcntl(fd
,F_SETLK
,&lock
);
2757 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2758 local_pathname
, strerror(errno
));
2761 printf("child: got lock 0:4 on file %s.\n",
2766 CatchSignal(SIGALRM
, alarm_handler
);
2768 /* Signal the parent. */
2769 if (write(write_fd
, &c
, 1) != 1) {
2770 printf("child: start signal fail %s.\n",
2777 /* Wait for the parent to be ready. */
2778 if (read(read_fd
, &c
, 1) != 1) {
2779 printf("child: reply signal fail %s.\n",
2787 printf("child: released lock 0:4 on file %s.\n",
2793 static bool _run_locktest9X(const char *fname
, int timeout
)
2795 struct cli_state
*cli1
;
2796 char *fpath
= talloc_asprintf(talloc_tos(), "\\%s", fname
);
2798 bool correct
= False
;
2799 int pipe_in
[2], pipe_out
[2];
2803 struct timeval start
;
2807 printf("starting locktest9X: %s\n", fname
);
2809 if (local_path
== NULL
) {
2810 d_fprintf(stderr
, "locktest9X must be given a local path via -l <localpath>\n");
2814 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2819 if (child_pid
== -1) {
2823 if (child_pid
== 0) {
2825 do_local_lock(fname
, pipe_out
[0], pipe_in
[1]);
2835 ret
= read(pipe_in
[0], &c
, 1);
2837 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2842 if (!torture_open_connection(&cli1
, 0)) {
2846 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2848 status
= cli_openx(cli1
, fpath
, O_RDWR
, DENY_NONE
,
2850 if (!NT_STATUS_IS_OK(status
)) {
2851 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2855 /* Ensure the child has the lock. */
2856 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2857 if (NT_STATUS_IS_OK(status
)) {
2858 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2861 d_printf("Child has the lock.\n");
2864 /* Tell the child to wait 5 seconds then exit. */
2865 ret
= write(pipe_out
[1], &c
, 1);
2867 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2872 /* Wait 20 seconds for the lock. */
2874 CatchSignal(SIGALRM
, alarm_handler_parent
);
2877 start
= timeval_current();
2879 status
= cli_lock32(cli1
, fnum
, 0, 4, timeout
, WRITE_LOCK
);
2880 if (!NT_STATUS_IS_OK(status
)) {
2881 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2882 "%s\n", nt_errstr(status
));
2887 seconds
= timeval_elapsed(&start
);
2889 printf("Parent got the lock after %.2f seconds.\n",
2892 status
= cli_close(cli1
, fnum
);
2893 if (!NT_STATUS_IS_OK(status
)) {
2894 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2901 cli_close(cli1
, fnum
);
2902 torture_close_connection(cli1
);
2906 printf("finished locktest9X: %s\n", fname
);
2910 static bool run_locktest9a(int dummy
)
2912 return _run_locktest9X("lock9a.dat", -1);
2915 static bool run_locktest9b(int dummy
)
2917 return _run_locktest9X("lock9b.dat", 10000);
2920 struct locktest10_state
{
2925 static void locktest10_lockingx_done(struct tevent_req
*subreq
);
2926 static void locktest10_read_andx_done(struct tevent_req
*subreq
);
2928 static bool run_locktest10(int dummy
)
2930 struct tevent_context
*ev
= NULL
;
2931 struct cli_state
*cli1
= NULL
;
2932 struct cli_state
*cli2
= NULL
;
2933 struct smb1_lock_element lck
= { 0 };
2934 struct tevent_req
*reqs
[2] = { NULL
};
2935 struct tevent_req
*smbreqs
[2] = { NULL
};
2936 const char fname
[] = "\\lockt10.lck";
2937 uint16_t fnum1
, fnum2
;
2941 struct locktest10_state state
= { .ok
= true };
2944 printf("starting locktest10\n");
2946 ev
= samba_tevent_context_init(NULL
);
2948 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
2952 ok
= torture_open_connection(&cli1
, 0);
2956 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2958 ok
= torture_open_connection(&cli2
, 1);
2962 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2964 status
= cli_openx(cli1
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum1
);
2965 if (!NT_STATUS_IS_OK(status
)) {
2967 "cli_openx failed: %s\n",
2972 status
= cli_writeall(cli1
, fnum1
, 0, &data
, 0, sizeof(data
), NULL
);
2973 if (!NT_STATUS_IS_OK(status
)) {
2975 "cli_writeall failed: %s\n",
2980 status
= cli_openx(cli2
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum2
);
2981 if (!NT_STATUS_IS_OK(status
)) {
2983 "cli_openx failed: %s\n",
2988 status
= cli_locktype(
2989 cli2
, fnum2
, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK
);
2990 if (!NT_STATUS_IS_OK(status
)) {
2992 "cli_locktype failed: %s\n",
2997 lck
= (struct smb1_lock_element
) {
2998 .pid
= cli_getpid(cli1
), .offset
= 0, .length
= 1,
3001 reqs
[0] = cli_lockingx_create(
3003 ev
, /* tevent_context */
3006 LOCKING_ANDX_EXCLUSIVE_LOCK
, /* typeoflock */
3007 0, /* newoplocklevel */
3009 0, /* num_unlocks */
3013 &smbreqs
[0]); /* psmbreq */
3014 if (reqs
[0] == NULL
) {
3015 d_fprintf(stderr
, "cli_lockingx_create failed\n");
3018 tevent_req_set_callback(reqs
[0], locktest10_lockingx_done
, &state
);
3020 reqs
[1] = cli_read_andx_create(
3027 &smbreqs
[1]); /* psmbreq */
3028 if (reqs
[1] == NULL
) {
3029 d_fprintf(stderr
, "cli_read_andx_create failed\n");
3032 tevent_req_set_callback(reqs
[1], locktest10_read_andx_done
, &state
);
3034 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
3035 if (!NT_STATUS_IS_OK(status
)) {
3037 "smb1cli_req_chain_submit failed: %s\n",
3042 while (!state
.done
) {
3043 tevent_loop_once(ev
);
3046 torture_close_connection(cli1
);
3055 static void locktest10_lockingx_done(struct tevent_req
*subreq
)
3057 struct locktest10_state
*state
= tevent_req_callback_data_void(subreq
);
3060 status
= cli_lockingx_recv(subreq
);
3061 TALLOC_FREE(subreq
);
3063 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
3064 d_printf("cli_lockingx returned %s\n", nt_errstr(status
));
3069 static void locktest10_read_andx_done(struct tevent_req
*subreq
)
3071 struct locktest10_state
*state
= tevent_req_callback_data_void(subreq
);
3072 ssize_t received
= -1;
3073 uint8_t *rcvbuf
= NULL
;
3076 status
= cli_read_andx_recv(subreq
, &received
, &rcvbuf
);
3078 if (!NT_STATUS_EQUAL(status
, NT_STATUS_REQUEST_ABORTED
)) {
3079 d_printf("cli_read_andx returned %s\n", nt_errstr(status
));
3084 TALLOC_FREE(subreq
);
3087 static bool run_locktest11(int dummy
)
3089 struct cli_state
*cli1
;
3090 const char *fname
= "\\lockt11.lck";
3095 if (!torture_open_connection(&cli1
, 0)) {
3099 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3101 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3103 status
= cli_openx(cli1
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum
);
3104 if (!NT_STATUS_IS_OK(status
)) {
3106 "cli_openx returned %s\n",
3112 * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
3113 * returns NT_STATUS_OK
3116 status
= cli_lockingx(
3119 LOCKING_ANDX_CANCEL_LOCK
, /* typeoflock */
3120 0, /* newoplocklevel */
3122 0, /* num_unlocks */
3127 if (!NT_STATUS_IS_OK(status
)) {
3128 d_printf("cli_lockingX returned %s\n", nt_errstr(status
));
3134 cli_close(cli1
, fnum
);
3135 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3140 struct deferred_close_state
{
3141 struct tevent_context
*ev
;
3142 struct cli_state
*cli
;
3146 static void deferred_close_waited(struct tevent_req
*subreq
);
3147 static void deferred_close_done(struct tevent_req
*subreq
);
3149 static struct tevent_req
*deferred_close_send(
3150 TALLOC_CTX
*mem_ctx
,
3151 struct tevent_context
*ev
,
3153 struct cli_state
*cli
,
3156 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3157 struct deferred_close_state
*state
= NULL
;
3158 struct timeval wakeup_time
= timeval_current_ofs(wait_secs
, 0);
3160 req
= tevent_req_create(
3161 mem_ctx
, &state
, struct deferred_close_state
);
3169 subreq
= tevent_wakeup_send(state
, state
->ev
, wakeup_time
);
3170 if (tevent_req_nomem(subreq
, req
)) {
3171 return tevent_req_post(req
, ev
);
3173 tevent_req_set_callback(subreq
, deferred_close_waited
, req
);
3177 static void deferred_close_waited(struct tevent_req
*subreq
)
3179 struct tevent_req
*req
= tevent_req_callback_data(
3180 subreq
, struct tevent_req
);
3181 struct deferred_close_state
*state
= tevent_req_data(
3182 req
, struct deferred_close_state
);
3185 ok
= tevent_wakeup_recv(subreq
);
3186 TALLOC_FREE(subreq
);
3188 tevent_req_oom(req
);
3192 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, state
->fnum
, 0);
3193 if (tevent_req_nomem(subreq
, req
)) {
3196 tevent_req_set_callback(subreq
, deferred_close_done
, req
);
3199 static void deferred_close_done(struct tevent_req
*subreq
)
3201 NTSTATUS status
= cli_close_recv(subreq
);
3202 tevent_req_simple_finish_ntstatus(subreq
, status
);
3205 static NTSTATUS
deferred_close_recv(struct tevent_req
*req
)
3207 return tevent_req_simple_recv_ntstatus(req
);
3210 struct lockread_state
{
3211 struct smb1_lock_element lck
;
3212 struct tevent_req
*reqs
[2];
3213 struct tevent_req
*smbreqs
[2];
3214 NTSTATUS lock_status
;
3215 NTSTATUS read_status
;
3219 static void lockread_lockingx_done(struct tevent_req
*subreq
);
3220 static void lockread_read_andx_done(struct tevent_req
*subreq
);
3222 static struct tevent_req
*lockread_send(
3223 TALLOC_CTX
*mem_ctx
,
3224 struct tevent_context
*ev
,
3225 struct cli_state
*cli
,
3228 struct tevent_req
*req
= NULL
;
3229 struct lockread_state
*state
= NULL
;
3232 req
= tevent_req_create(mem_ctx
, &state
, struct lockread_state
);
3237 state
->lck
= (struct smb1_lock_element
) {
3238 .pid
= cli_getpid(cli
), .offset
= 0, .length
= 1,
3241 state
->reqs
[0] = cli_lockingx_create(
3243 ev
, /* tevent_context */
3246 LOCKING_ANDX_EXCLUSIVE_LOCK
, /* typeoflock */
3247 0, /* newoplocklevel */
3248 10000, /* timeout */
3249 0, /* num_unlocks */
3252 &state
->lck
, /* locks */
3253 &state
->smbreqs
[0]); /* psmbreq */
3254 if (tevent_req_nomem(state
->reqs
[0], req
)) {
3255 return tevent_req_post(req
, ev
);
3257 tevent_req_set_callback(
3258 state
->reqs
[0], lockread_lockingx_done
, req
);
3260 state
->reqs
[1] = cli_read_andx_create(
3267 &state
->smbreqs
[1]); /* psmbreq */
3268 if (tevent_req_nomem(state
->reqs
[1], req
)) {
3269 return tevent_req_post(req
, ev
);
3271 tevent_req_set_callback(
3272 state
->reqs
[1], lockread_read_andx_done
, req
);
3274 status
= smb1cli_req_chain_submit(state
->smbreqs
, 2);
3275 if (tevent_req_nterror(req
, status
)) {
3276 return tevent_req_post(req
, ev
);
3281 static void lockread_lockingx_done(struct tevent_req
*subreq
)
3283 struct tevent_req
*req
= tevent_req_callback_data(
3284 subreq
, struct tevent_req
);
3285 struct lockread_state
*state
= tevent_req_data(
3286 req
, struct lockread_state
);
3287 state
->lock_status
= cli_lockingx_recv(subreq
);
3288 TALLOC_FREE(subreq
);
3290 "lockingx returned %s\n",
3291 nt_errstr(state
->lock_status
));
3294 static void lockread_read_andx_done(struct tevent_req
*subreq
)
3296 struct tevent_req
*req
= tevent_req_callback_data(
3297 subreq
, struct tevent_req
);
3298 struct lockread_state
*state
= tevent_req_data(
3299 req
, struct lockread_state
);
3300 ssize_t received
= -1;
3301 uint8_t *rcvbuf
= NULL
;
3303 state
->read_status
= cli_read_andx_recv(subreq
, &received
, &rcvbuf
);
3306 "read returned %s\n",
3307 nt_errstr(state
->read_status
));
3309 if (!NT_STATUS_IS_OK(state
->read_status
)) {
3310 TALLOC_FREE(subreq
);
3311 tevent_req_done(req
);
3316 state
->readbuf
= talloc_memdup(state
, rcvbuf
, received
);
3317 TALLOC_FREE(subreq
);
3318 if (tevent_req_nomem(state
->readbuf
, req
)) {
3322 TALLOC_FREE(subreq
);
3323 tevent_req_done(req
);
3326 static NTSTATUS
lockread_recv(
3327 struct tevent_req
*req
,
3328 NTSTATUS
*lock_status
,
3329 NTSTATUS
*read_status
,
3330 TALLOC_CTX
*mem_ctx
,
3333 struct lockread_state
*state
= tevent_req_data(
3334 req
, struct lockread_state
);
3337 if (tevent_req_is_nterror(req
, &status
)) {
3341 *lock_status
= state
->lock_status
;
3342 *read_status
= state
->read_status
;
3343 if (state
->readbuf
!= NULL
) {
3344 *read_buf
= talloc_move(mem_ctx
, &state
->readbuf
);
3349 return NT_STATUS_OK
;
3352 struct lock12_state
{
3356 static void lock12_closed(struct tevent_req
*subreq
);
3357 static void lock12_read(struct tevent_req
*subreq
);
3359 static struct tevent_req
*lock12_send(
3360 TALLOC_CTX
*mem_ctx
,
3361 struct tevent_context
*ev
,
3362 struct cli_state
*cli
,
3366 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3367 struct lock12_state
*state
= NULL
;
3369 req
= tevent_req_create(mem_ctx
, &state
, struct lock12_state
);
3374 subreq
= deferred_close_send(state
, ev
, 1, cli
, fnum1
);
3375 if (tevent_req_nomem(subreq
, req
)) {
3376 return tevent_req_post(req
, ev
);
3378 tevent_req_set_callback(subreq
, lock12_closed
, req
);
3380 subreq
= lockread_send(state
, ev
, cli
, fnum2
);
3381 if (tevent_req_nomem(subreq
, req
)) {
3382 return tevent_req_post(req
, ev
);
3384 tevent_req_set_callback(subreq
, lock12_read
, req
);
3389 static void lock12_closed(struct tevent_req
*subreq
)
3391 struct tevent_req
*req
= tevent_req_callback_data(
3392 subreq
, struct tevent_req
);
3395 status
= deferred_close_recv(subreq
);
3396 TALLOC_FREE(subreq
);
3397 DBG_DEBUG("close returned %s\n", nt_errstr(status
));
3398 if (tevent_req_nterror(req
, status
)) {
3403 static void lock12_read(struct tevent_req
*subreq
)
3405 struct tevent_req
*req
= tevent_req_callback_data(
3406 subreq
, struct tevent_req
);
3407 struct lock12_state
*state
= tevent_req_data(
3408 req
, struct lock12_state
);
3409 NTSTATUS status
, lock_status
, read_status
;
3410 uint8_t *buf
= NULL
;
3412 status
= lockread_recv(
3413 subreq
, &lock_status
, &read_status
, state
, &buf
);
3414 TALLOC_FREE(subreq
);
3415 if (tevent_req_nterror(req
, status
) ||
3416 tevent_req_nterror(req
, lock_status
) ||
3417 tevent_req_nterror(req
, read_status
)) {
3420 tevent_req_done(req
);
3423 static NTSTATUS
lock12_recv(struct tevent_req
*req
)
3428 if (tevent_req_is_nterror(req
, &status
)) {
3431 return NT_STATUS_OK
;
3434 static bool run_locktest12(int dummy
)
3436 struct tevent_context
*ev
= NULL
;
3437 struct tevent_req
*req
= NULL
;
3438 struct cli_state
*cli
= NULL
;
3439 const char fname
[] = "\\lockt12.lck";
3440 uint16_t fnum1
, fnum2
;
3446 printf("starting locktest12\n");
3448 ev
= samba_tevent_context_init(NULL
);
3450 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
3454 ok
= torture_open_connection(&cli
, 0);
3458 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
3460 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum1
);
3461 if (!NT_STATUS_IS_OK(status
)) {
3463 "cli_openx failed: %s\n",
3468 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum2
);
3469 if (!NT_STATUS_IS_OK(status
)) {
3471 "cli_openx failed: %s\n",
3476 status
= cli_writeall(cli
, fnum1
, 0, &data
, 0, sizeof(data
), NULL
);
3477 if (!NT_STATUS_IS_OK(status
)) {
3479 "cli_writeall failed: %s\n",
3484 status
= cli_locktype(
3485 cli
, fnum1
, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK
);
3486 if (!NT_STATUS_IS_OK(status
)) {
3488 "cli_locktype failed: %s\n",
3493 req
= lock12_send(ev
, ev
, cli
, fnum1
, fnum2
);
3495 d_fprintf(stderr
, "lock12_send failed\n");
3499 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
3501 d_fprintf(stderr
, "tevent_req_poll_ntstatus failed\n");
3505 if (!NT_STATUS_IS_OK(status
)) {
3507 "tevent_req_poll_ntstatus returned %s\n",
3512 status
= lock12_recv(req
);
3513 if (!NT_STATUS_IS_OK(status
)) {
3514 d_fprintf(stderr
, "lock12 returned %s\n", nt_errstr(status
));
3521 torture_close_connection(cli
);
3526 struct lock_ntcancel_state
{
3527 struct timeval start
;
3528 struct smb1_lock_element lck
;
3529 struct tevent_req
*subreq
;
3532 static void lock_ntcancel_waited(struct tevent_req
*subreq
);
3533 static void lock_ntcancel_done(struct tevent_req
*subreq
);
3535 static struct tevent_req
*lock_ntcancel_send(
3536 TALLOC_CTX
*mem_ctx
,
3537 struct tevent_context
*ev
,
3538 struct cli_state
*cli
,
3541 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
3542 struct lock_ntcancel_state
*state
= NULL
;
3544 req
= tevent_req_create(mem_ctx
, &state
, struct lock_ntcancel_state
);
3548 state
->lck
= (struct smb1_lock_element
) {
3549 .pid
= cli_getpid(cli
), .offset
= 0, .length
= 1,
3551 state
->start
= timeval_current();
3553 state
->subreq
= cli_lockingx_send(
3554 state
, /* mem_ctx */
3555 ev
, /* tevent_context */
3558 LOCKING_ANDX_EXCLUSIVE_LOCK
, /* typeoflock */
3559 0, /* newoplocklevel */
3560 10000, /* timeout */
3561 0, /* num_unlocks */
3564 &state
->lck
); /* locks */
3565 if (tevent_req_nomem(state
->subreq
, req
)) {
3566 return tevent_req_post(req
, ev
);
3568 tevent_req_set_callback(state
->subreq
, lock_ntcancel_done
, req
);
3570 subreq
= tevent_wakeup_send(state
, ev
, timeval_current_ofs(1, 0));
3571 if (tevent_req_nomem(subreq
, req
)) {
3572 return tevent_req_post(req
, ev
);
3574 tevent_req_set_callback(subreq
, lock_ntcancel_waited
, req
);
3578 static void lock_ntcancel_waited(struct tevent_req
*subreq
)
3580 struct tevent_req
*req
= tevent_req_callback_data(
3581 subreq
, struct tevent_req
);
3582 struct lock_ntcancel_state
*state
= tevent_req_data(
3583 req
, struct lock_ntcancel_state
);
3586 ok
= tevent_wakeup_recv(subreq
);
3587 TALLOC_FREE(subreq
);
3589 tevent_req_oom(req
);
3593 ok
= tevent_req_cancel(state
->subreq
);
3595 d_fprintf(stderr
, "Could not cancel subreq\n");
3596 tevent_req_oom(req
);
3601 static void lock_ntcancel_done(struct tevent_req
*subreq
)
3603 struct tevent_req
*req
= tevent_req_callback_data(
3604 subreq
, struct tevent_req
);
3605 struct lock_ntcancel_state
*state
= tevent_req_data(
3606 req
, struct lock_ntcancel_state
);
3610 status
= cli_lockingx_recv(subreq
);
3611 TALLOC_FREE(subreq
);
3613 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
3614 d_printf("cli_lockingx returned %s\n", nt_errstr(status
));
3615 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
3619 elapsed
= timeval_elapsed(&state
->start
);
3622 d_printf("cli_lockingx was too slow, cancel did not work\n");
3623 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
3627 tevent_req_done(req
);
3630 static NTSTATUS
lock_ntcancel_recv(struct tevent_req
*req
)
3632 return tevent_req_simple_recv_ntstatus(req
);
3635 static bool run_locktest13(int dummy
)
3637 struct tevent_context
*ev
= NULL
;
3638 struct tevent_req
*req
= NULL
;
3639 struct cli_state
*cli
= NULL
;
3640 const char fname
[] = "\\lockt13.lck";
3641 uint16_t fnum1
, fnum2
;
3647 printf("starting locktest13\n");
3649 ev
= samba_tevent_context_init(NULL
);
3651 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
3655 ok
= torture_open_connection(&cli
, 0);
3659 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
3661 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum1
);
3662 if (!NT_STATUS_IS_OK(status
)) {
3664 "cli_openx failed: %s\n",
3669 status
= cli_openx(cli
, fname
, O_CREAT
|O_RDWR
, DENY_NONE
, &fnum2
);
3670 if (!NT_STATUS_IS_OK(status
)) {
3672 "cli_openx failed: %s\n",
3677 status
= cli_writeall(cli
, fnum1
, 0, &data
, 0, sizeof(data
), NULL
);
3678 if (!NT_STATUS_IS_OK(status
)) {
3680 "cli_writeall failed: %s\n",
3685 status
= cli_locktype(
3686 cli
, fnum1
, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK
);
3687 if (!NT_STATUS_IS_OK(status
)) {
3689 "cli_locktype failed: %s\n",
3694 req
= lock_ntcancel_send(ev
, ev
, cli
, fnum2
);
3696 d_fprintf(stderr
, "lock_ntcancel_send failed\n");
3700 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
3702 d_fprintf(stderr
, "tevent_req_poll_ntstatus failed\n");
3706 if (!NT_STATUS_IS_OK(status
)) {
3708 "tevent_req_poll_ntstatus returned %s\n",
3713 status
= lock_ntcancel_recv(req
);
3714 if (!NT_STATUS_IS_OK(status
)) {
3716 "lock_ntcancel returned %s\n",
3724 torture_close_connection(cli
);
3730 test whether fnums and tids open on one VC are available on another (a major
3733 static bool run_fdpasstest(int dummy
)
3735 struct cli_state
*cli1
, *cli2
;
3736 const char *fname
= "\\fdpass.tst";
3741 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
3744 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3745 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3747 printf("starting fdpasstest\n");
3749 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3751 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3753 if (!NT_STATUS_IS_OK(status
)) {
3754 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3758 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
3760 if (!NT_STATUS_IS_OK(status
)) {
3761 printf("write failed (%s)\n", nt_errstr(status
));
3765 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
3766 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
3767 cli_setpid(cli2
, cli_getpid(cli1
));
3769 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
3770 printf("read succeeded! nasty security hole [%s]\n", buf
);
3774 cli_close(cli1
, fnum1
);
3775 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3777 torture_close_connection(cli1
);
3778 torture_close_connection(cli2
);
3780 printf("finished fdpasstest\n");
3784 static bool run_fdsesstest(int dummy
)
3786 struct cli_state
*cli
;
3788 uint16_t saved_vuid
;
3790 uint32_t saved_cnum
;
3791 const char *fname
= "\\fdsess.tst";
3792 const char *fname1
= "\\fdsess1.tst";
3799 if (!torture_open_connection(&cli
, 0))
3801 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
3803 if (!torture_cli_session_setup2(cli
, &new_vuid
))
3806 saved_cnum
= cli_state_get_tid(cli
);
3807 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", NULL
)))
3809 new_cnum
= cli_state_get_tid(cli
);
3810 cli_state_set_tid(cli
, saved_cnum
);
3812 printf("starting fdsesstest\n");
3814 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3815 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3817 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
3818 if (!NT_STATUS_IS_OK(status
)) {
3819 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3823 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
3825 if (!NT_STATUS_IS_OK(status
)) {
3826 printf("write failed (%s)\n", nt_errstr(status
));
3830 saved_vuid
= cli_state_get_uid(cli
);
3831 cli_state_set_uid(cli
, new_vuid
);
3833 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
3834 printf("read succeeded with different vuid! "
3835 "nasty security hole [%s]\n", buf
);
3838 /* Try to open a file with different vuid, samba cnum. */
3839 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
3840 printf("create with different vuid, same cnum succeeded.\n");
3841 cli_close(cli
, fnum2
);
3842 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3844 printf("create with different vuid, same cnum failed.\n");
3845 printf("This will cause problems with service clients.\n");
3849 cli_state_set_uid(cli
, saved_vuid
);
3851 /* Try with same vuid, different cnum. */
3852 cli_state_set_tid(cli
, new_cnum
);
3854 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
3855 printf("read succeeded with different cnum![%s]\n", buf
);
3859 cli_state_set_tid(cli
, saved_cnum
);
3860 cli_close(cli
, fnum1
);
3861 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3863 torture_close_connection(cli
);
3865 printf("finished fdsesstest\n");
3870 This test checks that
3872 1) the server does not allow an unlink on a file that is open
3874 static bool run_unlinktest(int dummy
)
3876 struct cli_state
*cli
;
3877 const char *fname
= "\\unlink.tst";
3879 bool correct
= True
;
3882 if (!torture_open_connection(&cli
, 0)) {
3886 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
3888 printf("starting unlink test\n");
3890 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3894 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
3895 if (!NT_STATUS_IS_OK(status
)) {
3896 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3900 status
= cli_unlink(cli
, fname
,
3901 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3902 if (NT_STATUS_IS_OK(status
)) {
3903 printf("error: server allowed unlink on an open file\n");
3906 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
3907 NT_STATUS_SHARING_VIOLATION
);
3910 cli_close(cli
, fnum
);
3911 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3913 if (!torture_close_connection(cli
)) {
3917 printf("unlink test finished\n");
3924 test how many open files this server supports on the one socket
3926 static bool run_maxfidtest(int dummy
)
3928 struct cli_state
*cli
;
3930 uint16_t fnums
[0x11000];
3933 bool correct
= True
;
3939 printf("failed to connect\n");
3943 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
3945 for (i
=0; i
<0x11000; i
++) {
3946 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
3947 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
3949 if (!NT_STATUS_IS_OK(status
)) {
3950 printf("open of %s failed (%s)\n",
3951 fname
, nt_errstr(status
));
3952 printf("maximum fnum is %d\n", i
);
3960 printf("cleaning up\n");
3962 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
3963 cli_close(cli
, fnums
[i
]);
3965 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3966 if (!NT_STATUS_IS_OK(status
)) {
3967 printf("unlink of %s failed (%s)\n",
3968 fname
, nt_errstr(status
));
3975 printf("maxfid test finished\n");
3976 if (!torture_close_connection(cli
)) {
3982 /* send smb negprot commands, not reading the response */
3983 static bool run_negprot_nowait(int dummy
)
3985 struct tevent_context
*ev
;
3987 struct cli_state
*cli
;
3988 bool correct
= True
;
3990 printf("starting negprot nowait test\n");
3992 ev
= samba_tevent_context_init(talloc_tos());
3997 if (!(cli
= open_nbt_connection())) {
4002 for (i
=0;i
<50000;i
++) {
4003 struct tevent_req
*req
;
4005 req
= smbXcli_negprot_send(
4018 if (!tevent_req_poll(req
, ev
)) {
4019 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
4027 if (torture_close_connection(cli
)) {
4031 printf("finished negprot nowait test\n");
4036 /* send smb negprot commands, not reading the response */
4037 static bool run_bad_nbt_session(int dummy
)
4039 struct nmb_name called
, calling
;
4040 struct sockaddr_storage ss
;
4045 printf("starting bad nbt session test\n");
4047 make_nmb_name(&calling
, myname
, 0x0);
4048 make_nmb_name(&called
, host
, 0x20);
4050 if (!resolve_name(host
, &ss
, 0x20, true)) {
4051 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
4055 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
4056 if (!NT_STATUS_IS_OK(status
)) {
4057 d_fprintf(stderr
, "open_socket_out failed: %s\n",
4062 ret
= cli_bad_session_request(fd
, &calling
, &called
);
4065 d_fprintf(stderr
, "open_socket_out failed: %s\n",
4070 printf("finished bad nbt session test\n");
4074 /* send random IPC commands */
4075 static bool run_randomipc(int dummy
)
4078 struct cli_state
*cli
;
4079 bool correct
= True
;
4082 printf("starting random ipc test\n");
4084 if (!torture_open_connection(&cli
, 0)) {
4088 for (i
=0;i
<count
;i
++) {
4089 int api
= sys_random() % 500;
4090 int param_len
= (sys_random() % 64);
4091 uint8_t param
[1024];
4092 uint8_t *rparam
= NULL
;
4093 uint8_t *rdata
= NULL
;
4094 uint32_t rdrcnt
, rprcnt
;
4096 generate_random_buffer(param
, param_len
);
4100 cli_trans(talloc_tos(), /* mem_ctx */
4103 "\\PIPE\\LANMAN", /* name */
4111 param_len
, /* num_param */
4115 CLI_BUFFER_SIZE
, /* max_data, for W2K */
4116 NULL
, /* recv_flags2 */
4119 NULL
, /* num_rsetup */
4120 &rparam
, /* rparam */
4122 &rprcnt
, /* num_rparam */
4125 &rdrcnt
); /* num_rdata */
4127 printf("%d/%d\r", i
,count
);
4129 TALLOC_FREE(rparam
);
4132 printf("%d/%d\n", i
, count
);
4134 if (!torture_close_connection(cli
)) {
4138 printf("finished random ipc test\n");
4145 static void browse_callback(const char *sname
, uint32_t stype
,
4146 const char *comment
, void *state
)
4148 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
4154 This test checks the browse list code
4157 static bool run_browsetest(int dummy
)
4159 static struct cli_state
*cli
;
4160 bool correct
= True
;
4162 printf("starting browse test\n");
4164 if (!torture_open_connection(&cli
, 0)) {
4168 printf("domain list:\n");
4169 cli_NetServerEnum(cli
, cli
->server_domain
,
4170 SV_TYPE_DOMAIN_ENUM
,
4171 browse_callback
, NULL
);
4173 printf("machine list:\n");
4174 cli_NetServerEnum(cli
, cli
->server_domain
,
4176 browse_callback
, NULL
);
4178 if (!torture_close_connection(cli
)) {
4182 printf("browse test finished\n");
4188 static bool check_attributes(struct cli_state
*cli
,
4190 uint32_t expected_attrs
)
4193 NTSTATUS status
= cli_getatr(cli
,
4198 if (!NT_STATUS_IS_OK(status
)) {
4199 printf("cli_getatr failed with %s\n",
4203 if (attrs
!= expected_attrs
) {
4204 printf("Attributes incorrect 0x%x, should be 0x%x\n",
4205 (unsigned int)attrs
,
4206 (unsigned int)expected_attrs
);
4213 This checks how the getatr calls works
4215 static bool run_attrtest(int dummy
)
4217 struct cli_state
*cli
;
4220 const char *fname
= "\\attrib123456789.tst";
4221 bool correct
= True
;
4224 printf("starting attrib test\n");
4226 if (!torture_open_connection(&cli
, 0)) {
4230 /* Ensure we can't unlink with out-of-range (unknown) attribute. */
4231 status
= cli_unlink(cli
, fname
, 0x20000);
4232 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4237 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4238 cli_openx(cli
, fname
,
4239 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
4240 cli_close(cli
, fnum
);
4242 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4243 if (!NT_STATUS_IS_OK(status
)) {
4244 printf("getatr failed (%s)\n", nt_errstr(status
));
4248 if (labs(t
- time(NULL
)) > 60*60*24*10) {
4249 printf("ERROR: SMBgetatr bug. time is %s",
4255 t2
= t
-60*60*24; /* 1 day ago */
4257 /* Ensure we can't set with out-of-range (unknown) attribute. */
4258 status
= cli_setatr(cli
, fname
, 0x20000, t2
);
4259 if (!NT_STATUS_EQUAL(status
, NT_STATUS_INVALID_PARAMETER
)) {
4264 status
= cli_setatr(cli
, fname
, 0, t2
);
4265 if (!NT_STATUS_IS_OK(status
)) {
4266 printf("setatr failed (%s)\n", nt_errstr(status
));
4270 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4271 if (!NT_STATUS_IS_OK(status
)) {
4272 printf("getatr failed (%s)\n", nt_errstr(status
));
4277 printf("ERROR: getatr/setatr bug. times are\n%s",
4279 printf("%s", ctime(&t2
));
4283 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4285 /* Check cli_setpathinfo_ext() */
4286 /* Re-create the file. */
4287 status
= cli_openx(cli
, fname
,
4288 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
4289 if (!NT_STATUS_IS_OK(status
)) {
4290 printf("Failed to recreate %s (%s)\n",
4291 fname
, nt_errstr(status
));
4294 cli_close(cli
, fnum
);
4296 status
= cli_setpathinfo_ext(
4299 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* create */
4300 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* access */
4301 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* write */
4302 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* change */
4303 FILE_ATTRIBUTE_SYSTEM
|
4304 FILE_ATTRIBUTE_HIDDEN
|
4305 FILE_ATTRIBUTE_READONLY
);
4306 if (!NT_STATUS_IS_OK(status
)) {
4307 printf("cli_setpathinfo_ext failed with %s\n",
4312 /* Check attributes are correct. */
4313 correct
= check_attributes(cli
,
4315 FILE_ATTRIBUTE_SYSTEM
|
4316 FILE_ATTRIBUTE_HIDDEN
|
4317 FILE_ATTRIBUTE_READONLY
);
4318 if (correct
== false) {
4322 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
4323 status
= cli_setpathinfo_ext(
4326 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* create */
4327 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* access */
4328 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* write */
4329 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* change */
4330 FILE_ATTRIBUTE_NORMAL
);
4331 if (!NT_STATUS_IS_OK(status
)) {
4332 printf("cli_setpathinfo_ext failed with %s\n",
4337 /* Check attributes are correct. */
4338 correct
= check_attributes(cli
,
4340 FILE_ATTRIBUTE_SYSTEM
|
4341 FILE_ATTRIBUTE_HIDDEN
|
4342 FILE_ATTRIBUTE_READONLY
);
4343 if (correct
== false) {
4347 /* Setting to (uint16_t)-1 should also be ignored. */
4348 status
= cli_setpathinfo_ext(
4351 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* create */
4352 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* access */
4353 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* write */
4354 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* change */
4356 if (!NT_STATUS_IS_OK(status
)) {
4357 printf("cli_setpathinfo_ext failed with %s\n",
4362 /* Check attributes are correct. */
4363 correct
= check_attributes(cli
,
4365 FILE_ATTRIBUTE_SYSTEM
|
4366 FILE_ATTRIBUTE_HIDDEN
|
4367 FILE_ATTRIBUTE_READONLY
);
4368 if (correct
== false) {
4372 /* Setting to 0 should clear them all. */
4373 status
= cli_setpathinfo_ext(
4376 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* create */
4377 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* access */
4378 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* write */
4379 (struct timespec
) { .tv_nsec
= SAMBA_UTIME_OMIT
}, /* change */
4381 if (!NT_STATUS_IS_OK(status
)) {
4382 printf("cli_setpathinfo_ext failed with %s\n",
4387 /* Check attributes are correct. */
4388 correct
= check_attributes(cli
,
4390 FILE_ATTRIBUTE_NORMAL
);
4391 if (correct
== false) {
4399 FILE_ATTRIBUTE_SYSTEM
|
4400 FILE_ATTRIBUTE_HIDDEN
|
4401 FILE_ATTRIBUTE_READONLY
);
4403 if (!torture_close_connection(cli
)) {
4407 printf("attrib test finished\n");
4412 static NTSTATUS
cli_qfilename(
4413 struct cli_state
*cli
,
4415 TALLOC_CTX
*mem_ctx
,
4418 uint16_t recv_flags2
;
4425 status
= cli_qfileinfo(talloc_tos(),
4428 FSCC_FILE_NAME_INFORMATION
,
4434 if (!NT_STATUS_IS_OK(status
)) {
4438 namelen
= IVAL(rdata
, 0);
4439 if (namelen
> (num_rdata
- 4)) {
4441 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
4444 pull_string_talloc(mem_ctx
,
4445 (const char *)rdata
,
4452 status
= map_nt_error_from_unix(errno
);
4459 return NT_STATUS_OK
;
4463 This checks a couple of trans2 calls
4465 static bool run_trans2test(int dummy
)
4467 struct cli_state
*cli
;
4470 time_t c_time
, a_time
, m_time
;
4471 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
4472 const char *fname
= "\\trans2.tst";
4473 const char *dname
= "\\trans2";
4474 const char *fname2
= "\\trans2\\trans2.tst";
4476 bool correct
= True
;
4481 printf("starting trans2 test\n");
4483 if (!torture_open_connection(&cli
, 0)) {
4487 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
4488 /* Ensure ino is zero, SMB2 gets a real one. */
4491 /* Ensure ino is -1, SMB1 never gets a real one. */
4495 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
4496 if (!NT_STATUS_IS_OK(status
)) {
4497 printf("ERROR: cli_get_fs_attr_info returned %s\n",
4502 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4503 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
4504 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
4505 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
4506 if (!NT_STATUS_IS_OK(status
)) {
4507 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
4511 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
4512 if (!NT_STATUS_IS_OK(status
)) {
4513 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
4516 else if (strcmp(pname
, fname
)) {
4517 printf("qfilename gave different name? [%s] [%s]\n",
4522 cli_close(cli
, fnum
);
4526 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4527 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
4529 if (!NT_STATUS_IS_OK(status
)) {
4530 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4533 cli_close(cli
, fnum
);
4535 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
4537 if (!NT_STATUS_IS_OK(status
)) {
4538 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
4541 time_t t
= time(NULL
);
4543 if (c_time
!= m_time
) {
4544 printf("create time=%s", ctime(&c_time
));
4545 printf("modify time=%s", ctime(&m_time
));
4546 printf("This system appears to have sticky create times\n");
4548 if ((labs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
4549 printf("access time=%s", ctime(&a_time
));
4550 printf("This system appears to set a midnight access time\n");
4554 if (labs(m_time
- t
) > 60*60*24*7) {
4555 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
4561 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4562 cli_openx(cli
, fname
,
4563 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
4564 cli_close(cli
, fnum
);
4565 status
= cli_qpathinfo2(cli
,
4575 if (!NT_STATUS_IS_OK(status
)) {
4576 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
4579 if (w_time_ts
.tv_sec
< 60*60*24*2) {
4580 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
4581 printf("This system appears to set a initial 0 write time\n");
4584 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
4585 /* SMB2 should always return an inode. */
4587 printf("SMB2 bad inode (0)\n");
4591 /* SMB1 must always return zero here. */
4593 printf("SMB1 bad inode (!0)\n");
4599 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4602 /* check if the server updates the directory modification time
4603 when creating a new file */
4604 status
= cli_mkdir(cli
, dname
);
4605 if (!NT_STATUS_IS_OK(status
)) {
4606 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
4610 status
= cli_qpathinfo2(cli
,
4620 if (!NT_STATUS_IS_OK(status
)) {
4621 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
4625 cli_openx(cli
, fname2
,
4626 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
4627 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
4628 cli_close(cli
, fnum
);
4629 status
= cli_qpathinfo2(cli
,
4639 if (!NT_STATUS_IS_OK(status
)) {
4640 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
4643 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
4645 printf("This system does not update directory modification times\n");
4649 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4650 cli_rmdir(cli
, dname
);
4652 if (!torture_close_connection(cli
)) {
4656 printf("trans2 test finished\n");
4662 This checks new W2K calls.
4665 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
4667 uint8_t *buf
= NULL
;
4671 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
4672 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
4673 if (!NT_STATUS_IS_OK(status
)) {
4674 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
4677 printf("qfileinfo: level %d, len = %u\n", level
, len
);
4678 dump_data(0, (uint8_t *)buf
, len
);
4685 static bool run_w2ktest(int dummy
)
4687 struct cli_state
*cli
;
4689 const char *fname
= "\\w2ktest\\w2k.tst";
4691 bool correct
= True
;
4693 printf("starting w2k test\n");
4695 if (!torture_open_connection(&cli
, 0)) {
4699 cli_openx(cli
, fname
,
4700 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
4702 for (level
= 1004; level
< 1040; level
++) {
4703 new_trans(cli
, fnum
, level
);
4706 cli_close(cli
, fnum
);
4708 if (!torture_close_connection(cli
)) {
4712 printf("w2k test finished\n");
4719 this is a harness for some oplock tests
4721 static bool run_oplock1(int dummy
)
4723 struct cli_state
*cli1
;
4724 const char *fname
= "\\lockt1.lck";
4726 bool correct
= True
;
4729 printf("starting oplock test 1\n");
4731 if (!torture_open_connection(&cli1
, 0)) {
4735 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4737 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4739 cli1
->use_oplocks
= True
;
4741 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
4743 if (!NT_STATUS_IS_OK(status
)) {
4744 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4748 cli1
->use_oplocks
= False
;
4750 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4751 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4753 status
= cli_close(cli1
, fnum1
);
4754 if (!NT_STATUS_IS_OK(status
)) {
4755 printf("close2 failed (%s)\n", nt_errstr(status
));
4759 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4760 if (!NT_STATUS_IS_OK(status
)) {
4761 printf("unlink failed (%s)\n", nt_errstr(status
));
4765 if (!torture_close_connection(cli1
)) {
4769 printf("finished oplock test 1\n");
4774 static bool run_oplock2(int dummy
)
4776 struct cli_state
*cli1
, *cli2
;
4777 const char *fname
= "\\lockt2.lck";
4778 uint16_t fnum1
, fnum2
;
4779 int saved_use_oplocks
= use_oplocks
;
4781 bool correct
= True
;
4782 volatile bool *shared_correct
;
4786 shared_correct
= (volatile bool *)anonymous_shared_allocate(sizeof(bool));
4787 *shared_correct
= True
;
4789 use_level_II_oplocks
= True
;
4792 printf("starting oplock test 2\n");
4794 if (!torture_open_connection(&cli1
, 0)) {
4795 use_level_II_oplocks
= False
;
4796 use_oplocks
= saved_use_oplocks
;
4800 if (!torture_open_connection(&cli2
, 1)) {
4801 use_level_II_oplocks
= False
;
4802 use_oplocks
= saved_use_oplocks
;
4806 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4808 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4809 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
4811 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
4813 if (!NT_STATUS_IS_OK(status
)) {
4814 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4818 /* Don't need the globals any more. */
4819 use_level_II_oplocks
= False
;
4820 use_oplocks
= saved_use_oplocks
;
4824 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
4825 if (!NT_STATUS_IS_OK(status
)) {
4826 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
4827 *shared_correct
= False
;
4833 status
= cli_close(cli2
, fnum2
);
4834 if (!NT_STATUS_IS_OK(status
)) {
4835 printf("close2 failed (%s)\n", nt_errstr(status
));
4836 *shared_correct
= False
;
4844 /* Ensure cli1 processes the break. Empty file should always return 0
4846 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
4847 if (!NT_STATUS_IS_OK(status
)) {
4848 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
4850 } else if (nread
!= 0) {
4851 printf("read on empty fnum1 failed. recv %ld expected %d\n",
4852 (unsigned long)nread
, 0);
4856 /* Should now be at level II. */
4857 /* Test if sending a write locks causes a break to none. */
4858 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
4859 if (!NT_STATUS_IS_OK(status
)) {
4860 printf("lock failed (%s)\n", nt_errstr(status
));
4864 cli_unlock(cli1
, fnum1
, 0, 4);
4868 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
4869 if (!NT_STATUS_IS_OK(status
)) {
4870 printf("lock failed (%s)\n", nt_errstr(status
));
4874 cli_unlock(cli1
, fnum1
, 0, 4);
4878 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
4880 status
= cli_close(cli1
, fnum1
);
4881 if (!NT_STATUS_IS_OK(status
)) {
4882 printf("close1 failed (%s)\n", nt_errstr(status
));
4888 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4889 if (!NT_STATUS_IS_OK(status
)) {
4890 printf("unlink failed (%s)\n", nt_errstr(status
));
4894 if (!torture_close_connection(cli1
)) {
4898 if (!*shared_correct
) {
4902 printf("finished oplock test 2\n");
4907 struct oplock4_state
{
4908 struct tevent_context
*ev
;
4909 struct cli_state
*cli
;
4914 static void oplock4_got_break(struct tevent_req
*req
);
4915 static void oplock4_got_open(struct tevent_req
*req
);
4917 static bool run_oplock4(int dummy
)
4919 struct tevent_context
*ev
;
4920 struct cli_state
*cli1
, *cli2
;
4921 struct tevent_req
*oplock_req
, *open_req
;
4922 const char *fname
= "\\lockt4.lck";
4923 const char *fname_ln
= "\\lockt4_ln.lck";
4924 uint16_t fnum1
, fnum2
;
4925 int saved_use_oplocks
= use_oplocks
;
4927 bool correct
= true;
4931 struct oplock4_state
*state
;
4933 printf("starting oplock test 4\n");
4935 if (!torture_open_connection(&cli1
, 0)) {
4936 use_level_II_oplocks
= false;
4937 use_oplocks
= saved_use_oplocks
;
4941 if (!torture_open_connection(&cli2
, 1)) {
4942 use_level_II_oplocks
= false;
4943 use_oplocks
= saved_use_oplocks
;
4947 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4948 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4950 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4951 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
4953 /* Create the file. */
4954 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
4956 if (!NT_STATUS_IS_OK(status
)) {
4957 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4961 status
= cli_close(cli1
, fnum1
);
4962 if (!NT_STATUS_IS_OK(status
)) {
4963 printf("close1 failed (%s)\n", nt_errstr(status
));
4967 /* Now create a hardlink. */
4968 status
= cli_hardlink(cli1
, fname
, fname_ln
);
4969 if (!NT_STATUS_IS_OK(status
)) {
4970 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4974 /* Prove that opening hardlinks cause deny modes to conflict. */
4975 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
4976 if (!NT_STATUS_IS_OK(status
)) {
4977 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4981 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
4982 if (NT_STATUS_IS_OK(status
)) {
4983 printf("open of %s succeeded - should fail with sharing violation.\n",
4988 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
4989 printf("open of %s should fail with sharing violation. Got %s\n",
4990 fname_ln
, nt_errstr(status
));
4994 status
= cli_close(cli1
, fnum1
);
4995 if (!NT_STATUS_IS_OK(status
)) {
4996 printf("close1 failed (%s)\n", nt_errstr(status
));
5000 cli1
->use_oplocks
= true;
5001 cli2
->use_oplocks
= true;
5003 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
5004 if (!NT_STATUS_IS_OK(status
)) {
5005 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5009 ev
= samba_tevent_context_init(talloc_tos());
5011 printf("tevent_context_init failed\n");
5015 state
= talloc(ev
, struct oplock4_state
);
5016 if (state
== NULL
) {
5017 printf("talloc failed\n");
5022 state
->got_break
= &got_break
;
5023 state
->fnum2
= &fnum2
;
5025 oplock_req
= cli_smb_oplock_break_waiter_send(
5026 talloc_tos(), ev
, cli1
);
5027 if (oplock_req
== NULL
) {
5028 printf("cli_smb_oplock_break_waiter_send failed\n");
5031 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
5033 open_req
= cli_openx_send(
5034 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
5035 if (open_req
== NULL
) {
5036 printf("cli_openx_send failed\n");
5039 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
5044 while (!got_break
|| fnum2
== 0xffff) {
5046 ret
= tevent_loop_once(ev
);
5048 printf("tevent_loop_once failed: %s\n",
5054 status
= cli_close(cli2
, fnum2
);
5055 if (!NT_STATUS_IS_OK(status
)) {
5056 printf("close2 failed (%s)\n", nt_errstr(status
));
5060 status
= cli_close(cli1
, fnum1
);
5061 if (!NT_STATUS_IS_OK(status
)) {
5062 printf("close1 failed (%s)\n", nt_errstr(status
));
5066 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5067 if (!NT_STATUS_IS_OK(status
)) {
5068 printf("unlink failed (%s)\n", nt_errstr(status
));
5072 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5073 if (!NT_STATUS_IS_OK(status
)) {
5074 printf("unlink failed (%s)\n", nt_errstr(status
));
5078 if (!torture_close_connection(cli1
)) {
5086 printf("finished oplock test 4\n");
5091 static void oplock4_got_break(struct tevent_req
*req
)
5093 struct oplock4_state
*state
= tevent_req_callback_data(
5094 req
, struct oplock4_state
);
5099 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
5101 if (!NT_STATUS_IS_OK(status
)) {
5102 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
5106 *state
->got_break
= true;
5108 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
5111 printf("cli_oplock_ack_send failed\n");
5116 static void oplock4_got_open(struct tevent_req
*req
)
5118 struct oplock4_state
*state
= tevent_req_callback_data(
5119 req
, struct oplock4_state
);
5122 status
= cli_openx_recv(req
, state
->fnum2
);
5123 if (!NT_STATUS_IS_OK(status
)) {
5124 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
5125 *state
->fnum2
= 0xffff;
5129 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
5131 struct oplock5_state
{
5136 * Async open the file that has a kernel oplock, do an echo to get
5137 * that 100% across, close the file to signal to the child fd that the
5138 * oplock can be dropped, wait for the open reply.
5141 static void oplock5_opened(struct tevent_req
*subreq
);
5142 static void oplock5_pong(struct tevent_req
*subreq
);
5143 static void oplock5_timedout(struct tevent_req
*subreq
);
5145 static struct tevent_req
*oplock5_send(
5146 TALLOC_CTX
*mem_ctx
,
5147 struct tevent_context
*ev
,
5148 struct cli_state
*cli
,
5152 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
5153 struct oplock5_state
*state
= NULL
;
5154 static uint8_t data
= 0;
5156 req
= tevent_req_create(mem_ctx
, &state
, struct oplock5_state
);
5160 state
->pipe_down_fd
= pipe_down_fd
;
5162 subreq
= cli_ntcreate_send(
5168 SEC_FILE_READ_DATA
, /* DesiredAccess */
5169 FILE_ATTRIBUTE_NORMAL
, /* FileAttributes */
5170 FILE_SHARE_WRITE
|FILE_SHARE_READ
, /* ShareAccess */
5171 FILE_OPEN
, /* CreateDisposition */
5172 FILE_NON_DIRECTORY_FILE
, /* CreateOptions */
5173 0, /* Impersonation */
5174 0); /* SecurityFlags */
5175 if (tevent_req_nomem(subreq
, req
)) {
5176 return tevent_req_post(req
, ev
);
5178 tevent_req_set_callback(subreq
, oplock5_opened
, req
);
5180 subreq
= cli_echo_send(
5185 (DATA_BLOB
) { .data
= &data
, .length
= sizeof(data
) });
5186 if (tevent_req_nomem(subreq
, req
)) {
5187 return tevent_req_post(req
, ev
);
5189 tevent_req_set_callback(subreq
, oplock5_pong
, req
);
5191 subreq
= tevent_wakeup_send(state
, ev
, timeval_current_ofs(20, 0));
5192 if (tevent_req_nomem(subreq
, req
)) {
5193 return tevent_req_post(req
, ev
);
5195 tevent_req_set_callback(subreq
, oplock5_timedout
, req
);
5200 static void oplock5_opened(struct tevent_req
*subreq
)
5202 struct tevent_req
*req
= tevent_req_callback_data(
5203 subreq
, struct tevent_req
);
5207 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
5208 TALLOC_FREE(subreq
);
5209 if (tevent_req_nterror(req
, status
)) {
5212 tevent_req_done(req
);
5215 static void oplock5_pong(struct tevent_req
*subreq
)
5217 struct tevent_req
*req
= tevent_req_callback_data(
5218 subreq
, struct tevent_req
);
5219 struct oplock5_state
*state
= tevent_req_data(
5220 req
, struct oplock5_state
);
5223 status
= cli_echo_recv(subreq
);
5224 TALLOC_FREE(subreq
);
5225 if (tevent_req_nterror(req
, status
)) {
5229 close(state
->pipe_down_fd
);
5232 static void oplock5_timedout(struct tevent_req
*subreq
)
5234 struct tevent_req
*req
= tevent_req_callback_data(
5235 subreq
, struct tevent_req
);
5238 ok
= tevent_wakeup_recv(subreq
);
5239 TALLOC_FREE(subreq
);
5241 tevent_req_oom(req
);
5244 tevent_req_nterror(req
, NT_STATUS_TIMEOUT
);
5247 static NTSTATUS
oplock5_recv(struct tevent_req
*req
)
5249 return tevent_req_simple_recv_ntstatus(req
);
5252 static bool run_oplock5(int dummy
)
5254 struct tevent_context
*ev
= NULL
;
5255 struct tevent_req
*req
= NULL
;
5256 struct cli_state
*cli
= NULL
;
5257 const char *fname
= "oplock5.txt";
5258 int pipe_down
[2], pipe_up
[2];
5265 printf("starting oplock5\n");
5267 if (local_path
== NULL
) {
5268 d_fprintf(stderr
, "oplock5 must be given a local path via "
5269 "-l <localpath>\n");
5273 ret
= pipe(pipe_down
);
5275 d_fprintf(stderr
, "pipe() failed: %s\n", strerror(errno
));
5278 ret
= pipe(pipe_up
);
5280 d_fprintf(stderr
, "pipe() failed: %s\n", strerror(errno
));
5285 if (child_pid
== -1) {
5286 d_fprintf(stderr
, "fork() failed: %s\n", strerror(errno
));
5290 if (child_pid
== 0) {
5291 char *local_file
= NULL
;
5294 close(pipe_down
[1]);
5297 local_file
= talloc_asprintf(
5298 talloc_tos(), "%s/%s", local_path
, fname
);
5299 if (local_file
== 0) {
5303 fd
= open(local_file
, O_RDWR
|O_CREAT
, 0644);
5306 "open(%s) in child failed: %s\n",
5313 signal(SIGIO
, SIG_IGN
);
5315 ret
= fcntl(fd
, F_SETLEASE
, F_WRLCK
);
5318 "SETLEASE in child failed: %s\n",
5325 ret
= sys_write(pipe_up
[1], &c
, sizeof(c
));
5328 "sys_write failed: %s\n",
5332 ret
= sys_read(pipe_down
[0], &c
, sizeof(c
));
5335 "sys_read failed: %s\n",
5343 close(pipe_down
[0]);
5345 ret
= sys_read(pipe_up
[0], &c
, sizeof(c
));
5348 "sys_read failed: %s\n",
5353 d_fprintf(stderr
, "got error code %"PRIu8
"\n", c
);
5357 ok
= torture_open_connection(&cli
, 0);
5359 d_fprintf(stderr
, "torture_open_connection failed\n");
5363 ev
= samba_tevent_context_init(talloc_tos());
5365 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
5369 req
= oplock5_send(ev
, ev
, cli
, fname
, pipe_down
[1]);
5371 d_fprintf(stderr
, "oplock5_send failed\n");
5375 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
5378 "tevent_req_poll_ntstatus failed: %s\n",
5383 status
= oplock5_recv(req
);
5385 if (!NT_STATUS_IS_OK(status
)) {
5387 "oplock5 failed: %s\n",
5395 #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
5398 Test delete on close semantics.
5400 static bool run_deletetest(int dummy
)
5402 struct cli_state
*cli1
= NULL
;
5403 struct cli_state
*cli2
= NULL
;
5404 const char *fname
= "\\delete.file";
5405 uint16_t fnum1
= (uint16_t)-1;
5406 uint16_t fnum2
= (uint16_t)-1;
5407 bool correct
= false;
5410 printf("starting delete test\n");
5412 if (!torture_open_connection(&cli1
, 0)) {
5416 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5418 /* Test 1 - this should delete the file on close. */
5420 cli_setatr(cli1
, fname
, 0, 0);
5421 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5423 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5424 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5425 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
5426 if (!NT_STATUS_IS_OK(status
)) {
5427 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5431 status
= cli_close(cli1
, fnum1
);
5432 if (!NT_STATUS_IS_OK(status
)) {
5433 printf("[1] close failed (%s)\n", nt_errstr(status
));
5437 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
5438 if (NT_STATUS_IS_OK(status
)) {
5439 printf("[1] open of %s succeeded (should fail)\n", fname
);
5443 printf("first delete on close test succeeded.\n");
5445 /* Test 2 - this should delete the file on close. */
5447 cli_setatr(cli1
, fname
, 0, 0);
5448 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5450 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
5451 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5452 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5453 if (!NT_STATUS_IS_OK(status
)) {
5454 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5458 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5459 if (!NT_STATUS_IS_OK(status
)) {
5460 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
5464 status
= cli_close(cli1
, fnum1
);
5465 if (!NT_STATUS_IS_OK(status
)) {
5466 printf("[2] close failed (%s)\n", nt_errstr(status
));
5470 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
5471 if (NT_STATUS_IS_OK(status
)) {
5472 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
5473 status
= cli_close(cli1
, fnum1
);
5474 if (!NT_STATUS_IS_OK(status
)) {
5475 printf("[2] close failed (%s)\n", nt_errstr(status
));
5477 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5481 printf("second delete on close test succeeded.\n");
5484 cli_setatr(cli1
, fname
, 0, 0);
5485 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5487 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
5488 FILE_ATTRIBUTE_NORMAL
,
5489 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5490 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5491 if (!NT_STATUS_IS_OK(status
)) {
5492 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5496 /* This should fail with a sharing violation - open for delete is only compatible
5497 with SHARE_DELETE. */
5499 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5500 FILE_ATTRIBUTE_NORMAL
,
5501 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5502 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5503 if (NT_STATUS_IS_OK(status
)) {
5504 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
5508 /* This should succeed. */
5509 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5510 FILE_ATTRIBUTE_NORMAL
,
5511 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5512 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5513 if (!NT_STATUS_IS_OK(status
)) {
5514 printf("[3] open - 3 of %s failed (%s)\n", fname
, nt_errstr(status
));
5518 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5519 if (!NT_STATUS_IS_OK(status
)) {
5520 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
5524 status
= cli_close(cli1
, fnum1
);
5525 if (!NT_STATUS_IS_OK(status
)) {
5526 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
5530 status
= cli_close(cli1
, fnum2
);
5531 if (!NT_STATUS_IS_OK(status
)) {
5532 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
5536 /* This should fail - file should no longer be there. */
5538 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
5539 if (NT_STATUS_IS_OK(status
)) {
5540 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
5541 status
= cli_close(cli1
, fnum1
);
5542 if (!NT_STATUS_IS_OK(status
)) {
5543 printf("[3] close failed (%s)\n", nt_errstr(status
));
5545 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5549 printf("third delete on close test succeeded.\n");
5552 cli_setatr(cli1
, fname
, 0, 0);
5553 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5555 status
= cli_ntcreate(cli1
, fname
, 0,
5556 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5557 FILE_ATTRIBUTE_NORMAL
,
5558 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5559 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5560 if (!NT_STATUS_IS_OK(status
)) {
5561 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5565 /* This should succeed. */
5566 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5567 FILE_ATTRIBUTE_NORMAL
,
5568 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5569 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5570 if (!NT_STATUS_IS_OK(status
)) {
5571 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5575 status
= cli_close(cli1
, fnum2
);
5576 if (!NT_STATUS_IS_OK(status
)) {
5577 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
5581 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5582 if (!NT_STATUS_IS_OK(status
)) {
5583 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
5587 /* This should fail - no more opens once delete on close set. */
5588 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5589 FILE_ATTRIBUTE_NORMAL
,
5590 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5591 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5592 if (NT_STATUS_IS_OK(status
)) {
5593 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
5597 status
= cli_close(cli1
, fnum1
);
5598 if (!NT_STATUS_IS_OK(status
)) {
5599 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
5603 printf("fourth delete on close test succeeded.\n");
5606 cli_setatr(cli1
, fname
, 0, 0);
5607 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5609 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
5610 if (!NT_STATUS_IS_OK(status
)) {
5611 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5615 /* This should fail - only allowed on NT opens with DELETE access. */
5617 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5618 if (NT_STATUS_IS_OK(status
)) {
5619 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
5623 status
= cli_close(cli1
, fnum1
);
5624 if (!NT_STATUS_IS_OK(status
)) {
5625 printf("[5] close failed (%s)\n", nt_errstr(status
));
5629 printf("fifth delete on close test succeeded.\n");
5632 cli_setatr(cli1
, fname
, 0, 0);
5633 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5635 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
5636 FILE_ATTRIBUTE_NORMAL
,
5637 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5638 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5639 if (!NT_STATUS_IS_OK(status
)) {
5640 printf("[6] open of %s failed (%s)\n", fname
,
5645 /* This should fail - only allowed on NT opens with DELETE access. */
5647 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5648 if (NT_STATUS_IS_OK(status
)) {
5649 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
5653 status
= cli_close(cli1
, fnum1
);
5654 if (!NT_STATUS_IS_OK(status
)) {
5655 printf("[6] close failed (%s)\n", nt_errstr(status
));
5659 printf("sixth delete on close test succeeded.\n");
5662 cli_setatr(cli1
, fname
, 0, 0);
5663 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5665 status
= cli_ntcreate(cli1
, fname
, 0,
5666 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5667 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5668 0, 0, &fnum1
, NULL
);
5669 if (!NT_STATUS_IS_OK(status
)) {
5670 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5674 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5675 if (!NT_STATUS_IS_OK(status
)) {
5676 printf("[7] setting delete_on_close on file failed !\n");
5680 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
5681 if (!NT_STATUS_IS_OK(status
)) {
5682 printf("[7] unsetting delete_on_close on file failed !\n");
5686 status
= cli_close(cli1
, fnum1
);
5687 if (!NT_STATUS_IS_OK(status
)) {
5688 printf("[7] close - 1 failed (%s)\n", nt_errstr(status
));
5692 /* This next open should succeed - we reset the flag. */
5693 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
5694 if (!NT_STATUS_IS_OK(status
)) {
5695 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5699 status
= cli_close(cli1
, fnum1
);
5700 if (!NT_STATUS_IS_OK(status
)) {
5701 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
5705 printf("seventh delete on close test succeeded.\n");
5708 cli_setatr(cli1
, fname
, 0, 0);
5709 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5711 if (!torture_open_connection(&cli2
, 1)) {
5712 printf("[8] failed to open second connection.\n");
5716 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5718 status
= cli_ntcreate(cli1
, fname
, 0,
5719 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5720 FILE_ATTRIBUTE_NORMAL
,
5721 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5722 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5723 if (!NT_STATUS_IS_OK(status
)) {
5724 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5728 status
= cli_ntcreate(cli2
, fname
, 0,
5729 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5730 FILE_ATTRIBUTE_NORMAL
,
5731 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5732 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5733 if (!NT_STATUS_IS_OK(status
)) {
5734 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5738 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5739 if (!NT_STATUS_IS_OK(status
)) {
5740 printf("[8] setting delete_on_close on file failed !\n");
5744 status
= cli_close(cli1
, fnum1
);
5745 if (!NT_STATUS_IS_OK(status
)) {
5746 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
5750 status
= cli_close(cli2
, fnum2
);
5751 if (!NT_STATUS_IS_OK(status
)) {
5752 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
5756 /* This should fail.. */
5757 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
5758 if (NT_STATUS_IS_OK(status
)) {
5759 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
5763 printf("eighth delete on close test succeeded.\n");
5767 /* This should fail - we need to set DELETE_ACCESS. */
5768 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
5769 FILE_ATTRIBUTE_NORMAL
,
5772 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
5773 if (NT_STATUS_IS_OK(status
)) {
5774 printf("[9] open of %s succeeded should have failed!\n", fname
);
5778 printf("ninth delete on close test succeeded.\n");
5782 status
= cli_ntcreate(cli1
, fname
, 0,
5783 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5784 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5785 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
5787 if (!NT_STATUS_IS_OK(status
)) {
5788 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5792 /* This should delete the file. */
5793 status
= cli_close(cli1
, fnum1
);
5794 if (!NT_STATUS_IS_OK(status
)) {
5795 printf("[10] close failed (%s)\n", nt_errstr(status
));
5799 /* This should fail.. */
5800 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
5801 if (NT_STATUS_IS_OK(status
)) {
5802 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
5806 printf("tenth delete on close test succeeded.\n");
5810 cli_setatr(cli1
, fname
, 0, 0);
5811 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5813 /* Can we open a read-only file with delete access? */
5815 /* Create a readonly file. */
5816 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
5817 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
5818 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5819 if (!NT_STATUS_IS_OK(status
)) {
5820 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
5824 status
= cli_close(cli1
, fnum1
);
5825 if (!NT_STATUS_IS_OK(status
)) {
5826 printf("[11] close failed (%s)\n", nt_errstr(status
));
5830 /* Now try open for delete access. */
5831 status
= cli_ntcreate(cli1
, fname
, 0,
5832 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
5834 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5835 FILE_OPEN
, 0, 0, &fnum1
, NULL
);
5836 if (!NT_STATUS_IS_OK(status
)) {
5837 printf("[11] open of %s failed: %s\n", fname
, nt_errstr(status
));
5841 cli_close(cli1
, fnum1
);
5843 printf("eleventh delete on close test succeeded.\n");
5847 * like test 4 but with initial delete on close
5850 cli_setatr(cli1
, fname
, 0, 0);
5851 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5853 status
= cli_ntcreate(cli1
, fname
, 0,
5854 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5855 FILE_ATTRIBUTE_NORMAL
,
5856 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
5858 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
5859 if (!NT_STATUS_IS_OK(status
)) {
5860 printf("[12] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5864 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5865 FILE_ATTRIBUTE_NORMAL
,
5866 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5867 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5868 if (!NT_STATUS_IS_OK(status
)) {
5869 printf("[12] open 2 of %s failed(%s).\n", fname
, nt_errstr(status
));
5873 status
= cli_close(cli1
, fnum2
);
5874 if (!NT_STATUS_IS_OK(status
)) {
5875 printf("[12] close 1 failed (%s)\n", nt_errstr(status
));
5879 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
5880 if (!NT_STATUS_IS_OK(status
)) {
5881 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status
));
5885 /* This should fail - no more opens once delete on close set. */
5886 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5887 FILE_ATTRIBUTE_NORMAL
,
5888 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5889 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5890 if (NT_STATUS_IS_OK(status
)) {
5891 printf("[12] open 3 of %s succeeded - should fail).\n", fname
);
5895 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
5896 if (!NT_STATUS_IS_OK(status
)) {
5897 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status
));
5901 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5902 FILE_ATTRIBUTE_NORMAL
,
5903 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5904 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5905 if (!NT_STATUS_IS_OK(status
)) {
5906 printf("[12] open 4 of %s failed (%s)\n", fname
, nt_errstr(status
));
5910 status
= cli_close(cli1
, fnum2
);
5911 if (!NT_STATUS_IS_OK(status
)) {
5912 printf("[12] close 2 failed (%s)\n", nt_errstr(status
));
5916 status
= cli_close(cli1
, fnum1
);
5917 if (!NT_STATUS_IS_OK(status
)) {
5918 printf("[12] close 3 failed (%s)\n", nt_errstr(status
));
5923 * setting delete on close on the handle does
5924 * not unset the initial delete on close...
5926 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
5927 FILE_ATTRIBUTE_NORMAL
,
5928 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5929 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
5930 if (NT_STATUS_IS_OK(status
)) {
5931 printf("[12] open 5 of %s succeeded - should fail).\n", fname
);
5933 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
5934 printf("ntcreate returned %s, expected "
5935 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5940 printf("twelfth delete on close test succeeded.\n");
5943 printf("finished delete test\n");
5948 /* FIXME: This will crash if we aborted before cli2 got
5949 * initialized, because these functions don't handle
5950 * uninitialized connections. */
5952 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
5953 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
5954 cli_setatr(cli1
, fname
, 0, 0);
5955 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5957 if (cli1
&& !torture_close_connection(cli1
)) {
5960 if (cli2
&& !torture_close_connection(cli2
)) {
5966 struct delete_stream_state
{
5970 static void delete_stream_unlinked(struct tevent_req
*subreq
);
5971 static void delete_stream_closed(struct tevent_req
*subreq
);
5973 static struct tevent_req
*delete_stream_send(
5974 TALLOC_CTX
*mem_ctx
,
5975 struct tevent_context
*ev
,
5976 struct cli_state
*cli
,
5977 const char *base_fname
,
5978 uint16_t stream_fnum
)
5980 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
5981 struct delete_stream_state
*state
= NULL
;
5983 req
= tevent_req_create(
5984 mem_ctx
, &state
, struct delete_stream_state
);
5989 subreq
= cli_unlink_send(
5994 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5995 if (tevent_req_nomem(subreq
, req
)) {
5996 return tevent_req_post(req
, ev
);
5998 tevent_req_set_callback(subreq
, delete_stream_unlinked
, req
);
6000 subreq
= cli_close_send(state
, ev
, cli
, stream_fnum
, 0);
6001 if (tevent_req_nomem(subreq
, req
)) {
6002 return tevent_req_post(req
, ev
);
6004 tevent_req_set_callback(subreq
, delete_stream_closed
, req
);
6009 static void delete_stream_unlinked(struct tevent_req
*subreq
)
6011 struct tevent_req
*req
= tevent_req_callback_data(
6012 subreq
, struct tevent_req
);
6013 struct delete_stream_state
*state
= tevent_req_data(
6014 req
, struct delete_stream_state
);
6017 status
= cli_unlink_recv(subreq
);
6018 TALLOC_FREE(subreq
);
6019 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
6020 printf("cli_unlink returned %s\n",
6022 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
6025 if (!state
->closed
) {
6026 /* close reply should have come in first */
6027 printf("Not closed\n");
6028 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
6031 tevent_req_done(req
);
6034 static void delete_stream_closed(struct tevent_req
*subreq
)
6036 struct tevent_req
*req
= tevent_req_callback_data(
6037 subreq
, struct tevent_req
);
6038 struct delete_stream_state
*state
= tevent_req_data(
6039 req
, struct delete_stream_state
);
6042 status
= cli_close_recv(subreq
);
6043 TALLOC_FREE(subreq
);
6044 if (tevent_req_nterror(req
, status
)) {
6047 /* also waiting for the unlink to come back */
6048 state
->closed
= true;
6051 static NTSTATUS
delete_stream_recv(struct tevent_req
*req
)
6053 return tevent_req_simple_recv_ntstatus(req
);
6056 static bool run_delete_stream(int dummy
)
6058 struct tevent_context
*ev
= NULL
;
6059 struct tevent_req
*req
= NULL
;
6060 struct cli_state
*cli
= NULL
;
6061 const char fname
[] = "delete_stream";
6062 const char fname_stream
[] = "delete_stream:Zone.Identifier:$DATA";
6063 uint16_t fnum1
, fnum2
;
6067 printf("Starting stream delete test\n");
6069 ok
= torture_open_connection(&cli
, 0);
6074 cli_setatr(cli
, fname
, 0, 0);
6075 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6077 /* Create the file. */
6078 status
= cli_ntcreate(
6082 READ_CONTROL_ACCESS
,
6084 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6090 if (!NT_STATUS_IS_OK(status
)) {
6092 "cli_ntcreate of %s failed (%s)\n",
6097 status
= cli_close(cli
, fnum1
);
6098 if (!NT_STATUS_IS_OK(status
)) {
6100 "cli_close of %s failed (%s)\n",
6106 /* Now create the stream. */
6107 status
= cli_ntcreate(
6113 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6120 if (!NT_STATUS_IS_OK(status
)) {
6122 "cli_ntcreate of %s failed (%s)\n",
6128 /* open it a second time */
6130 status
= cli_ntcreate(
6136 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6143 if (!NT_STATUS_IS_OK(status
)) {
6145 "2nd cli_ntcreate of %s failed (%s)\n",
6151 ev
= samba_tevent_context_init(talloc_tos());
6153 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
6157 req
= delete_stream_send(ev
, ev
, cli
, fname
, fnum1
);
6159 d_fprintf(stderr
, "delete_stream_send failed\n");
6163 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
6166 "tevent_req_poll_ntstatus failed: %s\n",
6171 status
= delete_stream_recv(req
);
6173 if (!NT_STATUS_IS_OK(status
)) {
6175 "delete_stream failed: %s\n",
6180 status
= cli_close(cli
, fnum2
);
6181 if (!NT_STATUS_IS_OK(status
)) {
6183 "close failed: %s\n",
6188 status
= cli_unlink(
6189 cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6190 if (!NT_STATUS_IS_OK(status
)) {
6192 "unlink failed: %s\n",
6201 Exercise delete on close semantics - use on the PRINT1 share in torture
6204 static bool run_delete_print_test(int dummy
)
6206 struct cli_state
*cli1
= NULL
;
6207 const char *fname
= "print_delete.file";
6208 uint16_t fnum1
= (uint16_t)-1;
6209 bool correct
= false;
6210 const char *buf
= "print file data\n";
6213 printf("starting print delete test\n");
6215 if (!torture_open_connection(&cli1
, 0)) {
6219 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6221 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6222 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6223 0, 0, &fnum1
, NULL
);
6224 if (!NT_STATUS_IS_OK(status
)) {
6225 printf("open of %s failed (%s)\n",
6231 status
= cli_writeall(cli1
,
6234 (const uint8_t *)buf
,
6236 strlen(buf
), /* size */
6238 if (!NT_STATUS_IS_OK(status
)) {
6239 printf("writing print file data failed (%s)\n",
6244 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
6245 if (!NT_STATUS_IS_OK(status
)) {
6246 printf("setting delete_on_close failed (%s)\n",
6251 status
= cli_close(cli1
, fnum1
);
6252 if (!NT_STATUS_IS_OK(status
)) {
6253 printf("close failed (%s)\n", nt_errstr(status
));
6257 printf("finished print delete test\n");
6263 if (fnum1
!= (uint16_t)-1) {
6264 cli_close(cli1
, fnum1
);
6267 if (cli1
&& !torture_close_connection(cli1
)) {
6273 static bool run_deletetest_ln(int dummy
)
6275 struct cli_state
*cli
;
6276 const char *fname
= "\\delete1";
6277 const char *fname_ln
= "\\delete1_ln";
6281 bool correct
= true;
6284 printf("starting deletetest-ln\n");
6286 if (!torture_open_connection(&cli
, 0)) {
6290 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6291 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6293 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6295 /* Create the file. */
6296 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6297 if (!NT_STATUS_IS_OK(status
)) {
6298 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
6302 status
= cli_close(cli
, fnum
);
6303 if (!NT_STATUS_IS_OK(status
)) {
6304 printf("close1 failed (%s)\n", nt_errstr(status
));
6308 /* Now create a hardlink. */
6309 status
= cli_hardlink(cli
, fname
, fname_ln
);
6310 if (!NT_STATUS_IS_OK(status
)) {
6311 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
6315 /* Open the original file. */
6316 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
6317 FILE_ATTRIBUTE_NORMAL
,
6318 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6319 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
6320 if (!NT_STATUS_IS_OK(status
)) {
6321 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
6325 /* Unlink the hard link path. */
6326 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
6327 FILE_ATTRIBUTE_NORMAL
,
6328 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6329 FILE_OPEN_IF
, 0, 0, &fnum1
, NULL
);
6330 if (!NT_STATUS_IS_OK(status
)) {
6331 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
6334 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
6335 if (!NT_STATUS_IS_OK(status
)) {
6336 d_printf("(%s) failed to set delete_on_close %s: %s\n",
6337 __location__
, fname_ln
, nt_errstr(status
));
6341 status
= cli_close(cli
, fnum1
);
6342 if (!NT_STATUS_IS_OK(status
)) {
6343 printf("close %s failed (%s)\n",
6344 fname_ln
, nt_errstr(status
));
6348 status
= cli_close(cli
, fnum
);
6349 if (!NT_STATUS_IS_OK(status
)) {
6350 printf("close %s failed (%s)\n",
6351 fname
, nt_errstr(status
));
6355 /* Ensure the original file is still there. */
6356 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
6357 if (!NT_STATUS_IS_OK(status
)) {
6358 printf("%s getatr on file %s failed (%s)\n",
6365 /* Ensure the link path is gone. */
6366 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
6367 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6368 printf("%s, getatr for file %s returned wrong error code %s "
6369 "- should have been deleted\n",
6371 fname_ln
, nt_errstr(status
));
6375 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6376 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6378 if (!torture_close_connection(cli
)) {
6382 printf("finished deletetest-ln\n");
6388 print out server properties
6390 static bool run_properties(int dummy
)
6392 struct cli_state
*cli
;
6393 bool correct
= True
;
6395 printf("starting properties test\n");
6399 if (!torture_open_connection(&cli
, 0)) {
6403 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6405 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
6407 if (!torture_close_connection(cli
)) {
6416 /* FIRST_DESIRED_ACCESS 0xf019f */
6417 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
6418 FILE_READ_EA| /* 0xf */ \
6419 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
6420 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
6421 DELETE_ACCESS|READ_CONTROL_ACCESS|\
6422 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
6423 /* SECOND_DESIRED_ACCESS 0xe0080 */
6424 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
6425 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
6426 WRITE_OWNER_ACCESS /* 0xe0000 */
6429 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
6430 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
6432 WRITE_OWNER_ACCESS /* */
6436 Test ntcreate calls made by xcopy
6438 static bool run_xcopy(int dummy
)
6440 static struct cli_state
*cli1
;
6441 const char *fname
= "\\test.txt";
6442 bool correct
= True
;
6443 uint16_t fnum1
, fnum2
;
6446 printf("starting xcopy test\n");
6448 if (!torture_open_connection(&cli1
, 0)) {
6452 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
6453 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
6454 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
, NULL
);
6455 if (!NT_STATUS_IS_OK(status
)) {
6456 printf("First open failed - %s\n", nt_errstr(status
));
6460 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
6461 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6462 FILE_OPEN
, 0x200000, 0, &fnum2
, NULL
);
6463 if (!NT_STATUS_IS_OK(status
)) {
6464 printf("second open failed - %s\n", nt_errstr(status
));
6468 if (!torture_close_connection(cli1
)) {
6476 Test rename on files open with share delete and no share delete.
6478 static bool run_rename(int dummy
)
6480 static struct cli_state
*cli1
;
6481 const char *fname
= "\\test.txt";
6482 const char *fname1
= "\\test1.txt";
6483 bool correct
= True
;
6488 printf("starting rename test\n");
6490 if (!torture_open_connection(&cli1
, 0)) {
6494 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6495 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6497 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
6498 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6499 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6500 if (!NT_STATUS_IS_OK(status
)) {
6501 printf("First open failed - %s\n", nt_errstr(status
));
6505 status
= cli_rename(cli1
, fname
, fname1
, false);
6506 if (!NT_STATUS_IS_OK(status
)) {
6507 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
6509 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
6513 status
= cli_close(cli1
, fnum1
);
6514 if (!NT_STATUS_IS_OK(status
)) {
6515 printf("close - 1 failed (%s)\n", nt_errstr(status
));
6519 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6520 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6521 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6523 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
6525 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
6527 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6528 if (!NT_STATUS_IS_OK(status
)) {
6529 printf("Second open failed - %s\n", nt_errstr(status
));
6533 status
= cli_rename(cli1
, fname
, fname1
, false);
6534 if (!NT_STATUS_IS_OK(status
)) {
6535 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
6538 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
6541 status
= cli_close(cli1
, fnum1
);
6542 if (!NT_STATUS_IS_OK(status
)) {
6543 printf("close - 2 failed (%s)\n", nt_errstr(status
));
6547 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6548 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6550 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
6551 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
6552 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6553 if (!NT_STATUS_IS_OK(status
)) {
6554 printf("Third open failed - %s\n", nt_errstr(status
));
6559 status
= cli_rename(cli1
, fname
, fname1
, false);
6560 if (!NT_STATUS_IS_OK(status
)) {
6561 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
6564 printf("Third rename succeeded (SHARE_NONE)\n");
6567 status
= cli_close(cli1
, fnum1
);
6568 if (!NT_STATUS_IS_OK(status
)) {
6569 printf("close - 3 failed (%s)\n", nt_errstr(status
));
6573 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6574 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6578 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
6579 FILE_ATTRIBUTE_NORMAL
,
6580 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
6581 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6582 if (!NT_STATUS_IS_OK(status
)) {
6583 printf("Fourth open failed - %s\n", nt_errstr(status
));
6587 status
= cli_rename(cli1
, fname
, fname1
, false);
6588 if (!NT_STATUS_IS_OK(status
)) {
6589 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
6591 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
6595 status
= cli_close(cli1
, fnum1
);
6596 if (!NT_STATUS_IS_OK(status
)) {
6597 printf("close - 4 failed (%s)\n", nt_errstr(status
));
6601 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6602 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6606 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
6607 FILE_ATTRIBUTE_NORMAL
,
6608 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
6609 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
6610 if (!NT_STATUS_IS_OK(status
)) {
6611 printf("Fifth open failed - %s\n", nt_errstr(status
));
6615 status
= cli_rename(cli1
, fname
, fname1
, false);
6616 if (!NT_STATUS_IS_OK(status
)) {
6617 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
6620 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
6624 status
= cli_close(cli1
, fnum1
);
6625 if (!NT_STATUS_IS_OK(status
)) {
6626 printf("close - 5 failed (%s)\n", nt_errstr(status
));
6630 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
6631 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
6632 if (!NT_STATUS_IS_OK(status
)) {
6633 printf("getatr on file %s failed - %s ! \n",
6634 fname1
, nt_errstr(status
));
6637 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
6638 printf("Renamed file %s has wrong attr 0x%x "
6639 "(should be 0x%x)\n",
6642 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
6645 printf("Renamed file %s has archive bit set\n", fname1
);
6649 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6650 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6652 if (!torture_close_connection(cli1
)) {
6660 Test rename into a directory with an ACL denying it.
6662 static bool run_rename_access(int dummy
)
6664 static struct cli_state
*cli
= NULL
;
6665 static struct cli_state
*posix_cli
= NULL
;
6666 const char *src
= "test.txt";
6667 const char *dname
= "dir";
6668 const char *dst
= "dir\\test.txt";
6669 const char *dsrc
= "test.dir";
6670 const char *ddst
= "dir\\test.dir";
6671 uint16_t fnum
= (uint16_t)-1;
6672 struct security_descriptor
*sd
= NULL
;
6673 struct security_descriptor
*newsd
= NULL
;
6675 TALLOC_CTX
*frame
= NULL
;
6677 frame
= talloc_stackframe();
6678 printf("starting rename access test\n");
6680 /* Windows connection. */
6681 if (!torture_open_connection(&cli
, 0)) {
6685 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6687 /* Posix connection. */
6688 if (!torture_open_connection(&posix_cli
, 0)) {
6692 smbXcli_conn_set_sockopt(posix_cli
->conn
, sockops
);
6694 status
= torture_setup_unix_extensions(posix_cli
);
6695 if (!NT_STATUS_IS_OK(status
)) {
6699 /* Start with a clean slate. */
6700 cli_unlink(cli
, src
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6701 cli_unlink(cli
, dst
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6702 cli_rmdir(cli
, dsrc
);
6703 cli_rmdir(cli
, ddst
);
6704 cli_rmdir(cli
, dname
);
6707 * Setup the destination directory with a DENY ACE to
6708 * prevent new files within it.
6710 status
= cli_ntcreate(cli
,
6713 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
|
6714 WRITE_DAC_ACCESS
|FILE_READ_DATA
|
6716 FILE_ATTRIBUTE_DIRECTORY
,
6717 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
6719 FILE_DIRECTORY_FILE
,
6723 if (!NT_STATUS_IS_OK(status
)) {
6724 printf("Create of %s - %s\n", dname
, nt_errstr(status
));
6728 status
= cli_query_secdesc(cli
,
6732 if (!NT_STATUS_IS_OK(status
)) {
6733 printf("cli_query_secdesc failed for %s (%s)\n",
6734 dname
, nt_errstr(status
));
6738 newsd
= security_descriptor_dacl_create(frame
,
6743 SEC_ACE_TYPE_ACCESS_DENIED
,
6744 SEC_DIR_ADD_FILE
|SEC_DIR_ADD_SUBDIR
,
6747 if (newsd
== NULL
) {
6750 sd
->dacl
= security_acl_concatenate(frame
,
6753 if (sd
->dacl
== NULL
) {
6756 status
= cli_set_secdesc(cli
, fnum
, sd
);
6757 if (!NT_STATUS_IS_OK(status
)) {
6758 printf("cli_set_secdesc failed for %s (%s)\n",
6759 dname
, nt_errstr(status
));
6762 status
= cli_close(cli
, fnum
);
6763 if (!NT_STATUS_IS_OK(status
)) {
6764 printf("close failed for %s (%s)\n",
6765 dname
, nt_errstr(status
));
6768 /* Now go around the back and chmod to 777 via POSIX. */
6769 status
= cli_chmod(posix_cli
, dname
, 0777);
6770 if (!NT_STATUS_IS_OK(status
)) {
6771 printf("cli_chmod failed for %s (%s)\n",
6777 /* Check we can't create a file within dname via Windows. */
6778 status
= cli_openx(cli
, dst
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6779 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6780 cli_close(posix_cli
, fnum
);
6781 printf("Create of %s should be ACCESS denied, was %s\n",
6782 dst
, nt_errstr(status
));
6786 /* Make the sample file/directory. */
6787 status
= cli_openx(cli
, src
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6788 if (!NT_STATUS_IS_OK(status
)) {
6789 printf("open of %s failed (%s)\n", src
, nt_errstr(status
));
6792 status
= cli_close(cli
, fnum
);
6793 if (!NT_STATUS_IS_OK(status
)) {
6794 printf("cli_close failed (%s)\n", nt_errstr(status
));
6798 status
= cli_mkdir(cli
, dsrc
);
6799 if (!NT_STATUS_IS_OK(status
)) {
6800 printf("cli_mkdir of %s failed (%s)\n",
6801 dsrc
, nt_errstr(status
));
6806 * OK - renames of the new file and directory into the
6807 * dst directory should fail.
6810 status
= cli_rename(cli
, src
, dst
, false);
6811 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6812 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
6813 src
, dst
, nt_errstr(status
));
6816 status
= cli_rename(cli
, dsrc
, ddst
, false);
6817 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6818 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
6819 src
, dst
, nt_errstr(status
));
6829 torture_close_connection(posix_cli
);
6833 if (fnum
!= (uint16_t)-1) {
6834 cli_close(cli
, fnum
);
6836 cli_unlink(cli
, src
,
6837 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6838 cli_unlink(cli
, dst
,
6839 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6840 cli_rmdir(cli
, dsrc
);
6841 cli_rmdir(cli
, ddst
);
6842 cli_rmdir(cli
, dname
);
6844 torture_close_connection(cli
);
6852 Test owner rights ACE.
6854 static bool run_owner_rights(int dummy
)
6856 static struct cli_state
*cli
= NULL
;
6857 const char *fname
= "owner_rights.txt";
6858 uint16_t fnum
= (uint16_t)-1;
6859 struct security_descriptor
*sd
= NULL
;
6860 struct security_descriptor
*newsd
= NULL
;
6862 TALLOC_CTX
*frame
= NULL
;
6864 frame
= talloc_stackframe();
6865 printf("starting owner rights test\n");
6867 /* Windows connection. */
6868 if (!torture_open_connection(&cli
, 0)) {
6872 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6874 /* Start with a clean slate. */
6875 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6877 /* Create the test file. */
6878 /* Now try and open for read and write-dac. */
6879 status
= cli_ntcreate(cli
,
6883 FILE_ATTRIBUTE_NORMAL
,
6884 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6891 if (!NT_STATUS_IS_OK(status
)) {
6892 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
6896 /* Get the original SD. */
6897 status
= cli_query_secdesc(cli
,
6901 if (!NT_STATUS_IS_OK(status
)) {
6902 printf("cli_query_secdesc failed for %s (%s)\n",
6903 fname
, nt_errstr(status
));
6908 * Add an "owner-rights" ACE denying WRITE_DATA,
6909 * and an "owner-rights" ACE allowing READ_DATA.
6912 newsd
= security_descriptor_dacl_create(frame
,
6917 SEC_ACE_TYPE_ACCESS_DENIED
,
6921 SEC_ACE_TYPE_ACCESS_ALLOWED
,
6925 if (newsd
== NULL
) {
6928 sd
->dacl
= security_acl_concatenate(frame
,
6931 if (sd
->dacl
== NULL
) {
6934 status
= cli_set_secdesc(cli
, fnum
, sd
);
6935 if (!NT_STATUS_IS_OK(status
)) {
6936 printf("cli_set_secdesc failed for %s (%s)\n",
6937 fname
, nt_errstr(status
));
6940 status
= cli_close(cli
, fnum
);
6941 if (!NT_STATUS_IS_OK(status
)) {
6942 printf("close failed for %s (%s)\n",
6943 fname
, nt_errstr(status
));
6946 fnum
= (uint16_t)-1;
6948 /* Try and open for FILE_WRITE_DATA */
6949 status
= cli_ntcreate(cli
,
6953 FILE_ATTRIBUTE_NORMAL
,
6954 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6961 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
6962 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
6966 /* Now try and open for FILE_READ_DATA */
6967 status
= cli_ntcreate(cli
,
6971 FILE_ATTRIBUTE_NORMAL
,
6972 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6979 if (!NT_STATUS_IS_OK(status
)) {
6980 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
6984 status
= cli_close(cli
, fnum
);
6985 if (!NT_STATUS_IS_OK(status
)) {
6986 printf("close failed for %s (%s)\n",
6987 fname
, nt_errstr(status
));
6991 /* Restore clean slate. */
6993 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6995 /* Create the test file. */
6996 status
= cli_ntcreate(cli
,
7000 FILE_ATTRIBUTE_NORMAL
,
7001 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7008 if (!NT_STATUS_IS_OK(status
)) {
7009 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
7013 /* Get the original SD. */
7014 status
= cli_query_secdesc(cli
,
7018 if (!NT_STATUS_IS_OK(status
)) {
7019 printf("cli_query_secdesc failed for %s (%s)\n",
7020 fname
, nt_errstr(status
));
7025 * Add an "owner-rights ACE denying WRITE_DATA,
7026 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
7029 newsd
= security_descriptor_dacl_create(frame
,
7034 SEC_ACE_TYPE_ACCESS_DENIED
,
7038 SEC_ACE_TYPE_ACCESS_ALLOWED
,
7039 FILE_READ_DATA
|FILE_WRITE_DATA
,
7042 if (newsd
== NULL
) {
7045 sd
->dacl
= security_acl_concatenate(frame
,
7048 if (sd
->dacl
== NULL
) {
7051 status
= cli_set_secdesc(cli
, fnum
, sd
);
7052 if (!NT_STATUS_IS_OK(status
)) {
7053 printf("cli_set_secdesc failed for %s (%s)\n",
7054 fname
, nt_errstr(status
));
7057 status
= cli_close(cli
, fnum
);
7058 if (!NT_STATUS_IS_OK(status
)) {
7059 printf("close failed for %s (%s)\n",
7060 fname
, nt_errstr(status
));
7063 fnum
= (uint16_t)-1;
7065 /* Try and open for FILE_WRITE_DATA */
7066 status
= cli_ntcreate(cli
,
7070 FILE_ATTRIBUTE_NORMAL
,
7071 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7078 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
7079 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
7083 /* Now try and open for FILE_READ_DATA */
7084 status
= cli_ntcreate(cli
,
7088 FILE_ATTRIBUTE_NORMAL
,
7089 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7096 if (!NT_STATUS_IS_OK(status
)) {
7097 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
7101 status
= cli_close(cli
, fnum
);
7102 if (!NT_STATUS_IS_OK(status
)) {
7103 printf("close failed for %s (%s)\n",
7104 fname
, nt_errstr(status
));
7108 /* Restore clean slate. */
7110 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7113 /* Create the test file. */
7114 status
= cli_ntcreate(cli
,
7118 FILE_ATTRIBUTE_NORMAL
,
7119 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7126 if (!NT_STATUS_IS_OK(status
)) {
7127 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
7131 /* Get the original SD. */
7132 status
= cli_query_secdesc(cli
,
7136 if (!NT_STATUS_IS_OK(status
)) {
7137 printf("cli_query_secdesc failed for %s (%s)\n",
7138 fname
, nt_errstr(status
));
7143 * Add an "authenticated users" ACE allowing READ_DATA,
7144 * add an "owner-rights" denying READ_DATA,
7145 * and an "authenticated users" ACE allowing WRITE_DATA.
7148 newsd
= security_descriptor_dacl_create(frame
,
7152 SID_NT_AUTHENTICATED_USERS
,
7153 SEC_ACE_TYPE_ACCESS_ALLOWED
,
7157 SEC_ACE_TYPE_ACCESS_DENIED
,
7160 SID_NT_AUTHENTICATED_USERS
,
7161 SEC_ACE_TYPE_ACCESS_ALLOWED
,
7165 if (newsd
== NULL
) {
7166 printf("newsd == NULL\n");
7169 sd
->dacl
= security_acl_concatenate(frame
,
7172 if (sd
->dacl
== NULL
) {
7173 printf("sd->dacl == NULL\n");
7176 status
= cli_set_secdesc(cli
, fnum
, sd
);
7177 if (!NT_STATUS_IS_OK(status
)) {
7178 printf("cli_set_secdesc failed for %s (%s)\n",
7179 fname
, nt_errstr(status
));
7182 status
= cli_close(cli
, fnum
);
7183 if (!NT_STATUS_IS_OK(status
)) {
7184 printf("close failed for %s (%s)\n",
7185 fname
, nt_errstr(status
));
7188 fnum
= (uint16_t)-1;
7190 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
7191 status
= cli_ntcreate(cli
,
7194 FILE_READ_DATA
|FILE_WRITE_DATA
,
7195 FILE_ATTRIBUTE_NORMAL
,
7196 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7203 if (!NT_STATUS_IS_OK(status
)) {
7204 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
7208 status
= cli_close(cli
, fnum
);
7209 if (!NT_STATUS_IS_OK(status
)) {
7210 printf("close failed for %s (%s)\n",
7211 fname
, nt_errstr(status
));
7215 cli_unlink(cli
, fname
,
7216 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7224 if (fnum
!= (uint16_t)-1) {
7225 cli_close(cli
, fnum
);
7227 cli_unlink(cli
, fname
,
7228 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7229 torture_close_connection(cli
);
7237 * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
7238 * Note this test only works with a user with SeSecurityPrivilege set.
7240 * NB. This is also tested in samba3.base.createx_access
7241 * but this makes it very explicit what we're looking for.
7243 static bool run_smb1_system_security(int dummy
)
7245 static struct cli_state
*cli
= NULL
;
7246 const char *fname
= "system_security.txt";
7247 uint16_t fnum
= (uint16_t)-1;
7249 TALLOC_CTX
*frame
= NULL
;
7251 frame
= talloc_stackframe();
7252 printf("starting smb1 system security test\n");
7254 /* SMB1 connection - torture_open_connection() forces this. */
7255 if (!torture_open_connection(&cli
, 0)) {
7259 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7261 /* Start with a clean slate. */
7262 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7264 /* Create the test file. */
7265 status
= cli_ntcreate(cli
,
7269 FILE_ATTRIBUTE_NORMAL
,
7270 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7277 if (!NT_STATUS_IS_OK(status
)) {
7278 printf("Create of %s - %s\n", fname
, nt_errstr(status
));
7282 status
= cli_close(cli
, fnum
);
7284 /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
7286 * On SMB1 this succeeds - SMB2 it fails,
7287 * see the SMB2-SACL test.
7289 status
= cli_ntcreate(cli
,
7292 SEC_FLAG_SYSTEM_SECURITY
,
7293 FILE_ATTRIBUTE_NORMAL
,
7294 FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7301 if (!NT_STATUS_IS_OK(status
)) {
7302 printf("Open of %s - %s\n", fname
, nt_errstr(status
));
7306 status
= cli_close(cli
, fnum
);
7308 cli_unlink(cli
, fname
,
7309 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7311 torture_close_connection(cli
);
7318 if (fnum
!= (uint16_t)-1) {
7319 cli_close(cli
, fnum
);
7321 cli_unlink(cli
, fname
,
7322 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7323 torture_close_connection(cli
);
7330 static bool run_pipe_number(int dummy
)
7332 struct cli_state
*cli1
;
7333 const char *pipe_name
= "\\SPOOLSS";
7338 printf("starting pipenumber test\n");
7339 if (!torture_open_connection(&cli1
, 0)) {
7343 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7345 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
7346 FILE_ATTRIBUTE_NORMAL
,
7347 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
7348 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
7349 if (!NT_STATUS_IS_OK(status
)) {
7350 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
7354 printf("\r%6d", num_pipes
);
7357 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
7358 torture_close_connection(cli1
);
7363 Test open mode returns on read-only files.
7365 static bool run_opentest(int dummy
)
7367 static struct cli_state
*cli1
;
7368 static struct cli_state
*cli2
;
7369 const char *fname
= "\\readonly.file";
7370 uint16_t fnum1
, fnum2
;
7373 bool correct
= True
;
7377 printf("starting open test\n");
7379 if (!torture_open_connection(&cli1
, 0)) {
7383 cli_setatr(cli1
, fname
, 0, 0);
7384 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7386 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7388 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
7389 if (!NT_STATUS_IS_OK(status
)) {
7390 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
7394 status
= cli_close(cli1
, fnum1
);
7395 if (!NT_STATUS_IS_OK(status
)) {
7396 printf("close2 failed (%s)\n", nt_errstr(status
));
7400 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
7401 if (!NT_STATUS_IS_OK(status
)) {
7402 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
7406 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
7407 if (!NT_STATUS_IS_OK(status
)) {
7408 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
7412 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
7413 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
7415 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
7416 NT_STATUS_ACCESS_DENIED
)) {
7417 printf("correct error code ERRDOS/ERRnoaccess returned\n");
7420 printf("finished open test 1\n");
7422 cli_close(cli1
, fnum1
);
7424 /* Now try not readonly and ensure ERRbadshare is returned. */
7426 cli_setatr(cli1
, fname
, 0, 0);
7428 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
7429 if (!NT_STATUS_IS_OK(status
)) {
7430 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
7434 /* This will fail - but the error should be ERRshare. */
7435 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
7437 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
7438 NT_STATUS_SHARING_VIOLATION
)) {
7439 printf("correct error code ERRDOS/ERRbadshare returned\n");
7442 status
= cli_close(cli1
, fnum1
);
7443 if (!NT_STATUS_IS_OK(status
)) {
7444 printf("close2 failed (%s)\n", nt_errstr(status
));
7448 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7450 printf("finished open test 2\n");
7452 /* Test truncate open disposition on file opened for read. */
7453 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
7454 if (!NT_STATUS_IS_OK(status
)) {
7455 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
7459 /* write 20 bytes. */
7461 memset(buf
, '\0', 20);
7463 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
7464 if (!NT_STATUS_IS_OK(status
)) {
7465 printf("write failed (%s)\n", nt_errstr(status
));
7469 status
= cli_close(cli1
, fnum1
);
7470 if (!NT_STATUS_IS_OK(status
)) {
7471 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
7475 /* Ensure size == 20. */
7476 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
7477 if (!NT_STATUS_IS_OK(status
)) {
7478 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
7483 printf("(3) file size != 20\n");
7487 /* Now test if we can truncate a file opened for readonly. */
7488 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
7489 if (!NT_STATUS_IS_OK(status
)) {
7490 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
7494 status
= cli_close(cli1
, fnum1
);
7495 if (!NT_STATUS_IS_OK(status
)) {
7496 printf("close2 failed (%s)\n", nt_errstr(status
));
7500 /* Ensure size == 0. */
7501 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
7502 if (!NT_STATUS_IS_OK(status
)) {
7503 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
7508 printf("(3) file size != 0\n");
7511 printf("finished open test 3\n");
7513 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7515 printf("Do ctemp tests\n");
7516 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
7517 if (!NT_STATUS_IS_OK(status
)) {
7518 printf("ctemp failed (%s)\n", nt_errstr(status
));
7522 printf("ctemp gave path %s\n", tmp_path
);
7523 status
= cli_close(cli1
, fnum1
);
7524 if (!NT_STATUS_IS_OK(status
)) {
7525 printf("close of temp failed (%s)\n", nt_errstr(status
));
7528 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7529 if (!NT_STATUS_IS_OK(status
)) {
7530 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
7533 /* Test the non-io opens... */
7535 if (!torture_open_connection(&cli2
, 1)) {
7539 cli_setatr(cli2
, fname
, 0, 0);
7540 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7542 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
7544 printf("TEST #1 testing 2 non-io opens (no delete)\n");
7545 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
7546 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7547 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7548 if (!NT_STATUS_IS_OK(status
)) {
7549 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7553 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
7554 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7555 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7556 if (!NT_STATUS_IS_OK(status
)) {
7557 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7561 status
= cli_close(cli1
, fnum1
);
7562 if (!NT_STATUS_IS_OK(status
)) {
7563 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7567 status
= cli_close(cli2
, fnum2
);
7568 if (!NT_STATUS_IS_OK(status
)) {
7569 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7573 printf("non-io open test #1 passed.\n");
7575 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7577 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
7579 status
= cli_ntcreate(cli1
, fname
, 0,
7580 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7581 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7582 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7583 if (!NT_STATUS_IS_OK(status
)) {
7584 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7588 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
7589 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7590 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7591 if (!NT_STATUS_IS_OK(status
)) {
7592 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7596 status
= cli_close(cli1
, fnum1
);
7597 if (!NT_STATUS_IS_OK(status
)) {
7598 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7602 status
= cli_close(cli2
, fnum2
);
7603 if (!NT_STATUS_IS_OK(status
)) {
7604 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7608 printf("non-io open test #2 passed.\n");
7610 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7612 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
7614 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
7615 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7616 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7617 if (!NT_STATUS_IS_OK(status
)) {
7618 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7622 status
= cli_ntcreate(cli2
, fname
, 0,
7623 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7624 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7625 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7626 if (!NT_STATUS_IS_OK(status
)) {
7627 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7631 status
= cli_close(cli1
, fnum1
);
7632 if (!NT_STATUS_IS_OK(status
)) {
7633 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7637 status
= cli_close(cli2
, fnum2
);
7638 if (!NT_STATUS_IS_OK(status
)) {
7639 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7643 printf("non-io open test #3 passed.\n");
7645 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7647 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
7649 status
= cli_ntcreate(cli1
, fname
, 0,
7650 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7651 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7652 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7653 if (!NT_STATUS_IS_OK(status
)) {
7654 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7658 status
= cli_ntcreate(cli2
, fname
, 0,
7659 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7660 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7661 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7662 if (NT_STATUS_IS_OK(status
)) {
7663 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
7667 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
7669 status
= cli_close(cli1
, fnum1
);
7670 if (!NT_STATUS_IS_OK(status
)) {
7671 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7675 printf("non-io open test #4 passed.\n");
7677 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7679 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
7681 status
= cli_ntcreate(cli1
, fname
, 0,
7682 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7683 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
7684 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7685 if (!NT_STATUS_IS_OK(status
)) {
7686 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7690 status
= cli_ntcreate(cli2
, fname
, 0,
7691 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7692 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
7693 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7694 if (!NT_STATUS_IS_OK(status
)) {
7695 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7699 status
= cli_close(cli1
, fnum1
);
7700 if (!NT_STATUS_IS_OK(status
)) {
7701 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7705 status
= cli_close(cli2
, fnum2
);
7706 if (!NT_STATUS_IS_OK(status
)) {
7707 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7711 printf("non-io open test #5 passed.\n");
7713 printf("TEST #6 testing 1 non-io open, one io open\n");
7715 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7717 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
7718 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7719 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7720 if (!NT_STATUS_IS_OK(status
)) {
7721 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7725 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
7726 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7727 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7728 if (!NT_STATUS_IS_OK(status
)) {
7729 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7733 status
= cli_close(cli1
, fnum1
);
7734 if (!NT_STATUS_IS_OK(status
)) {
7735 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7739 status
= cli_close(cli2
, fnum2
);
7740 if (!NT_STATUS_IS_OK(status
)) {
7741 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
7745 printf("non-io open test #6 passed.\n");
7747 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
7749 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7751 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
7752 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
7753 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7754 if (!NT_STATUS_IS_OK(status
)) {
7755 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7759 status
= cli_ntcreate(cli2
, fname
, 0,
7760 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
7761 FILE_ATTRIBUTE_NORMAL
,
7762 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
7763 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
7764 if (NT_STATUS_IS_OK(status
)) {
7765 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
7769 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
7771 status
= cli_close(cli1
, fnum1
);
7772 if (!NT_STATUS_IS_OK(status
)) {
7773 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
7777 printf("non-io open test #7 passed.\n");
7779 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7781 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
7782 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
7783 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
7784 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
7785 if (!NT_STATUS_IS_OK(status
)) {
7786 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
7791 /* Write to ensure we have to update the file time. */
7792 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
7794 if (!NT_STATUS_IS_OK(status
)) {
7795 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
7800 status
= cli_close(cli1
, fnum1
);
7801 if (!NT_STATUS_IS_OK(status
)) {
7802 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
7808 if (!torture_close_connection(cli1
)) {
7811 if (!torture_close_connection(cli2
)) {
7818 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
7820 uint16_t major
, minor
;
7821 uint32_t caplow
, caphigh
;
7824 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
7825 printf("Server doesn't support UNIX CIFS extensions.\n");
7826 return NT_STATUS_NOT_SUPPORTED
;
7829 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
7831 if (!NT_STATUS_IS_OK(status
)) {
7832 printf("Server didn't return UNIX CIFS extensions: %s\n",
7837 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
7839 if (!NT_STATUS_IS_OK(status
)) {
7840 printf("Server doesn't support setting UNIX CIFS extensions: "
7841 "%s.\n", nt_errstr(status
));
7845 return NT_STATUS_OK
;
7849 Test POSIX open /mkdir calls.
7851 static bool run_simple_posix_open_test(int dummy
)
7853 static struct cli_state
*cli1
;
7854 const char *fname
= "posix:file";
7855 const char *hname
= "posix:hlink";
7856 const char *sname
= "posix:symlink";
7857 const char *dname
= "posix:dir";
7859 char *target
= NULL
;
7860 uint16_t fnum1
= (uint16_t)-1;
7861 SMB_STRUCT_STAT sbuf
;
7862 bool correct
= false;
7865 const char *fname_windows
= "windows_file";
7866 uint16_t fnum2
= (uint16_t)-1;
7869 printf("Starting simple POSIX open test\n");
7871 if (!torture_open_connection(&cli1
, 0)) {
7875 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7877 status
= torture_setup_unix_extensions(cli1
);
7878 if (!NT_STATUS_IS_OK(status
)) {
7882 cli_setatr(cli1
, fname
, 0, 0);
7883 cli_posix_unlink(cli1
, fname
);
7884 cli_setatr(cli1
, dname
, 0, 0);
7885 cli_posix_rmdir(cli1
, dname
);
7886 cli_setatr(cli1
, hname
, 0, 0);
7887 cli_posix_unlink(cli1
, hname
);
7888 cli_setatr(cli1
, sname
, 0, 0);
7889 cli_posix_unlink(cli1
, sname
);
7890 cli_setatr(cli1
, fname_windows
, 0, 0);
7891 cli_posix_unlink(cli1
, fname_windows
);
7893 /* Create a directory. */
7894 status
= cli_posix_mkdir(cli1
, dname
, 0777);
7895 if (!NT_STATUS_IS_OK(status
)) {
7896 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
7900 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
7902 if (!NT_STATUS_IS_OK(status
)) {
7903 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
7907 /* Test ftruncate - set file size. */
7908 status
= cli_ftruncate(cli1
, fnum1
, 1000);
7909 if (!NT_STATUS_IS_OK(status
)) {
7910 printf("ftruncate failed (%s)\n", nt_errstr(status
));
7914 /* Ensure st_size == 1000 */
7915 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
7916 if (!NT_STATUS_IS_OK(status
)) {
7917 printf("stat failed (%s)\n", nt_errstr(status
));
7921 if (sbuf
.st_ex_size
!= 1000) {
7922 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
7926 /* Ensure st_mode == 0600 */
7927 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
7928 printf("posix_open - bad permissions 0%o != 0600\n",
7929 (unsigned int)(sbuf
.st_ex_mode
& 07777));
7933 /* Test ftruncate - set file size back to zero. */
7934 status
= cli_ftruncate(cli1
, fnum1
, 0);
7935 if (!NT_STATUS_IS_OK(status
)) {
7936 printf("ftruncate failed (%s)\n", nt_errstr(status
));
7940 status
= cli_close(cli1
, fnum1
);
7941 if (!NT_STATUS_IS_OK(status
)) {
7942 printf("close failed (%s)\n", nt_errstr(status
));
7946 /* Now open the file again for read only. */
7947 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
7948 if (!NT_STATUS_IS_OK(status
)) {
7949 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
7953 /* Now unlink while open. */
7954 status
= cli_posix_unlink(cli1
, fname
);
7955 if (!NT_STATUS_IS_OK(status
)) {
7956 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
7960 status
= cli_close(cli1
, fnum1
);
7961 if (!NT_STATUS_IS_OK(status
)) {
7962 printf("close(2) failed (%s)\n", nt_errstr(status
));
7966 /* Ensure the file has gone. */
7967 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
7968 if (NT_STATUS_IS_OK(status
)) {
7969 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
7973 /* Create again to test open with O_TRUNC. */
7974 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
7975 if (!NT_STATUS_IS_OK(status
)) {
7976 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
7980 /* Test ftruncate - set file size. */
7981 status
= cli_ftruncate(cli1
, fnum1
, 1000);
7982 if (!NT_STATUS_IS_OK(status
)) {
7983 printf("ftruncate failed (%s)\n", nt_errstr(status
));
7987 /* Ensure st_size == 1000 */
7988 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
7989 if (!NT_STATUS_IS_OK(status
)) {
7990 printf("stat failed (%s)\n", nt_errstr(status
));
7994 if (sbuf
.st_ex_size
!= 1000) {
7995 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
7999 status
= cli_close(cli1
, fnum1
);
8000 if (!NT_STATUS_IS_OK(status
)) {
8001 printf("close(2) failed (%s)\n", nt_errstr(status
));
8005 /* Re-open with O_TRUNC. */
8006 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
8007 if (!NT_STATUS_IS_OK(status
)) {
8008 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
8012 /* Ensure st_size == 0 */
8013 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
8014 if (!NT_STATUS_IS_OK(status
)) {
8015 printf("stat failed (%s)\n", nt_errstr(status
));
8019 if (sbuf
.st_ex_size
!= 0) {
8020 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
8024 status
= cli_close(cli1
, fnum1
);
8025 if (!NT_STATUS_IS_OK(status
)) {
8026 printf("close failed (%s)\n", nt_errstr(status
));
8030 status
= cli_posix_unlink(cli1
, fname
);
8031 if (!NT_STATUS_IS_OK(status
)) {
8032 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
8036 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
8037 if (!NT_STATUS_IS_OK(status
)) {
8038 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
8039 dname
, nt_errstr(status
));
8043 cli_close(cli1
, fnum1
);
8045 /* What happens when we try and POSIX open a directory for write ? */
8046 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
8047 if (NT_STATUS_IS_OK(status
)) {
8048 printf("POSIX open of directory %s succeeded, "
8049 "should have failed.\n",
8053 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
8054 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
8059 /* Create the file. */
8060 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
8062 if (!NT_STATUS_IS_OK(status
)) {
8063 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
8067 /* Write some data into it. */
8068 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
8070 if (!NT_STATUS_IS_OK(status
)) {
8071 printf("cli_write failed: %s\n", nt_errstr(status
));
8075 cli_close(cli1
, fnum1
);
8077 /* Now create a hardlink. */
8078 status
= cli_posix_hardlink(cli1
, fname
, hname
);
8079 if (!NT_STATUS_IS_OK(status
)) {
8080 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
8084 /* Now create a symlink. */
8085 status
= cli_posix_symlink(cli1
, fname
, sname
);
8086 if (!NT_STATUS_IS_OK(status
)) {
8087 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
8091 /* Open the hardlink for read. */
8092 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
8093 if (!NT_STATUS_IS_OK(status
)) {
8094 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
8098 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
8099 if (!NT_STATUS_IS_OK(status
)) {
8100 printf("POSIX read of %s failed (%s)\n", hname
,
8103 } else if (nread
!= 10) {
8104 printf("POSIX read of %s failed. Received %ld, expected %d\n",
8105 hname
, (unsigned long)nread
, 10);
8109 if (memcmp(buf
, "TEST DATA\n", 10)) {
8110 printf("invalid data read from hardlink\n");
8114 /* Do a POSIX lock/unlock. */
8115 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
8116 if (!NT_STATUS_IS_OK(status
)) {
8117 printf("POSIX lock failed %s\n", nt_errstr(status
));
8121 /* Punch a hole in the locked area. */
8122 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
8123 if (!NT_STATUS_IS_OK(status
)) {
8124 printf("POSIX unlock failed %s\n", nt_errstr(status
));
8128 cli_close(cli1
, fnum1
);
8130 /* Open the symlink for read - this should fail. A POSIX
8131 client should not be doing opens on a symlink. */
8132 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
8133 if (NT_STATUS_IS_OK(status
)) {
8134 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
8137 ok
= check_both_error(
8138 __LINE__
, status
, ERRDOS
, ERRbadpath
,
8139 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
8141 printf("POSIX open of %s should have failed "
8142 "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
8143 "failed with %s instead.\n",
8144 sname
, nt_errstr(status
));
8148 status
= cli_readlink(cli1
, sname
, talloc_tos(), &target
, NULL
, NULL
);
8149 if (!NT_STATUS_IS_OK(status
)) {
8150 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
8154 if (strcmp(target
, fname
) != 0) {
8155 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
8156 sname
, fname
, target
);
8160 status
= cli_posix_rmdir(cli1
, dname
);
8161 if (!NT_STATUS_IS_OK(status
)) {
8162 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
8166 /* Check directory opens with a specific permission. */
8167 status
= cli_posix_mkdir(cli1
, dname
, 0700);
8168 if (!NT_STATUS_IS_OK(status
)) {
8169 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
8173 /* Ensure st_mode == 0700 */
8174 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
8175 if (!NT_STATUS_IS_OK(status
)) {
8176 printf("stat failed (%s)\n", nt_errstr(status
));
8180 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
8181 printf("posix_mkdir - bad permissions 0%o != 0700\n",
8182 (unsigned int)(sbuf
.st_ex_mode
& 07777));
8187 * Now create a Windows file, and attempt a POSIX unlink.
8188 * This should fail with a sharing violation but due to:
8190 * [Bug 9571] Unlink after open causes smbd to panic
8192 * ensure we've fixed the lock ordering violation.
8195 status
= cli_ntcreate(cli1
, fname_windows
, 0,
8196 FILE_READ_DATA
|FILE_WRITE_DATA
, 0,
8197 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8199 0x0, 0x0, &fnum2
, NULL
);
8200 if (!NT_STATUS_IS_OK(status
)) {
8201 printf("Windows create of %s failed (%s)\n", fname_windows
,
8206 /* Now try posix_unlink. */
8207 status
= cli_posix_unlink(cli1
, fname_windows
);
8208 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
8209 printf("POSIX unlink of %s should fail "
8210 "with NT_STATUS_SHARING_VIOLATION "
8211 "got %s instead !\n",
8217 cli_close(cli1
, fnum2
);
8219 printf("Simple POSIX open test passed\n");
8224 if (fnum1
!= (uint16_t)-1) {
8225 cli_close(cli1
, fnum1
);
8226 fnum1
= (uint16_t)-1;
8229 if (fnum2
!= (uint16_t)-1) {
8230 cli_close(cli1
, fnum2
);
8231 fnum2
= (uint16_t)-1;
8234 cli_setatr(cli1
, sname
, 0, 0);
8235 cli_posix_unlink(cli1
, sname
);
8236 cli_setatr(cli1
, hname
, 0, 0);
8237 cli_posix_unlink(cli1
, hname
);
8238 cli_setatr(cli1
, fname
, 0, 0);
8239 cli_posix_unlink(cli1
, fname
);
8240 cli_setatr(cli1
, dname
, 0, 0);
8241 cli_posix_rmdir(cli1
, dname
);
8242 cli_setatr(cli1
, fname_windows
, 0, 0);
8243 cli_posix_unlink(cli1
, fname_windows
);
8245 if (!torture_close_connection(cli1
)) {
8253 Test POSIX and Windows ACLs are rejected on symlinks.
8255 static bool run_acl_symlink_test(int dummy
)
8257 static struct cli_state
*cli
;
8258 const char *fname
= "posix_file";
8259 const char *sname
= "posix_symlink";
8260 uint16_t fnum
= (uint16_t)-1;
8261 bool correct
= false;
8263 char *posix_acl
= NULL
;
8264 size_t posix_acl_len
= 0;
8265 char *posix_acl_sym
= NULL
;
8266 size_t posix_acl_len_sym
= 0;
8267 struct security_descriptor
*sd
= NULL
;
8268 TALLOC_CTX
*frame
= NULL
;
8270 frame
= talloc_stackframe();
8272 printf("Starting acl symlink test\n");
8274 if (!torture_open_connection(&cli
, 0)) {
8279 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8281 status
= torture_setup_unix_extensions(cli
);
8282 if (!NT_STATUS_IS_OK(status
)) {
8287 cli_setatr(cli
, fname
, 0, 0);
8288 cli_posix_unlink(cli
, fname
);
8289 cli_setatr(cli
, sname
, 0, 0);
8290 cli_posix_unlink(cli
, sname
);
8292 status
= cli_ntcreate(cli
,
8295 READ_CONTROL_ACCESS
,
8297 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8304 if (!NT_STATUS_IS_OK(status
)) {
8305 printf("cli_ntcreate of %s failed (%s)\n",
8311 /* Get the Windows ACL on the file. */
8312 status
= cli_query_secdesc(cli
,
8316 if (!NT_STATUS_IS_OK(status
)) {
8317 printf("cli_query_secdesc failed (%s)\n",
8322 /* Get the POSIX ACL on the file. */
8323 status
= cli_posix_getacl(cli
,
8329 if (!NT_STATUS_IS_OK(status
)) {
8330 printf("cli_posix_getacl failed (%s)\n",
8335 status
= cli_close(cli
, fnum
);
8336 if (!NT_STATUS_IS_OK(status
)) {
8337 printf("close failed (%s)\n", nt_errstr(status
));
8340 fnum
= (uint16_t)-1;
8342 /* Now create a symlink. */
8343 status
= cli_posix_symlink(cli
, fname
, sname
);
8344 if (!NT_STATUS_IS_OK(status
)) {
8345 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
8352 /* Open a handle on the symlink for SD set/get should fail. */
8353 status
= cli_ntcreate(cli
,
8356 READ_CONTROL_ACCESS
|SEC_STD_WRITE_DAC
,
8358 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8365 if (NT_STATUS_IS_OK(status
)) {
8366 printf("Symlink open for getsd/setsd of %s "
8367 "succeeded (should fail)\n",
8372 /* Try a stat-open on the symlink, should also fail. */
8373 status
= cli_ntcreate(cli
,
8376 FILE_READ_ATTRIBUTES
|FILE_WRITE_ATTRIBUTES
,
8378 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8385 if (NT_STATUS_IS_OK(status
)) {
8386 printf("Stat-open of symlink succeeded (should fail)\n");
8390 /* Get the POSIX ACL on the symlink pathname. Should fail. */
8391 status
= cli_posix_getacl(cli
,
8397 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
8398 printf("cli_posix_getacl on a symlink gave %s. "
8399 "Should be NT_STATUS_ACCESS_DENIED.\n",
8404 /* Set the POSIX ACL on the symlink pathname. Should fail. */
8405 status
= cli_posix_setacl(cli
,
8410 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
8411 printf("cli_posix_setacl on a symlink gave %s. "
8412 "Should be NT_STATUS_ACCESS_DENIED.\n",
8417 printf("ACL symlink test passed\n");
8422 if (fnum
!= (uint16_t)-1) {
8423 cli_close(cli
, fnum
);
8424 fnum
= (uint16_t)-1;
8427 cli_setatr(cli
, sname
, 0, 0);
8428 cli_posix_unlink(cli
, sname
);
8429 cli_setatr(cli
, fname
, 0, 0);
8430 cli_posix_unlink(cli
, fname
);
8432 if (!torture_close_connection(cli
)) {
8441 Test POSIX can delete a file containing streams.
8443 static bool run_posix_stream_delete(int dummy
)
8445 struct cli_state
*cli1
= NULL
;
8446 struct cli_state
*cli2
= NULL
;
8447 const char *fname
= "streamfile";
8448 const char *stream_fname
= "streamfile:Zone.Identifier:$DATA";
8449 uint16_t fnum1
= (uint16_t)-1;
8450 bool correct
= false;
8452 TALLOC_CTX
*frame
= NULL
;
8454 frame
= talloc_stackframe();
8456 printf("Starting POSIX stream delete test\n");
8458 if (!torture_open_connection(&cli1
, 0) ||
8459 !torture_open_connection(&cli2
, 1)) {
8464 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
8465 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
8467 status
= torture_setup_unix_extensions(cli2
);
8468 if (!NT_STATUS_IS_OK(status
)) {
8472 cli_setatr(cli1
, fname
, 0, 0);
8473 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8475 /* Create the file. */
8476 status
= cli_ntcreate(cli1
,
8479 READ_CONTROL_ACCESS
,
8481 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8488 if (!NT_STATUS_IS_OK(status
)) {
8489 printf("cli_ntcreate of %s failed (%s)\n",
8495 status
= cli_close(cli1
, fnum1
);
8496 if (!NT_STATUS_IS_OK(status
)) {
8497 printf("cli_close of %s failed (%s)\n",
8502 fnum1
= (uint16_t)-1;
8504 /* Now create the stream. */
8505 status
= cli_ntcreate(cli1
,
8510 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
8517 if (!NT_STATUS_IS_OK(status
)) {
8518 printf("cli_ntcreate of %s failed (%s)\n",
8524 /* Leave the stream handle open... */
8526 /* POSIX unlink should fail. */
8527 status
= cli_posix_unlink(cli2
, fname
);
8528 if (NT_STATUS_IS_OK(status
)) {
8529 printf("cli_posix_unlink of %s succeeded, should have failed\n",
8534 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
8535 printf("cli_posix_unlink of %s failed with (%s) "
8536 "should have been NT_STATUS_SHARING_VIOLATION\n",
8542 /* Close the stream handle. */
8543 status
= cli_close(cli1
, fnum1
);
8544 if (!NT_STATUS_IS_OK(status
)) {
8545 printf("cli_close of %s failed (%s)\n",
8550 fnum1
= (uint16_t)-1;
8552 /* POSIX unlink after stream handle closed should succeed. */
8553 status
= cli_posix_unlink(cli2
, fname
);
8554 if (!NT_STATUS_IS_OK(status
)) {
8555 printf("cli_posix_unlink of %s failed (%s)\n",
8561 printf("POSIX stream delete test passed\n");
8566 if (fnum1
!= (uint16_t)-1) {
8567 cli_close(cli1
, fnum1
);
8568 fnum1
= (uint16_t)-1;
8571 cli_setatr(cli1
, fname
, 0, 0);
8572 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8574 if (!torture_close_connection(cli1
)) {
8577 if (!torture_close_connection(cli2
)) {
8586 Test setting EA's are rejected on symlinks.
8588 static bool run_ea_symlink_test(int dummy
)
8590 static struct cli_state
*cli
;
8591 const char *fname
= "posix_file_ea";
8592 const char *sname
= "posix_symlink_ea";
8593 const char *ea_name
= "testea_name";
8594 const char *ea_value
= "testea_value";
8595 uint16_t fnum
= (uint16_t)-1;
8596 bool correct
= false;
8599 struct ea_struct
*eas
= NULL
;
8600 TALLOC_CTX
*frame
= NULL
;
8602 frame
= talloc_stackframe();
8604 printf("Starting EA symlink test\n");
8606 if (!torture_open_connection(&cli
, 0)) {
8611 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8613 status
= torture_setup_unix_extensions(cli
);
8614 if (!NT_STATUS_IS_OK(status
)) {
8619 cli_setatr(cli
, fname
, 0, 0);
8620 cli_posix_unlink(cli
, fname
);
8621 cli_setatr(cli
, sname
, 0, 0);
8622 cli_posix_unlink(cli
, sname
);
8624 status
= cli_ntcreate(cli
,
8627 READ_CONTROL_ACCESS
,
8629 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
8636 if (!NT_STATUS_IS_OK(status
)) {
8637 printf("cli_ntcreate of %s failed (%s)\n",
8643 status
= cli_close(cli
, fnum
);
8644 if (!NT_STATUS_IS_OK(status
)) {
8645 printf("close failed (%s)\n",
8649 fnum
= (uint16_t)-1;
8651 /* Set an EA on the path. */
8652 status
= cli_set_ea_path(cli
,
8656 strlen(ea_value
)+1);
8658 if (!NT_STATUS_IS_OK(status
)) {
8659 printf("cli_set_ea_path failed (%s)\n",
8664 /* Now create a symlink. */
8665 status
= cli_posix_symlink(cli
, fname
, sname
);
8666 if (!NT_STATUS_IS_OK(status
)) {
8667 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
8674 /* Get the EA list on the path. Should return value set. */
8675 status
= cli_get_ea_list_path(cli
,
8681 if (!NT_STATUS_IS_OK(status
)) {
8682 printf("cli_get_ea_list_path failed (%s)\n",
8687 /* Ensure the EA we set is there. */
8688 for (i
=0; i
<num_eas
; i
++) {
8689 if (strcmp(eas
[i
].name
, ea_name
) == 0 &&
8690 eas
[i
].value
.length
== strlen(ea_value
)+1 &&
8691 memcmp(eas
[i
].value
.data
,
8693 eas
[i
].value
.length
) == 0) {
8699 printf("Didn't find EA on pathname %s\n",
8707 /* Get the EA list on the symlink. Should return empty list. */
8708 status
= cli_get_ea_list_path(cli
,
8714 if (!NT_STATUS_IS_OK(status
)) {
8715 printf("cli_get_ea_list_path failed (%s)\n",
8721 printf("cli_get_ea_list_path failed (%s)\n",
8726 /* Set an EA on the symlink. Should fail. */
8727 status
= cli_set_ea_path(cli
,
8731 strlen(ea_value
)+1);
8733 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
8734 printf("cli_set_ea_path on a symlink gave %s. "
8735 "Should be NT_STATUS_ACCESS_DENIED.\n",
8740 printf("EA symlink test passed\n");
8745 if (fnum
!= (uint16_t)-1) {
8746 cli_close(cli
, fnum
);
8747 fnum
= (uint16_t)-1;
8750 cli_setatr(cli
, sname
, 0, 0);
8751 cli_posix_unlink(cli
, sname
);
8752 cli_setatr(cli
, fname
, 0, 0);
8753 cli_posix_unlink(cli
, fname
);
8755 if (!torture_close_connection(cli
)) {
8764 Test POSIX locks are OFD-locks.
8766 static bool run_posix_ofd_lock_test(int dummy
)
8768 static struct cli_state
*cli
;
8769 const char *fname
= "posix_file";
8770 uint16_t fnum1
= (uint16_t)-1;
8771 uint16_t fnum2
= (uint16_t)-1;
8772 bool correct
= false;
8774 TALLOC_CTX
*frame
= NULL
;
8776 frame
= talloc_stackframe();
8778 printf("Starting POSIX ofd-lock test\n");
8780 if (!torture_open_connection(&cli
, 0)) {
8785 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
8787 status
= torture_setup_unix_extensions(cli
);
8788 if (!NT_STATUS_IS_OK(status
)) {
8793 cli_setatr(cli
, fname
, 0, 0);
8794 cli_posix_unlink(cli
, fname
);
8796 /* Open the file twice. */
8797 status
= cli_posix_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
8799 if (!NT_STATUS_IS_OK(status
)) {
8800 printf("First POSIX open of %s failed\n", fname
);
8804 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum2
);
8805 if (!NT_STATUS_IS_OK(status
)) {
8806 printf("First POSIX open of %s failed\n", fname
);
8810 /* Set a 0-50 lock on fnum1. */
8811 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
8812 if (!NT_STATUS_IS_OK(status
)) {
8813 printf("POSIX lock (1) failed %s\n", nt_errstr(status
));
8817 /* Set a 60-100 lock on fnum2. */
8818 status
= cli_posix_lock(cli
, fnum2
, 60, 100, false, WRITE_LOCK
);
8819 if (!NT_STATUS_IS_OK(status
)) {
8820 printf("POSIX lock (2) failed %s\n", nt_errstr(status
));
8824 /* close fnum1 - 0-50 lock should go away. */
8825 status
= cli_close(cli
, fnum1
);
8826 if (!NT_STATUS_IS_OK(status
)) {
8827 printf("close failed (%s)\n",
8831 fnum1
= (uint16_t)-1;
8833 /* Change the lock context. */
8834 cli_setpid(cli
, cli_getpid(cli
) + 1);
8836 /* Re-open fnum1. */
8837 status
= cli_posix_open(cli
, fname
, O_RDWR
, 0, &fnum1
);
8838 if (!NT_STATUS_IS_OK(status
)) {
8839 printf("Third POSIX open of %s failed\n", fname
);
8843 /* 60-100 lock should still be there. */
8844 status
= cli_posix_lock(cli
, fnum1
, 60, 100, false, WRITE_LOCK
);
8845 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
8846 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status
));
8850 /* 0-50 lock should be gone. */
8851 status
= cli_posix_lock(cli
, fnum1
, 0, 50, false, WRITE_LOCK
);
8852 if (!NT_STATUS_IS_OK(status
)) {
8853 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status
));
8857 printf("POSIX OFD lock test passed\n");
8862 if (fnum1
!= (uint16_t)-1) {
8863 cli_close(cli
, fnum1
);
8864 fnum1
= (uint16_t)-1;
8866 if (fnum2
!= (uint16_t)-1) {
8867 cli_close(cli
, fnum2
);
8868 fnum2
= (uint16_t)-1;
8871 cli_setatr(cli
, fname
, 0, 0);
8872 cli_posix_unlink(cli
, fname
);
8874 if (!torture_close_connection(cli
)) {
8882 struct posix_blocking_state
{
8883 struct tevent_context
*ev
;
8884 struct cli_state
*cli1
;
8886 struct cli_state
*cli2
;
8892 static void posix_blocking_locked(struct tevent_req
*subreq
);
8893 static void posix_blocking_gotblocked(struct tevent_req
*subreq
);
8894 static void posix_blocking_gotecho(struct tevent_req
*subreq
);
8895 static void posix_blocking_unlocked(struct tevent_req
*subreq
);
8897 static struct tevent_req
*posix_blocking_send(
8898 TALLOC_CTX
*mem_ctx
,
8899 struct tevent_context
*ev
,
8900 struct cli_state
*cli1
,
8902 struct cli_state
*cli2
,
8905 struct tevent_req
*req
= NULL
, *subreq
= NULL
;
8906 struct posix_blocking_state
*state
= NULL
;
8908 req
= tevent_req_create(mem_ctx
, &state
, struct posix_blocking_state
);
8914 state
->fnum1
= fnum1
;
8916 state
->fnum2
= fnum2
;
8918 subreq
= cli_posix_lock_send(
8927 if (tevent_req_nomem(subreq
, req
)) {
8928 return tevent_req_post(req
, ev
);
8930 tevent_req_set_callback(subreq
, posix_blocking_locked
, req
);
8934 static void posix_blocking_locked(struct tevent_req
*subreq
)
8936 struct tevent_req
*req
= tevent_req_callback_data(
8937 subreq
, struct tevent_req
);
8938 struct posix_blocking_state
*state
= tevent_req_data(
8939 req
, struct posix_blocking_state
);
8942 status
= cli_posix_lock_recv(subreq
);
8943 TALLOC_FREE(subreq
);
8944 if (tevent_req_nterror(req
, status
)) {
8948 subreq
= cli_posix_lock_send(
8957 if (tevent_req_nomem(subreq
, req
)) {
8960 tevent_req_set_callback(subreq
, posix_blocking_gotblocked
, req
);
8962 /* Make sure the blocking request is delivered */
8963 subreq
= cli_echo_send(
8968 (DATA_BLOB
) { .data
= (uint8_t *)state
, .length
= 1 });
8969 if (tevent_req_nomem(subreq
, req
)) {
8972 tevent_req_set_callback(subreq
, posix_blocking_gotecho
, req
);
8975 static void posix_blocking_gotblocked(struct tevent_req
*subreq
)
8977 struct tevent_req
*req
= tevent_req_callback_data(
8978 subreq
, struct tevent_req
);
8979 struct posix_blocking_state
*state
= tevent_req_data(
8980 req
, struct posix_blocking_state
);
8983 status
= cli_posix_lock_recv(subreq
);
8984 TALLOC_FREE(subreq
);
8985 if (tevent_req_nterror(req
, status
)) {
8988 if (!state
->gotecho
) {
8989 printf("blocked req got through before echo\n");
8990 tevent_req_nterror(req
, NT_STATUS_INVALID_LOCK_SEQUENCE
);
8993 tevent_req_done(req
);
8996 static void posix_blocking_gotecho(struct tevent_req
*subreq
)
8998 struct tevent_req
*req
= tevent_req_callback_data(
8999 subreq
, struct tevent_req
);
9000 struct posix_blocking_state
*state
= tevent_req_data(
9001 req
, struct posix_blocking_state
);
9004 status
= cli_echo_recv(subreq
);
9005 TALLOC_FREE(subreq
);
9006 if (tevent_req_nterror(req
, status
)) {
9009 if (state
->gotblocked
) {
9010 printf("blocked req got through before echo\n");
9011 tevent_req_nterror(req
, NT_STATUS_INVALID_LOCK_SEQUENCE
);
9014 state
->gotecho
= true;
9016 subreq
= cli_posix_lock_send(
9025 if (tevent_req_nomem(subreq
, req
)) {
9028 tevent_req_set_callback(subreq
, posix_blocking_unlocked
, req
);
9031 static void posix_blocking_unlocked(struct tevent_req
*subreq
)
9033 struct tevent_req
*req
= tevent_req_callback_data(
9034 subreq
, struct tevent_req
);
9037 status
= cli_posix_lock_recv(subreq
);
9038 TALLOC_FREE(subreq
);
9039 if (tevent_req_nterror(req
, status
)) {
9042 /* tevent_req_done in posix_blocking_gotlocked */
9045 static NTSTATUS
posix_blocking_recv(struct tevent_req
*req
)
9047 return tevent_req_simple_recv_ntstatus(req
);
9050 static bool run_posix_blocking_lock(int dummy
)
9052 struct tevent_context
*ev
= NULL
;
9053 struct cli_state
*cli1
= NULL
, *cli2
= NULL
;
9054 const char *fname
= "posix_blocking";
9055 uint16_t fnum1
= UINT16_MAX
, fnum2
= UINT16_MAX
;
9056 struct tevent_req
*req
= NULL
;
9061 printf("Starting posix blocking lock test\n");
9063 ev
= samba_tevent_context_init(NULL
);
9068 ok
= torture_open_connection(&cli1
, 0);
9072 ok
= torture_open_connection(&cli2
, 0);
9077 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
9079 status
= torture_setup_unix_extensions(cli1
);
9080 if (!NT_STATUS_IS_OK(status
)) {
9084 status
= torture_setup_unix_extensions(cli2
);
9085 if (!NT_STATUS_IS_OK(status
)) {
9089 cli_setatr(cli1
, fname
, 0, 0);
9090 cli_posix_unlink(cli1
, fname
);
9092 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
9094 if (!NT_STATUS_IS_OK(status
)) {
9095 printf("First POSIX open of %s failed: %s\n",
9101 status
= cli_posix_open(cli2
, fname
, O_RDWR
, 0600, &fnum2
);
9102 if (!NT_STATUS_IS_OK(status
)) {
9103 printf("Second POSIX open of %s failed: %s\n",
9109 req
= posix_blocking_send(ev
, ev
, cli1
, fnum1
, cli2
, fnum2
);
9111 printf("cli_posix_blocking failed\n");
9115 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
9117 printf("tevent_req_poll_ntstatus failed: %s\n",
9121 status
= posix_blocking_recv(req
);
9123 if (!NT_STATUS_IS_OK(status
)) {
9124 printf("posix_blocking_recv returned %s\n",
9132 if (fnum1
!= UINT16_MAX
) {
9133 cli_close(cli1
, fnum1
);
9136 if (fnum2
!= UINT16_MAX
) {
9137 cli_close(cli2
, fnum2
);
9142 cli_setatr(cli1
, fname
, 0, 0);
9143 cli_posix_unlink(cli1
, fname
);
9149 ok
&= torture_close_connection(cli1
);
9153 ok
&= torture_close_connection(cli2
);
9165 Test POSIX mkdir is case-sensitive.
9167 static bool run_posix_mkdir_test(int dummy
)
9169 static struct cli_state
*cli
;
9170 const char *fname_foo
= "POSIX_foo";
9171 const char *fname_foo_Foo
= "POSIX_foo/Foo";
9172 const char *fname_foo_foo
= "POSIX_foo/foo";
9173 const char *fname_Foo
= "POSIX_Foo";
9174 const char *fname_Foo_Foo
= "POSIX_Foo/Foo";
9175 const char *fname_Foo_foo
= "POSIX_Foo/foo";
9176 bool correct
= false;
9178 TALLOC_CTX
*frame
= NULL
;
9179 uint16_t fnum
= (uint16_t)-1;
9181 frame
= talloc_stackframe();
9183 printf("Starting POSIX mkdir test\n");
9185 if (!torture_open_connection(&cli
, 0)) {
9190 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9192 status
= torture_setup_unix_extensions(cli
);
9193 if (!NT_STATUS_IS_OK(status
)) {
9198 cli_posix_rmdir(cli
, fname_foo_foo
);
9199 cli_posix_rmdir(cli
, fname_foo_Foo
);
9200 cli_posix_rmdir(cli
, fname_foo
);
9202 cli_posix_rmdir(cli
, fname_Foo_foo
);
9203 cli_posix_rmdir(cli
, fname_Foo_Foo
);
9204 cli_posix_rmdir(cli
, fname_Foo
);
9207 * Create a file POSIX_foo then try
9208 * and use it in a directory path by
9209 * doing mkdir POSIX_foo/bar.
9210 * The mkdir should fail with
9211 * NT_STATUS_OBJECT_PATH_NOT_FOUND
9214 status
= cli_posix_open(cli
,
9219 if (!NT_STATUS_IS_OK(status
)) {
9220 printf("cli_posix_open of %s failed error %s\n",
9226 status
= cli_posix_mkdir(cli
, fname_foo_foo
, 0777);
9227 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
9228 printf("cli_posix_mkdir of %s should fail with "
9229 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
9236 status
= cli_close(cli
, fnum
);
9237 if (!NT_STATUS_IS_OK(status
)) {
9238 printf("cli_close failed %s\n", nt_errstr(status
));
9241 fnum
= (uint16_t)-1;
9243 status
= cli_posix_unlink(cli
, fname_foo
);
9244 if (!NT_STATUS_IS_OK(status
)) {
9245 printf("cli_posix_unlink of %s failed error %s\n",
9252 * Now we've deleted everything, posix_mkdir, posix_rmdir,
9253 * posix_open, posix_unlink, on
9254 * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
9255 * not silently create POSIX_foo/foo.
9258 status
= cli_posix_mkdir(cli
, fname_foo_foo
, 0777);
9259 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
9260 printf("cli_posix_mkdir of %s should fail with "
9261 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
9268 status
= cli_posix_rmdir(cli
, fname_foo_foo
);
9269 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
9270 printf("cli_posix_rmdir of %s should fail with "
9271 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
9278 status
= cli_posix_open(cli
,
9283 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
9284 printf("cli_posix_open of %s should fail with "
9285 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
9292 status
= cli_posix_unlink(cli
, fname_foo_foo
);
9293 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
9294 printf("cli_posix_unlink of %s should fail with "
9295 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
9302 status
= cli_posix_mkdir(cli
, fname_foo
, 0777);
9303 if (!NT_STATUS_IS_OK(status
)) {
9304 printf("cli_posix_mkdir of %s failed\n", fname_foo
);
9308 status
= cli_posix_mkdir(cli
, fname_Foo
, 0777);
9309 if (!NT_STATUS_IS_OK(status
)) {
9310 printf("cli_posix_mkdir of %s failed\n", fname_Foo
);
9314 status
= cli_posix_mkdir(cli
, fname_foo_foo
, 0777);
9315 if (!NT_STATUS_IS_OK(status
)) {
9316 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo
);
9320 status
= cli_posix_mkdir(cli
, fname_foo_Foo
, 0777);
9321 if (!NT_STATUS_IS_OK(status
)) {
9322 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo
);
9326 status
= cli_posix_mkdir(cli
, fname_Foo_foo
, 0777);
9327 if (!NT_STATUS_IS_OK(status
)) {
9328 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo
);
9332 status
= cli_posix_mkdir(cli
, fname_Foo_Foo
, 0777);
9333 if (!NT_STATUS_IS_OK(status
)) {
9334 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo
);
9338 printf("POSIX mkdir test passed\n");
9343 if (fnum
!= (uint16_t)-1) {
9344 cli_close(cli
, fnum
);
9345 fnum
= (uint16_t)-1;
9348 cli_posix_rmdir(cli
, fname_foo_foo
);
9349 cli_posix_rmdir(cli
, fname_foo_Foo
);
9350 cli_posix_rmdir(cli
, fname_foo
);
9352 cli_posix_rmdir(cli
, fname_Foo_foo
);
9353 cli_posix_rmdir(cli
, fname_Foo_Foo
);
9354 cli_posix_rmdir(cli
, fname_Foo
);
9356 if (!torture_close_connection(cli
)) {
9364 struct posix_acl_oplock_state
{
9365 struct tevent_context
*ev
;
9366 struct cli_state
*cli
;
9372 static void posix_acl_oplock_got_break(struct tevent_req
*req
)
9374 struct posix_acl_oplock_state
*state
= tevent_req_callback_data(
9375 req
, struct posix_acl_oplock_state
);
9380 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
9382 if (!NT_STATUS_IS_OK(status
)) {
9383 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
9387 *state
->got_break
= true;
9389 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
9392 printf("cli_oplock_ack_send failed\n");
9397 static void posix_acl_oplock_got_acl(struct tevent_req
*req
)
9399 struct posix_acl_oplock_state
*state
= tevent_req_callback_data(
9400 req
, struct posix_acl_oplock_state
);
9401 size_t ret_size
= 0;
9402 char *ret_data
= NULL
;
9404 state
->status
= cli_posix_getacl_recv(req
,
9409 if (!NT_STATUS_IS_OK(state
->status
)) {
9410 printf("cli_posix_getacl_recv returned %s\n",
9411 nt_errstr(state
->status
));
9413 *state
->acl_ret
= true;
9416 static bool run_posix_acl_oplock_test(int dummy
)
9418 struct tevent_context
*ev
;
9419 struct cli_state
*cli1
, *cli2
;
9420 struct tevent_req
*oplock_req
, *getacl_req
;
9421 const char *fname
= "posix_acl_oplock";
9423 int saved_use_oplocks
= use_oplocks
;
9425 bool correct
= true;
9426 bool got_break
= false;
9427 bool acl_ret
= false;
9429 struct posix_acl_oplock_state
*state
;
9431 printf("starting posix_acl_oplock test\n");
9433 if (!torture_open_connection(&cli1
, 0)) {
9434 use_level_II_oplocks
= false;
9435 use_oplocks
= saved_use_oplocks
;
9439 if (!torture_open_connection(&cli2
, 1)) {
9440 use_level_II_oplocks
= false;
9441 use_oplocks
= saved_use_oplocks
;
9445 /* Setup posix on cli2 only. */
9446 status
= torture_setup_unix_extensions(cli2
);
9447 if (!NT_STATUS_IS_OK(status
)) {
9451 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
9452 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
9454 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9456 /* Create the file on the Windows connection. */
9457 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
9459 if (!NT_STATUS_IS_OK(status
)) {
9460 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
9464 status
= cli_close(cli1
, fnum
);
9465 if (!NT_STATUS_IS_OK(status
)) {
9466 printf("close1 failed (%s)\n", nt_errstr(status
));
9470 cli1
->use_oplocks
= true;
9472 /* Open with oplock. */
9473 status
= cli_ntcreate(cli1
,
9477 FILE_ATTRIBUTE_NORMAL
,
9478 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
9485 if (!NT_STATUS_IS_OK(status
)) {
9486 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
9490 ev
= samba_tevent_context_init(talloc_tos());
9492 printf("tevent_context_init failed\n");
9496 state
= talloc_zero(ev
, struct posix_acl_oplock_state
);
9497 if (state
== NULL
) {
9498 printf("talloc failed\n");
9503 state
->got_break
= &got_break
;
9504 state
->acl_ret
= &acl_ret
;
9506 oplock_req
= cli_smb_oplock_break_waiter_send(
9507 talloc_tos(), ev
, cli1
);
9508 if (oplock_req
== NULL
) {
9509 printf("cli_smb_oplock_break_waiter_send failed\n");
9512 tevent_req_set_callback(oplock_req
, posix_acl_oplock_got_break
, state
);
9514 /* Get ACL on POSIX connection - should break oplock. */
9515 getacl_req
= cli_posix_getacl_send(talloc_tos(),
9519 if (getacl_req
== NULL
) {
9520 printf("cli_posix_getacl_send failed\n");
9523 tevent_req_set_callback(getacl_req
, posix_acl_oplock_got_acl
, state
);
9525 while (!got_break
|| !acl_ret
) {
9527 ret
= tevent_loop_once(ev
);
9529 printf("tevent_loop_once failed: %s\n",
9535 if (!NT_STATUS_IS_OK(state
->status
)) {
9536 printf("getacl failed (%s)\n", nt_errstr(state
->status
));
9540 status
= cli_close(cli1
, fnum
);
9541 if (!NT_STATUS_IS_OK(status
)) {
9542 printf("close2 failed (%s)\n", nt_errstr(status
));
9546 status
= cli_unlink(cli1
,
9548 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9549 if (!NT_STATUS_IS_OK(status
)) {
9550 printf("unlink failed (%s)\n", nt_errstr(status
));
9554 if (!torture_close_connection(cli1
)) {
9557 if (!torture_close_connection(cli2
)) {
9565 printf("finished posix acl oplock test\n");
9570 static bool run_posix_acl_shareroot_test(int dummy
)
9572 struct cli_state
*cli
;
9574 bool correct
= false;
9575 char *posix_acl
= NULL
;
9576 size_t posix_acl_len
= 0;
9577 uint16_t num_file_acls
= 0;
9578 uint16_t num_dir_acls
= 0;
9580 uint32_t expected_size
= 0;
9581 bool got_user
= false;
9582 bool got_group
= false;
9583 bool got_other
= false;
9584 TALLOC_CTX
*frame
= NULL
;
9586 frame
= talloc_stackframe();
9588 printf("starting posix_acl_shareroot test\n");
9590 if (!torture_open_connection(&cli
, 0)) {
9595 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9597 status
= torture_setup_unix_extensions(cli
);
9598 if (!NT_STATUS_IS_OK(status
)) {
9599 printf("Failed to setup unix extensions\n");
9603 /* Get the POSIX ACL on the root of the share. */
9604 status
= cli_posix_getacl(cli
,
9610 if (!NT_STATUS_IS_OK(status
)) {
9611 printf("cli_posix_getacl of '.' failed (%s)\n",
9616 if (posix_acl_len
< 6 ||
9617 SVAL(posix_acl
,0) != SMB_POSIX_ACL_VERSION
) {
9618 printf("getfacl ., unknown POSIX acl version %u.\n",
9619 (unsigned int)CVAL(posix_acl
,0) );
9623 num_file_acls
= SVAL(posix_acl
,2);
9624 num_dir_acls
= SVAL(posix_acl
,4);
9625 expected_size
= SMB_POSIX_ACL_HEADER_SIZE
+
9626 SMB_POSIX_ACL_ENTRY_SIZE
*
9627 (num_file_acls
+num_dir_acls
);
9629 if (posix_acl_len
!= expected_size
) {
9630 printf("incorrect POSIX acl buffer size "
9631 "(should be %u, was %u).\n",
9632 (unsigned int)expected_size
,
9633 (unsigned int)posix_acl_len
);
9638 * We don't need to know what the ACL's are
9639 * we just need to know we have at least 3
9640 * file entries (u,g,o).
9643 for (i
= 0; i
< num_file_acls
; i
++) {
9644 unsigned char tagtype
=
9646 SMB_POSIX_ACL_HEADER_SIZE
+
9647 (i
*SMB_POSIX_ACL_ENTRY_SIZE
));
9650 case SMB_POSIX_ACL_USER_OBJ
:
9653 case SMB_POSIX_ACL_GROUP_OBJ
:
9656 case SMB_POSIX_ACL_OTHER
:
9665 printf("Missing user entry\n");
9670 printf("Missing group entry\n");
9675 printf("Missing other entry\n");
9683 if (!torture_close_connection(cli
)) {
9687 printf("finished posix acl shareroot test\n");
9693 static uint32_t open_attrs_table
[] = {
9694 FILE_ATTRIBUTE_NORMAL
,
9695 FILE_ATTRIBUTE_ARCHIVE
,
9696 FILE_ATTRIBUTE_READONLY
,
9697 FILE_ATTRIBUTE_HIDDEN
,
9698 FILE_ATTRIBUTE_SYSTEM
,
9700 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
9701 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
9702 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
9703 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
9704 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
9705 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
9707 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
9708 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
9709 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
9710 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
9713 struct trunc_open_results
{
9716 uint32_t trunc_attr
;
9717 uint32_t result_attr
;
9720 static struct trunc_open_results attr_results
[] = {
9721 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
9722 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
9723 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
9724 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
9725 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
9726 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
9727 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9728 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9729 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
9730 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9731 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9732 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
9733 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9734 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9735 { 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
},
9736 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9737 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9738 { 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
},
9739 { 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
},
9740 { 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
},
9741 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9742 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
9743 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
9744 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9745 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
9746 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
9749 static bool run_openattrtest(int dummy
)
9751 static struct cli_state
*cli1
;
9752 const char *fname
= "\\openattr.file";
9754 bool correct
= True
;
9756 unsigned int i
, j
, k
, l
;
9759 printf("starting open attr test\n");
9761 if (!torture_open_connection(&cli1
, 0)) {
9765 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
9767 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32_t); i
++) {
9768 cli_setatr(cli1
, fname
, 0, 0);
9769 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9771 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
9772 open_attrs_table
[i
], FILE_SHARE_NONE
,
9773 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
9774 if (!NT_STATUS_IS_OK(status
)) {
9775 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
9779 status
= cli_close(cli1
, fnum1
);
9780 if (!NT_STATUS_IS_OK(status
)) {
9781 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
9785 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32_t); j
++) {
9786 status
= cli_ntcreate(cli1
, fname
, 0,
9787 FILE_READ_DATA
|FILE_WRITE_DATA
,
9788 open_attrs_table
[j
],
9789 FILE_SHARE_NONE
, FILE_OVERWRITE
,
9790 0, 0, &fnum1
, NULL
);
9791 if (!NT_STATUS_IS_OK(status
)) {
9792 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
9793 if (attr_results
[l
].num
== k
) {
9794 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
9795 k
, open_attrs_table
[i
],
9796 open_attrs_table
[j
],
9797 fname
, NT_STATUS_V(status
), nt_errstr(status
));
9802 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
9803 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
9804 k
, open_attrs_table
[i
], open_attrs_table
[j
],
9809 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
9815 status
= cli_close(cli1
, fnum1
);
9816 if (!NT_STATUS_IS_OK(status
)) {
9817 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
9821 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
9822 if (!NT_STATUS_IS_OK(status
)) {
9823 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
9828 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
9829 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
9832 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
9833 if (attr_results
[l
].num
== k
) {
9834 if (attr
!= attr_results
[l
].result_attr
||
9835 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
9836 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
9837 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
9838 open_attrs_table
[i
],
9839 open_attrs_table
[j
],
9841 attr_results
[l
].result_attr
);
9851 cli_setatr(cli1
, fname
, 0, 0);
9852 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9854 printf("open attr test %s.\n", correct
? "passed" : "failed");
9856 if (!torture_close_connection(cli1
)) {
9862 static NTSTATUS
list_fn(struct file_info
*finfo
,
9863 const char *name
, void *state
)
9865 int *matched
= (int *)state
;
9866 if (matched
!= NULL
) {
9869 return NT_STATUS_OK
;
9873 test directory listing speed
9875 static bool run_dirtest(int dummy
)
9878 static struct cli_state
*cli
;
9880 struct timeval core_start
;
9881 bool correct
= True
;
9884 printf("starting directory test\n");
9886 if (!torture_open_connection(&cli
, 0)) {
9890 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
9893 for (i
=0;i
<torture_numops
;i
++) {
9895 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
9896 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
9897 fprintf(stderr
,"Failed to open %s\n", fname
);
9900 cli_close(cli
, fnum
);
9903 core_start
= timeval_current();
9906 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
9907 printf("Matched %d\n", matched
);
9910 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
9911 printf("Matched %d\n", matched
);
9914 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
9915 printf("Matched %d\n", matched
);
9917 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
9920 for (i
=0;i
<torture_numops
;i
++) {
9922 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
9923 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
9926 if (!torture_close_connection(cli
)) {
9930 printf("finished dirtest\n");
9935 static NTSTATUS
del_fn(struct file_info
*finfo
, const char *mask
,
9938 struct cli_state
*pcli
= (struct cli_state
*)state
;
9940 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
9942 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
9943 return NT_STATUS_OK
;
9945 if (finfo
->attr
& FILE_ATTRIBUTE_DIRECTORY
) {
9946 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
9947 printf("del_fn: failed to rmdir %s\n,", fname
);
9949 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
9950 printf("del_fn: failed to unlink %s\n,", fname
);
9952 return NT_STATUS_OK
;
9957 send a raw ioctl - used by the torture code
9959 static NTSTATUS
cli_raw_ioctl(struct cli_state
*cli
,
9967 PUSH_LE_U16(vwv
+ 0, 0, fnum
);
9968 PUSH_LE_U16(vwv
+ 1, 0, code
>> 16);
9969 PUSH_LE_U16(vwv
+ 2, 0, (code
& 0xFFFF));
9971 status
= cli_smb(talloc_tos(),
9985 if (!NT_STATUS_IS_OK(status
)) {
9988 *blob
= data_blob_null
;
9989 return NT_STATUS_OK
;
9993 sees what IOCTLs are supported
9995 bool torture_ioctl_test(int dummy
)
9997 static struct cli_state
*cli
;
9998 uint16_t device
, function
;
10000 const char *fname
= "\\ioctl.dat";
10004 if (!torture_open_connection(&cli
, 0)) {
10008 printf("starting ioctl test\n");
10010 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
10012 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
10013 if (!NT_STATUS_IS_OK(status
)) {
10014 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
10018 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
10019 printf("ioctl device info: %s\n", nt_errstr(status
));
10021 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
10022 printf("ioctl job info: %s\n", nt_errstr(status
));
10024 for (device
=0;device
<0x100;device
++) {
10025 printf("ioctl test with device = 0x%x\n", device
);
10026 for (function
=0;function
<0x100;function
++) {
10027 uint32_t code
= (device
<<16) | function
;
10029 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
10031 if (NT_STATUS_IS_OK(status
)) {
10032 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
10034 data_blob_free(&blob
);
10039 if (!torture_close_connection(cli
)) {
10048 tries variants of chkpath
10050 bool torture_chkpath_test(int dummy
)
10052 static struct cli_state
*cli
;
10057 if (!torture_open_connection(&cli
, 0)) {
10061 printf("starting chkpath test\n");
10063 /* cleanup from an old run */
10064 torture_deltree(cli
, "\\chkpath.dir");
10066 status
= cli_mkdir(cli
, "\\chkpath.dir");
10067 if (!NT_STATUS_IS_OK(status
)) {
10068 printf("mkdir1 failed : %s\n", nt_errstr(status
));
10072 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
10073 if (!NT_STATUS_IS_OK(status
)) {
10074 printf("mkdir2 failed : %s\n", nt_errstr(status
));
10078 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
10080 if (!NT_STATUS_IS_OK(status
)) {
10081 printf("open1 failed (%s)\n", nt_errstr(status
));
10084 cli_close(cli
, fnum
);
10086 status
= cli_chkpath(cli
, "\\chkpath.dir");
10087 if (!NT_STATUS_IS_OK(status
)) {
10088 printf("chkpath1 failed: %s\n", nt_errstr(status
));
10092 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
10093 if (!NT_STATUS_IS_OK(status
)) {
10094 printf("chkpath2 failed: %s\n", nt_errstr(status
));
10098 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
10099 if (!NT_STATUS_IS_OK(status
)) {
10100 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
10101 NT_STATUS_NOT_A_DIRECTORY
);
10103 printf("* chkpath on a file should fail\n");
10107 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
10108 if (!NT_STATUS_IS_OK(status
)) {
10109 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
10110 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
10112 printf("* chkpath on a non existent file should fail\n");
10116 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
10117 if (!NT_STATUS_IS_OK(status
)) {
10118 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
10119 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
10121 printf("* chkpath on a non existent component should fail\n");
10125 torture_deltree(cli
, "\\chkpath.dir");
10127 if (!torture_close_connection(cli
)) {
10134 static bool run_eatest(int dummy
)
10136 static struct cli_state
*cli
;
10137 const char *fname
= "\\eatest.txt";
10138 bool correct
= True
;
10141 struct ea_struct
*ea_list
= NULL
;
10142 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
10145 printf("starting eatest\n");
10147 if (!torture_open_connection(&cli
, 0)) {
10148 talloc_destroy(mem_ctx
);
10152 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
10154 status
= cli_ntcreate(cli
, fname
, 0,
10155 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
10156 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
10157 0x4044, 0, &fnum
, NULL
);
10158 if (!NT_STATUS_IS_OK(status
)) {
10159 printf("open failed - %s\n", nt_errstr(status
));
10160 talloc_destroy(mem_ctx
);
10164 for (i
= 0; i
< 10; i
++) {
10165 fstring ea_name
, ea_val
;
10167 slprintf(ea_name
, sizeof(ea_name
), "EA_%zu", i
);
10168 memset(ea_val
, (char)i
+1, i
+1);
10169 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
10170 if (!NT_STATUS_IS_OK(status
)) {
10171 printf("ea_set of name %s failed - %s\n", ea_name
,
10172 nt_errstr(status
));
10173 talloc_destroy(mem_ctx
);
10178 cli_close(cli
, fnum
);
10179 for (i
= 0; i
< 10; i
++) {
10180 fstring ea_name
, ea_val
;
10182 slprintf(ea_name
, sizeof(ea_name
), "EA_%zu", i
+10);
10183 memset(ea_val
, (char)i
+1, i
+1);
10184 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
10185 if (!NT_STATUS_IS_OK(status
)) {
10186 printf("ea_set of name %s failed - %s\n", ea_name
,
10187 nt_errstr(status
));
10188 talloc_destroy(mem_ctx
);
10193 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
10194 if (!NT_STATUS_IS_OK(status
)) {
10195 printf("ea_get list failed - %s\n", nt_errstr(status
));
10199 printf("num_eas = %d\n", (int)num_eas
);
10201 if (num_eas
!= 20) {
10202 printf("Should be 20 EA's stored... failing.\n");
10206 for (i
= 0; i
< num_eas
; i
++) {
10207 printf("%zu: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
10208 dump_data(0, ea_list
[i
].value
.data
,
10209 ea_list
[i
].value
.length
);
10212 /* Setting EA's to zero length deletes them. Test this */
10213 printf("Now deleting all EA's - case independent....\n");
10216 cli_set_ea_path(cli
, fname
, "", "", 0);
10218 for (i
= 0; i
< 20; i
++) {
10220 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
10221 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
10222 if (!NT_STATUS_IS_OK(status
)) {
10223 printf("ea_set of name %s failed - %s\n", ea_name
,
10224 nt_errstr(status
));
10225 talloc_destroy(mem_ctx
);
10231 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
10232 if (!NT_STATUS_IS_OK(status
)) {
10233 printf("ea_get list failed - %s\n", nt_errstr(status
));
10237 printf("num_eas = %d\n", (int)num_eas
);
10238 for (i
= 0; i
< num_eas
; i
++) {
10239 printf("%zu: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
10240 dump_data(0, ea_list
[i
].value
.data
,
10241 ea_list
[i
].value
.length
);
10244 if (num_eas
!= 0) {
10245 printf("deleting EA's failed.\n");
10249 /* Try and delete a non existent EA. */
10250 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
10251 if (!NT_STATUS_IS_OK(status
)) {
10252 printf("deleting non-existent EA 'foo' should succeed. %s\n",
10253 nt_errstr(status
));
10257 talloc_destroy(mem_ctx
);
10258 if (!torture_close_connection(cli
)) {
10265 static bool run_dirtest1(int dummy
)
10268 static struct cli_state
*cli
;
10271 bool correct
= True
;
10273 printf("starting directory test\n");
10275 if (!torture_open_connection(&cli
, 0)) {
10279 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
10281 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
10282 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
10283 cli_rmdir(cli
, "\\LISTDIR");
10284 cli_mkdir(cli
, "\\LISTDIR");
10286 /* Create 1000 files and 1000 directories. */
10287 for (i
=0;i
<1000;i
++) {
10289 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
10290 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
10291 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
10292 0, 0, &fnum
, NULL
))) {
10293 fprintf(stderr
,"Failed to open %s\n", fname
);
10296 cli_close(cli
, fnum
);
10298 for (i
=0;i
<1000;i
++) {
10300 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
10301 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
10302 fprintf(stderr
,"Failed to open %s\n", fname
);
10307 /* Now ensure that doing an old list sees both files and directories. */
10309 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
10310 printf("num_seen = %d\n", num_seen
);
10311 /* We should see 100 files + 1000 directories + . and .. */
10312 if (num_seen
!= 2002)
10315 /* Ensure if we have the "must have" bits we only see the
10316 * relevant entries.
10319 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
10320 printf("num_seen = %d\n", num_seen
);
10321 if (num_seen
!= 1002)
10325 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
10326 printf("num_seen = %d\n", num_seen
);
10327 if (num_seen
!= 1000)
10330 /* Delete everything. */
10331 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
10332 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
10333 cli_rmdir(cli
, "\\LISTDIR");
10336 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
10337 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
10338 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
10341 if (!torture_close_connection(cli
)) {
10345 printf("finished dirtest1\n");
10350 static bool run_error_map_extract(int dummy
) {
10352 static struct cli_state
*c_dos
;
10353 static struct cli_state
*c_nt
;
10361 NTSTATUS nt_status
;
10365 /* NT-Error connection */
10367 disable_spnego
= true;
10368 if (!(c_nt
= open_nbt_connection())) {
10369 disable_spnego
= false;
10372 disable_spnego
= false;
10374 status
= smbXcli_negprot(c_nt
->conn
,
10382 if (!NT_STATUS_IS_OK(status
)) {
10383 printf("%s rejected the NT-error negprot (%s)\n", host
,
10384 nt_errstr(status
));
10385 cli_shutdown(c_nt
);
10389 status
= cli_session_setup_anon(c_nt
);
10390 if (!NT_STATUS_IS_OK(status
)) {
10391 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
10395 /* DOS-Error connection */
10397 disable_spnego
= true;
10398 force_dos_errors
= true;
10399 if (!(c_dos
= open_nbt_connection())) {
10400 disable_spnego
= false;
10401 force_dos_errors
= false;
10404 disable_spnego
= false;
10405 force_dos_errors
= false;
10407 status
= smbXcli_negprot(c_dos
->conn
,
10414 if (!NT_STATUS_IS_OK(status
)) {
10415 printf("%s rejected the DOS-error negprot (%s)\n", host
,
10416 nt_errstr(status
));
10417 cli_shutdown(c_dos
);
10421 status
= cli_session_setup_anon(c_dos
);
10422 if (!NT_STATUS_IS_OK(status
)) {
10423 printf("%s rejected the DOS-error initial session setup (%s)\n",
10424 host
, nt_errstr(status
));
10428 c_nt
->map_dos_errors
= false;
10429 c_dos
->map_dos_errors
= false;
10431 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
10432 struct cli_credentials
*user_creds
= NULL
;
10434 fstr_sprintf(user
, "%X", error
);
10436 user_creds
= cli_session_creds_init(talloc_tos(),
10441 false, /* use_kerberos */
10442 false, /* fallback_after_kerberos */
10443 false, /* use_ccache */
10444 false); /* password_is_nt_hash */
10445 if (user_creds
== NULL
) {
10446 printf("cli_session_creds_init(%s) failed\n", user
);
10450 status
= cli_session_setup_creds(c_nt
, user_creds
);
10451 if (NT_STATUS_IS_OK(status
)) {
10452 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
10455 /* Case #1: 32-bit NT errors */
10456 if (!NT_STATUS_IS_DOS(status
)) {
10457 nt_status
= status
;
10459 printf("/** Dos error on NT connection! (%s) */\n",
10460 nt_errstr(status
));
10461 nt_status
= NT_STATUS(0xc0000000);
10464 status
= cli_session_setup_creds(c_dos
, user_creds
);
10465 if (NT_STATUS_IS_OK(status
)) {
10466 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
10469 /* Case #1: 32-bit NT errors */
10470 if (NT_STATUS_IS_DOS(status
)) {
10471 printf("/** NT error on DOS connection! (%s) */\n",
10472 nt_errstr(status
));
10473 errnum
= errclass
= 0;
10475 errclass
= NT_STATUS_DOS_CLASS(status
);
10476 errnum
= NT_STATUS_DOS_CODE(status
);
10479 if (NT_STATUS_V(nt_status
) != error
) {
10480 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
10481 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
10482 get_nt_error_c_code(talloc_tos(), nt_status
));
10485 printf("\t{%s,\t%s,\t%s},\n",
10486 smb_dos_err_class(errclass
),
10487 smb_dos_err_name(errclass
, errnum
),
10488 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
10490 TALLOC_FREE(user_creds
);
10495 static bool run_sesssetup_bench(int dummy
)
10497 static struct cli_state
*c
;
10498 const char *fname
= "\\file.dat";
10503 if (!torture_open_connection(&c
, 0)) {
10507 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
10508 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
10509 FILE_DELETE_ON_CLOSE
, 0, &fnum
, NULL
);
10510 if (!NT_STATUS_IS_OK(status
)) {
10511 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
10515 for (i
=0; i
<torture_numops
; i
++) {
10516 status
= cli_session_setup_creds(c
, torture_creds
);
10517 if (!NT_STATUS_IS_OK(status
)) {
10518 d_printf("(%s) cli_session_setup_creds failed: %s\n",
10519 __location__
, nt_errstr(status
));
10523 d_printf("\r%d ", (int)cli_state_get_uid(c
));
10525 status
= cli_ulogoff(c
);
10526 if (!NT_STATUS_IS_OK(status
)) {
10527 d_printf("(%s) cli_ulogoff failed: %s\n",
10528 __location__
, nt_errstr(status
));
10536 static bool subst_test(const char *str
, const char *user
, const char *domain
,
10537 uid_t uid
, gid_t gid
, const char *expected
)
10540 bool result
= true;
10542 subst
= talloc_sub_specified(talloc_tos(), str
, user
, NULL
, domain
, uid
, gid
);
10544 if (strcmp(subst
, expected
) != 0) {
10545 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
10546 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
10551 TALLOC_FREE(subst
);
10555 static void chain1_open_completion(struct tevent_req
*req
)
10559 status
= cli_openx_recv(req
, &fnum
);
10562 d_printf("cli_openx_recv returned %s: %d\n",
10564 NT_STATUS_IS_OK(status
) ? fnum
: -1);
10567 static void chain1_write_completion(struct tevent_req
*req
)
10571 status
= cli_write_andx_recv(req
, &written
);
10574 d_printf("cli_write_andx_recv returned %s: %d\n",
10576 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
10579 static void chain1_close_completion(struct tevent_req
*req
)
10582 bool *done
= (bool *)tevent_req_callback_data_void(req
);
10584 status
= cli_close_recv(req
);
10589 d_printf("cli_close returned %s\n", nt_errstr(status
));
10592 static bool run_chain1(int dummy
)
10594 struct cli_state
*cli1
;
10595 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
10596 struct tevent_req
*reqs
[3], *smbreqs
[3];
10598 const char *str
= "foobar";
10599 const char *fname
= "\\test_chain";
10602 printf("starting chain1 test\n");
10603 if (!torture_open_connection(&cli1
, 0)) {
10607 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
10609 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
10611 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, fname
,
10612 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
10613 if (reqs
[0] == NULL
) return false;
10614 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
10617 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
10618 (const uint8_t *)str
, 0, strlen(str
)+1,
10619 smbreqs
, 1, &smbreqs
[1]);
10620 if (reqs
[1] == NULL
) return false;
10621 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
10623 reqs
[2] = cli_smb1_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
10624 if (reqs
[2] == NULL
) return false;
10625 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
10627 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
10628 if (!NT_STATUS_IS_OK(status
)) {
10633 tevent_loop_once(evt
);
10636 torture_close_connection(cli1
);
10640 static void chain2_sesssetup_completion(struct tevent_req
*req
)
10643 status
= cli_session_setup_guest_recv(req
);
10644 d_printf("sesssetup returned %s\n", nt_errstr(status
));
10647 static void chain2_tcon_completion(struct tevent_req
*req
)
10649 bool *done
= (bool *)tevent_req_callback_data_void(req
);
10651 status
= cli_tcon_andx_recv(req
);
10652 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
10656 static bool run_chain2(int dummy
)
10658 struct cli_state
*cli1
;
10659 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
10660 struct tevent_req
*reqs
[2], *smbreqs
[2];
10663 int flags
= CLI_FULL_CONNECTION_FORCE_SMB1
;
10665 printf("starting chain2 test\n");
10666 status
= cli_start_connection(talloc_tos(),
10672 SMB_SIGNING_DEFAULT
,
10674 if (!NT_STATUS_IS_OK(status
)) {
10678 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
10680 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
10682 if (reqs
[0] == NULL
) return false;
10683 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
10685 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
10686 "?????", NULL
, 0, &smbreqs
[1]);
10687 if (reqs
[1] == NULL
) return false;
10688 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
10690 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
10691 if (!NT_STATUS_IS_OK(status
)) {
10696 tevent_loop_once(evt
);
10699 torture_close_connection(cli1
);
10704 struct torture_createdel_state
{
10705 struct tevent_context
*ev
;
10706 struct cli_state
*cli
;
10709 static void torture_createdel_created(struct tevent_req
*subreq
);
10710 static void torture_createdel_closed(struct tevent_req
*subreq
);
10712 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
10713 struct tevent_context
*ev
,
10714 struct cli_state
*cli
,
10717 struct tevent_req
*req
, *subreq
;
10718 struct torture_createdel_state
*state
;
10720 req
= tevent_req_create(mem_ctx
, &state
,
10721 struct torture_createdel_state
);
10728 subreq
= cli_ntcreate_send(
10729 state
, ev
, cli
, name
, 0,
10730 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
10731 FILE_ATTRIBUTE_NORMAL
,
10732 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
10733 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
,
10734 SMB2_IMPERSONATION_IMPERSONATION
, 0);
10736 if (tevent_req_nomem(subreq
, req
)) {
10737 return tevent_req_post(req
, ev
);
10739 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
10743 static void torture_createdel_created(struct tevent_req
*subreq
)
10745 struct tevent_req
*req
= tevent_req_callback_data(
10746 subreq
, struct tevent_req
);
10747 struct torture_createdel_state
*state
= tevent_req_data(
10748 req
, struct torture_createdel_state
);
10752 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
10753 TALLOC_FREE(subreq
);
10754 if (tevent_req_nterror(req
, status
)) {
10755 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
10756 nt_errstr(status
)));
10760 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
, 0);
10761 if (tevent_req_nomem(subreq
, req
)) {
10764 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
10767 static void torture_createdel_closed(struct tevent_req
*subreq
)
10769 struct tevent_req
*req
= tevent_req_callback_data(
10770 subreq
, struct tevent_req
);
10773 status
= cli_close_recv(subreq
);
10774 if (tevent_req_nterror(req
, status
)) {
10775 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
10778 tevent_req_done(req
);
10781 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
10783 return tevent_req_simple_recv_ntstatus(req
);
10786 struct torture_createdels_state
{
10787 struct tevent_context
*ev
;
10788 struct cli_state
*cli
;
10789 const char *base_name
;
10793 struct tevent_req
**reqs
;
10796 static void torture_createdels_done(struct tevent_req
*subreq
);
10798 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
10799 struct tevent_context
*ev
,
10800 struct cli_state
*cli
,
10801 const char *base_name
,
10805 struct tevent_req
*req
;
10806 struct torture_createdels_state
*state
;
10809 req
= tevent_req_create(mem_ctx
, &state
,
10810 struct torture_createdels_state
);
10816 state
->base_name
= talloc_strdup(state
, base_name
);
10817 if (tevent_req_nomem(state
->base_name
, req
)) {
10818 return tevent_req_post(req
, ev
);
10820 state
->num_files
= MAX(num_parallel
, num_files
);
10822 state
->received
= 0;
10824 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
10825 if (tevent_req_nomem(state
->reqs
, req
)) {
10826 return tevent_req_post(req
, ev
);
10829 for (i
=0; i
<num_parallel
; i
++) {
10832 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
10834 if (tevent_req_nomem(name
, req
)) {
10835 return tevent_req_post(req
, ev
);
10837 state
->reqs
[i
] = torture_createdel_send(
10838 state
->reqs
, state
->ev
, state
->cli
, name
);
10839 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
10840 return tevent_req_post(req
, ev
);
10842 name
= talloc_move(state
->reqs
[i
], &name
);
10843 tevent_req_set_callback(state
->reqs
[i
],
10844 torture_createdels_done
, req
);
10850 static void torture_createdels_done(struct tevent_req
*subreq
)
10852 struct tevent_req
*req
= tevent_req_callback_data(
10853 subreq
, struct tevent_req
);
10854 struct torture_createdels_state
*state
= tevent_req_data(
10855 req
, struct torture_createdels_state
);
10856 size_t i
, num_parallel
= talloc_array_length(state
->reqs
);
10860 status
= torture_createdel_recv(subreq
);
10861 if (!NT_STATUS_IS_OK(status
)){
10862 DEBUG(10, ("torture_createdel_recv returned %s\n",
10863 nt_errstr(status
)));
10864 TALLOC_FREE(subreq
);
10865 tevent_req_nterror(req
, status
);
10869 for (i
=0; i
<num_parallel
; i
++) {
10870 if (subreq
== state
->reqs
[i
]) {
10874 if (i
== num_parallel
) {
10875 DEBUG(10, ("received something we did not send\n"));
10876 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
10879 TALLOC_FREE(state
->reqs
[i
]);
10881 if (state
->sent
>= state
->num_files
) {
10882 tevent_req_done(req
);
10886 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
10888 if (tevent_req_nomem(name
, req
)) {
10891 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
10893 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
10896 name
= talloc_move(state
->reqs
[i
], &name
);
10897 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
10901 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
10903 return tevent_req_simple_recv_ntstatus(req
);
10906 struct swallow_notify_state
{
10907 struct tevent_context
*ev
;
10908 struct cli_state
*cli
;
10910 uint32_t completion_filter
;
10912 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
10916 static void swallow_notify_done(struct tevent_req
*subreq
);
10918 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
10919 struct tevent_context
*ev
,
10920 struct cli_state
*cli
,
10922 uint32_t completion_filter
,
10924 bool (*fn
)(uint32_t action
,
10929 struct tevent_req
*req
, *subreq
;
10930 struct swallow_notify_state
*state
;
10932 req
= tevent_req_create(mem_ctx
, &state
,
10933 struct swallow_notify_state
);
10939 state
->fnum
= fnum
;
10940 state
->completion_filter
= completion_filter
;
10941 state
->recursive
= recursive
;
10943 state
->priv
= priv
;
10945 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
10946 0xffff, state
->completion_filter
,
10948 if (tevent_req_nomem(subreq
, req
)) {
10949 return tevent_req_post(req
, ev
);
10951 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
10955 static void swallow_notify_done(struct tevent_req
*subreq
)
10957 struct tevent_req
*req
= tevent_req_callback_data(
10958 subreq
, struct tevent_req
);
10959 struct swallow_notify_state
*state
= tevent_req_data(
10960 req
, struct swallow_notify_state
);
10962 uint32_t i
, num_changes
;
10963 struct notify_change
*changes
;
10965 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
10966 TALLOC_FREE(subreq
);
10967 if (!NT_STATUS_IS_OK(status
)) {
10968 DEBUG(10, ("cli_notify_recv returned %s\n",
10969 nt_errstr(status
)));
10970 tevent_req_nterror(req
, status
);
10974 for (i
=0; i
<num_changes
; i
++) {
10975 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
10977 TALLOC_FREE(changes
);
10979 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
10980 0xffff, state
->completion_filter
,
10982 if (tevent_req_nomem(subreq
, req
)) {
10985 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
10988 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
10990 if (DEBUGLEVEL
> 5) {
10991 d_printf("%d %s\n", (int)action
, name
);
10996 static void notify_bench_done(struct tevent_req
*req
)
10998 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
10999 *num_finished
+= 1;
11002 static bool run_notify_bench(int dummy
)
11004 const char *dname
= "\\notify-bench";
11005 struct tevent_context
*ev
;
11008 struct tevent_req
*req1
;
11009 struct tevent_req
*req2
= NULL
;
11010 int i
, num_unc_names
;
11011 int num_finished
= 0;
11013 printf("starting notify-bench test\n");
11015 if (use_multishare_conn
) {
11017 unc_list
= file_lines_load(multishare_conn_fname
,
11018 &num_unc_names
, 0, NULL
);
11019 if (!unc_list
|| num_unc_names
<= 0) {
11020 d_printf("Failed to load unc names list from '%s'\n",
11021 multishare_conn_fname
);
11024 TALLOC_FREE(unc_list
);
11029 ev
= samba_tevent_context_init(talloc_tos());
11031 d_printf("tevent_context_init failed\n");
11035 for (i
=0; i
<num_unc_names
; i
++) {
11036 struct cli_state
*cli
;
11039 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
11041 if (base_fname
== NULL
) {
11045 if (!torture_open_connection(&cli
, i
)) {
11049 status
= cli_ntcreate(cli
, dname
, 0,
11050 MAXIMUM_ALLOWED_ACCESS
,
11051 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
11053 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
11056 if (!NT_STATUS_IS_OK(status
)) {
11057 d_printf("Could not create %s: %s\n", dname
,
11058 nt_errstr(status
));
11062 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
11063 FILE_NOTIFY_CHANGE_FILE_NAME
|
11064 FILE_NOTIFY_CHANGE_DIR_NAME
|
11065 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
11066 FILE_NOTIFY_CHANGE_LAST_WRITE
,
11067 false, print_notifies
, NULL
);
11068 if (req1
== NULL
) {
11069 d_printf("Could not create notify request\n");
11073 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
11074 base_fname
, 10, torture_numops
);
11075 if (req2
== NULL
) {
11076 d_printf("Could not create createdels request\n");
11079 TALLOC_FREE(base_fname
);
11081 tevent_req_set_callback(req2
, notify_bench_done
,
11085 while (num_finished
< num_unc_names
) {
11087 ret
= tevent_loop_once(ev
);
11089 d_printf("tevent_loop_once failed\n");
11094 if (!tevent_req_poll(req2
, ev
)) {
11095 d_printf("tevent_req_poll failed\n");
11098 status
= torture_createdels_recv(req2
);
11099 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
11104 static bool run_mangle1(int dummy
)
11106 struct cli_state
*cli
;
11107 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
11112 printf("starting mangle1 test\n");
11113 if (!torture_open_connection(&cli
, 0)) {
11117 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
11119 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
11120 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
11121 0, 0, &fnum
, NULL
);
11122 if (!NT_STATUS_IS_OK(status
)) {
11123 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
11126 cli_close(cli
, fnum
);
11128 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
11129 if (!NT_STATUS_IS_OK(status
)) {
11130 d_printf("cli_qpathinfo_alt_name failed: %s\n",
11131 nt_errstr(status
));
11134 d_printf("alt_name: %s\n", alt_name
);
11136 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
11137 if (!NT_STATUS_IS_OK(status
)) {
11138 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
11139 nt_errstr(status
));
11142 cli_close(cli
, fnum
);
11144 status
= cli_qpathinfo1(cli
, alt_name
, NULL
, NULL
, NULL
, NULL
, NULL
);
11145 if (!NT_STATUS_IS_OK(status
)) {
11146 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
11147 nt_errstr(status
));
11154 static NTSTATUS
mangle_illegal_list_shortname_fn(struct file_info
*f
,
11158 if (f
->short_name
== NULL
) {
11159 return NT_STATUS_OK
;
11162 if (strlen(f
->short_name
) == 0) {
11163 return NT_STATUS_OK
;
11166 printf("unexpected shortname: %s\n", f
->short_name
);
11168 return NT_STATUS_OBJECT_NAME_INVALID
;
11171 static NTSTATUS
mangle_illegal_list_name_fn(struct file_info
*f
,
11175 char *name
= state
;
11177 printf("name: %s\n", f
->name
);
11178 fstrcpy(name
, f
->name
);
11179 return NT_STATUS_OK
;
11182 static bool run_mangle_illegal(int dummy
)
11184 struct cli_state
*cli
= NULL
;
11185 struct cli_state
*cli_posix
= NULL
;
11186 const char *fname
= "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
11187 const char *illegal_fname
= "MANGLE_ILLEGAL/foo:bar";
11188 char *mangled_path
= NULL
;
11194 printf("starting mangle-illegal test\n");
11196 if (!torture_open_connection(&cli
, 0)) {
11200 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
11202 if (!torture_open_connection(&cli_posix
, 0)) {
11206 smbXcli_conn_set_sockopt(cli_posix
->conn
, sockops
);
11208 status
= torture_setup_unix_extensions(cli_posix
);
11209 if (!NT_STATUS_IS_OK(status
)) {
11213 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
11214 status
= cli_mkdir(cli
, "\\MANGLE_ILLEGAL");
11215 if (!NT_STATUS_IS_OK(status
)) {
11216 printf("mkdir1 failed : %s\n", nt_errstr(status
));
11221 * Create a file with illegal NTFS characters and test that we
11222 * get a usable mangled name
11225 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
11226 cli_posix_unlink(cli_posix
, illegal_fname
);
11228 status
= cli_posix_open(cli_posix
, illegal_fname
, O_RDWR
|O_CREAT
|O_EXCL
,
11230 if (!NT_STATUS_IS_OK(status
)) {
11231 printf("POSIX create of %s failed (%s)\n",
11232 illegal_fname
, nt_errstr(status
));
11236 status
= cli_close(cli_posix
, fnum
);
11237 if (!NT_STATUS_IS_OK(status
)) {
11238 printf("close failed (%s)\n", nt_errstr(status
));
11242 status
= cli_list(cli
, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn
, &name
);
11243 if (!NT_STATUS_IS_OK(status
)) {
11244 d_printf("cli_list failed: %s\n", nt_errstr(status
));
11248 mangled_path
= talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name
);
11249 if (mangled_path
== NULL
) {
11253 status
= cli_openx(cli
, mangled_path
, O_RDONLY
, DENY_NONE
, &fnum
);
11254 if (!NT_STATUS_IS_OK(status
)) {
11255 d_printf("cli_openx(%s) failed: %s\n", mangled_path
, nt_errstr(status
));
11256 TALLOC_FREE(mangled_path
);
11259 TALLOC_FREE(mangled_path
);
11260 cli_close(cli
, fnum
);
11262 cli_setatr(cli_posix
, illegal_fname
, 0, 0);
11263 cli_posix_unlink(cli_posix
, illegal_fname
);
11266 * Create a file with a long name and check that we got *no* short name.
11269 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
11270 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
11271 0, 0, &fnum
, NULL
);
11272 if (!NT_STATUS_IS_OK(status
)) {
11273 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
11276 cli_close(cli
, fnum
);
11278 status
= cli_list(cli
, fname
, 0, mangle_illegal_list_shortname_fn
, &alt_name
);
11279 if (!NT_STATUS_IS_OK(status
)) {
11280 d_printf("cli_list failed\n");
11284 cli_unlink(cli
, fname
, 0);
11285 cli_rmdir(cli
, "\\MANGLE_ILLEGAL");
11287 if (!torture_close_connection(cli_posix
)) {
11291 if (!torture_close_connection(cli
)) {
11298 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
11300 size_t *to_pull
= (size_t *)priv
;
11301 size_t thistime
= *to_pull
;
11303 thistime
= MIN(thistime
, n
);
11304 if (thistime
== 0) {
11308 memset(buf
, 0, thistime
);
11309 *to_pull
-= thistime
;
11313 static bool run_windows_write(int dummy
)
11315 struct cli_state
*cli1
;
11319 const char *fname
= "\\writetest.txt";
11320 struct timeval start_time
;
11325 printf("starting windows_write test\n");
11326 if (!torture_open_connection(&cli1
, 0)) {
11330 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
11331 if (!NT_STATUS_IS_OK(status
)) {
11332 printf("open failed (%s)\n", nt_errstr(status
));
11336 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
11338 start_time
= timeval_current();
11340 for (i
=0; i
<torture_numops
; i
++) {
11342 off_t start
= i
* torture_blocksize
;
11343 size_t to_pull
= torture_blocksize
- 1;
11345 status
= cli_writeall(cli1
, fnum
, 0, &c
,
11346 start
+ torture_blocksize
- 1, 1, NULL
);
11347 if (!NT_STATUS_IS_OK(status
)) {
11348 printf("cli_write failed: %s\n", nt_errstr(status
));
11352 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
11353 null_source
, &to_pull
);
11354 if (!NT_STATUS_IS_OK(status
)) {
11355 printf("cli_push returned: %s\n", nt_errstr(status
));
11360 seconds
= timeval_elapsed(&start_time
);
11361 kbytes
= (double)torture_blocksize
* torture_numops
;
11364 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
11365 (double)seconds
, (int)(kbytes
/seconds
));
11369 cli_close(cli1
, fnum
);
11370 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11371 torture_close_connection(cli1
);
11375 static size_t calc_expected_return(struct cli_state
*cli
, size_t len_requested
)
11377 size_t max_pdu
= 0x1FFFF;
11379 if (cli
->server_posix_capabilities
& CIFS_UNIX_LARGE_READ_CAP
) {
11380 max_pdu
= 0xFFFFFF;
11383 if (smb1cli_conn_signing_is_active(cli
->conn
)) {
11387 if (smb1cli_conn_encryption_on(cli
->conn
)) {
11388 max_pdu
= CLI_BUFFER_SIZE
;
11391 if ((len_requested
& 0xFFFF0000) == 0xFFFF0000) {
11392 len_requested
&= 0xFFFF;
11395 return MIN(len_requested
,
11396 max_pdu
- (MIN_SMB_SIZE
+ VWV(12) + 1 /* padding byte */));
11399 static bool check_read_call(struct cli_state
*cli
,
11402 size_t len_requested
)
11405 struct tevent_req
*subreq
= NULL
;
11406 ssize_t len_read
= 0;
11407 size_t len_expected
= 0;
11408 struct tevent_context
*ev
= NULL
;
11410 ev
= samba_tevent_context_init(talloc_tos());
11415 subreq
= cli_read_andx_send(talloc_tos(),
11422 if (!tevent_req_poll_ntstatus(subreq
, ev
, &status
)) {
11426 status
= cli_read_andx_recv(subreq
, &len_read
, &buf
);
11427 if (!NT_STATUS_IS_OK(status
)) {
11428 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status
));
11432 TALLOC_FREE(subreq
);
11435 len_expected
= calc_expected_return(cli
, len_requested
);
11437 if (len_expected
> 0x10000 && len_read
== 0x10000) {
11438 /* Windows servers only return a max of 0x10000,
11439 doesn't matter if you set CAP_LARGE_READX in
11440 the client sessionsetupX call or not. */
11441 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
11442 (unsigned int)len_requested
);
11443 } else if (len_read
!= len_expected
) {
11444 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
11445 (unsigned int)len_requested
,
11446 (unsigned int)len_read
,
11447 (unsigned int)len_expected
);
11450 d_printf("Correct read reply.\n");
11456 /* Test large readX variants. */
11457 static bool large_readx_tests(struct cli_state
*cli
,
11461 /* A read of 0xFFFF0001 should *always* return 1 byte. */
11462 if (check_read_call(cli
, fnum
, buf
, 0xFFFF0001) == false) {
11465 /* A read of 0x10000 should return 0x10000 bytes. */
11466 if (check_read_call(cli
, fnum
, buf
, 0x10000) == false) {
11469 /* A read of 0x10000 should return 0x10001 bytes. */
11470 if (check_read_call(cli
, fnum
, buf
, 0x10001) == false) {
11473 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
11474 the requested number of bytes. */
11475 if (check_read_call(cli
, fnum
, buf
, 0x1FFFF - (MIN_SMB_SIZE
+ VWV(12))) == false) {
11478 /* A read of 1MB should return 1MB bytes (on Samba). */
11479 if (check_read_call(cli
, fnum
, buf
, 0x100000) == false) {
11483 if (check_read_call(cli
, fnum
, buf
, 0x20001) == false) {
11486 if (check_read_call(cli
, fnum
, buf
, 0x22000001) == false) {
11489 if (check_read_call(cli
, fnum
, buf
, 0xFFFE0001) == false) {
11495 static bool run_large_readx(int dummy
)
11497 uint8_t *buf
= NULL
;
11498 struct cli_state
*cli1
= NULL
;
11499 struct cli_state
*cli2
= NULL
;
11500 bool correct
= false;
11501 const char *fname
= "\\large_readx.dat";
11503 uint16_t fnum1
= UINT16_MAX
;
11504 uint32_t normal_caps
= 0;
11505 size_t file_size
= 20*1024*1024;
11506 TALLOC_CTX
*frame
= talloc_stackframe();
11510 enum smb_signing_setting signing_setting
;
11511 enum protocol_types protocol
;
11515 .signing_setting
= SMB_SIGNING_IF_REQUIRED
,
11516 .protocol
= PROTOCOL_NT1
,
11518 .name
= "NT1 - SIGNING_REQUIRED",
11519 .signing_setting
= SMB_SIGNING_REQUIRED
,
11520 .protocol
= PROTOCOL_NT1
,
11524 printf("starting large_readx test\n");
11526 if (!torture_open_connection(&cli1
, 0)) {
11530 normal_caps
= smb1cli_conn_capabilities(cli1
->conn
);
11532 if (!(normal_caps
& CAP_LARGE_READX
)) {
11533 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
11534 (unsigned int)normal_caps
);
11538 /* Create a file of size 4MB. */
11539 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
11540 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
11541 0, 0, &fnum1
, NULL
);
11543 if (!NT_STATUS_IS_OK(status
)) {
11544 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
11548 /* Write file_size bytes. */
11549 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
11554 status
= cli_writeall(cli1
,
11561 if (!NT_STATUS_IS_OK(status
)) {
11562 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
11566 status
= cli_close(cli1
, fnum1
);
11567 if (!NT_STATUS_IS_OK(status
)) {
11568 d_printf("cli_close failed: %s\n", nt_errstr(status
));
11572 fnum1
= UINT16_MAX
;
11574 for (i
=0; i
< ARRAY_SIZE(runs
); i
++) {
11575 enum smb_signing_setting saved_signing_setting
= signing_state
;
11576 uint16_t fnum2
= -1;
11579 (runs
[i
].signing_setting
== SMB_SIGNING_REQUIRED
))
11581 d_printf("skip[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
11585 d_printf("run[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
11587 signing_state
= runs
[i
].signing_setting
;
11588 cli2
= open_nbt_connection();
11589 signing_state
= saved_signing_setting
;
11590 if (cli2
== NULL
) {
11594 status
= smbXcli_negprot(cli2
->conn
,
11601 if (!NT_STATUS_IS_OK(status
)) {
11605 status
= cli_session_setup_creds(cli2
, torture_creds
);
11606 if (!NT_STATUS_IS_OK(status
)) {
11610 status
= cli_tree_connect(cli2
,
11614 if (!NT_STATUS_IS_OK(status
)) {
11618 cli_set_timeout(cli2
, 120000); /* set a really long timeout (2 minutes) */
11620 normal_caps
= smb1cli_conn_capabilities(cli2
->conn
);
11622 if (!(normal_caps
& CAP_LARGE_READX
)) {
11623 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
11624 (unsigned int)normal_caps
);
11629 if (force_cli_encryption(cli2
, share
) == false) {
11632 } else if (SERVER_HAS_UNIX_CIFS(cli2
)) {
11633 uint16_t major
, minor
;
11634 uint32_t caplow
, caphigh
;
11636 status
= cli_unix_extensions_version(cli2
,
11638 &caplow
, &caphigh
);
11639 if (!NT_STATUS_IS_OK(status
)) {
11644 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
,
11645 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
11646 0, 0, &fnum2
, NULL
);
11647 if (!NT_STATUS_IS_OK(status
)) {
11648 d_printf("Second open %s failed: %s\n", fname
, nt_errstr(status
));
11652 /* All reads must return less than file_size bytes. */
11653 if (!large_readx_tests(cli2
, fnum2
, buf
)) {
11657 status
= cli_close(cli2
, fnum2
);
11658 if (!NT_STATUS_IS_OK(status
)) {
11659 d_printf("cli_close failed: %s\n", nt_errstr(status
));
11664 if (!torture_close_connection(cli2
)) {
11671 printf("Success on large_readx test\n");
11676 if (!torture_close_connection(cli2
)) {
11682 if (fnum1
!= UINT16_MAX
) {
11683 status
= cli_close(cli1
, fnum1
);
11684 if (!NT_STATUS_IS_OK(status
)) {
11685 d_printf("cli_close failed: %s\n", nt_errstr(status
));
11687 fnum1
= UINT16_MAX
;
11690 status
= cli_unlink(cli1
, fname
,
11691 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11692 if (!NT_STATUS_IS_OK(status
)) {
11693 printf("unlink failed (%s)\n", nt_errstr(status
));
11696 if (!torture_close_connection(cli1
)) {
11701 TALLOC_FREE(frame
);
11703 printf("finished large_readx test\n");
11707 static NTSTATUS
msdfs_attribute_list_fn(struct file_info
*finfo
,
11709 void *private_data
)
11711 uint32_t *p_attr
= (uint32_t *)private_data
;
11713 if (strequal(finfo
->name
, test_filename
)) {
11714 *p_attr
= finfo
->attr
;
11717 return NT_STATUS_OK
;
11720 static bool run_msdfs_attribute(int dummy
)
11722 static struct cli_state
*cli
;
11723 bool correct
= false;
11727 printf("Starting MSDFS-ATTRIBUTE test\n");
11729 if (test_filename
== NULL
|| test_filename
[0] == '\0') {
11730 printf("MSDFS-ATTRIBUTE test "
11731 "needs -f filename-of-msdfs-link\n");
11736 * NB. We use torture_open_connection_flags() not
11737 * torture_open_connection() as the latter forces
11740 if (!torture_open_connection_flags(&cli
, 0, 0)) {
11744 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
11746 status
= cli_list(cli
,
11748 FILE_ATTRIBUTE_DIRECTORY
,
11749 msdfs_attribute_list_fn
,
11752 if (!NT_STATUS_IS_OK(status
)) {
11753 printf("cli_list failed with %s\n",
11754 nt_errstr(status
));
11757 if ((attr
& FILE_ATTRIBUTE_REPARSE_POINT
) == 0) {
11758 printf("file %s should have "
11759 "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
11761 (unsigned int)attr
);
11765 if ((attr
& FILE_ATTRIBUTE_DIRECTORY
) == 0) {
11766 printf("file %s should have "
11767 "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
11769 (unsigned int)attr
);
11777 torture_close_connection(cli
);
11781 static bool run_cli_echo(int dummy
)
11783 struct cli_state
*cli
;
11786 printf("starting cli_echo test\n");
11787 if (!torture_open_connection(&cli
, 0)) {
11790 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
11792 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
11794 d_printf("cli_echo returned %s\n", nt_errstr(status
));
11796 torture_close_connection(cli
);
11797 return NT_STATUS_IS_OK(status
);
11800 static int splice_status(off_t written
, void *priv
)
11805 static bool run_cli_splice(int dummy
)
11807 uint8_t *buf
= NULL
;
11808 struct cli_state
*cli1
= NULL
;
11809 bool correct
= false;
11810 const char *fname_src
= "\\splice_src.dat";
11811 const char *fname_dst
= "\\splice_dst.dat";
11813 uint16_t fnum1
= UINT16_MAX
;
11814 uint16_t fnum2
= UINT16_MAX
;
11815 size_t file_size
= 2*1024*1024;
11816 size_t splice_size
= 1*1024*1024 + 713;
11817 uint8_t digest1
[16], digest2
[16];
11820 TALLOC_CTX
*frame
= talloc_stackframe();
11822 printf("starting cli_splice test\n");
11824 if (!torture_open_connection(&cli1
, 0)) {
11828 cli_unlink(cli1
, fname_src
,
11829 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11830 cli_unlink(cli1
, fname_dst
,
11831 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11833 /* Create a file */
11834 status
= cli_ntcreate(cli1
, fname_src
, 0, GENERIC_ALL_ACCESS
,
11835 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
11836 0, 0, &fnum1
, NULL
);
11838 if (!NT_STATUS_IS_OK(status
)) {
11839 d_printf("open %s failed: %s\n", fname_src
, nt_errstr(status
));
11843 /* Write file_size bytes - must be bigger than splice_size. */
11844 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
11846 d_printf("talloc_fail\n");
11850 /* Fill it with random numbers. */
11851 generate_random_buffer(buf
, file_size
);
11853 /* MD5 the first 1MB + 713 bytes. */
11854 gnutls_hash_fast(GNUTLS_DIG_MD5
,
11859 status
= cli_writeall(cli1
,
11866 if (!NT_STATUS_IS_OK(status
)) {
11867 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
11871 status
= cli_ntcreate(cli1
, fname_dst
, 0, GENERIC_ALL_ACCESS
,
11872 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
11873 0, 0, &fnum2
, NULL
);
11875 if (!NT_STATUS_IS_OK(status
)) {
11876 d_printf("open %s failed: %s\n", fname_dst
, nt_errstr(status
));
11880 /* Now splice 1MB + 713 bytes. */
11881 status
= cli_splice(cli1
,
11892 if (!NT_STATUS_IS_OK(status
)) {
11893 d_printf("cli_splice failed: %s\n", nt_errstr(status
));
11897 /* Clear the old buffer. */
11898 memset(buf
, '\0', file_size
);
11900 /* Read the new file. */
11901 status
= cli_read(cli1
, fnum2
, (char *)buf
, 0, splice_size
, &nread
);
11902 if (!NT_STATUS_IS_OK(status
)) {
11903 d_printf("cli_read failed: %s\n", nt_errstr(status
));
11906 if (nread
!= splice_size
) {
11907 d_printf("bad read of 0x%x, should be 0x%x\n",
11908 (unsigned int)nread
,
11909 (unsigned int)splice_size
);
11913 /* MD5 the first 1MB + 713 bytes. */
11914 gnutls_hash_fast(GNUTLS_DIG_MD5
,
11919 /* Must be the same. */
11920 if (memcmp(digest1
, digest2
, 16) != 0) {
11921 d_printf("bad MD5 compare\n");
11926 printf("Success on cli_splice test\n");
11931 if (fnum1
!= UINT16_MAX
) {
11932 cli_close(cli1
, fnum1
);
11934 if (fnum2
!= UINT16_MAX
) {
11935 cli_close(cli1
, fnum2
);
11938 cli_unlink(cli1
, fname_src
,
11939 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11940 cli_unlink(cli1
, fname_dst
,
11941 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
11943 if (!torture_close_connection(cli1
)) {
11948 TALLOC_FREE(frame
);
11952 static bool run_uid_regression_test(int dummy
)
11954 static struct cli_state
*cli
;
11957 bool correct
= True
;
11958 struct smbXcli_tcon
*tcon_copy
= NULL
;
11961 printf("starting uid regression test\n");
11963 if (!torture_open_connection(&cli
, 0)) {
11967 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
11969 /* Ok - now save then logoff our current user. */
11970 old_vuid
= cli_state_get_uid(cli
);
11972 status
= cli_ulogoff(cli
);
11973 if (!NT_STATUS_IS_OK(status
)) {
11974 d_printf("(%s) cli_ulogoff failed: %s\n",
11975 __location__
, nt_errstr(status
));
11980 cli_state_set_uid(cli
, old_vuid
);
11982 /* Try an operation. */
11983 status
= cli_mkdir(cli
, "\\uid_reg_test");
11984 if (NT_STATUS_IS_OK(status
)) {
11985 d_printf("(%s) cli_mkdir succeeded\n",
11990 /* Should be bad uid. */
11991 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
11992 NT_STATUS_USER_SESSION_DELETED
)) {
11998 old_cnum
= cli_state_get_tid(cli
);
12000 * This is an SMB1-only test.
12001 * Copy the tcon, not "save/restore".
12003 * In SMB1 the cli_tdis() below frees
12004 * cli->smb1.tcon so we need a copy
12005 * of the struct to put back for the
12006 * second tdis call with invalid vuid.
12008 * This is a test-only hack. Real client code
12009 * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
12011 tcon_copy
= smbXcli_tcon_copy(cli
, cli
->smb1
.tcon
);
12012 if (tcon_copy
== NULL
) {
12017 /* Now try a SMBtdis with the invalid vuid set to zero. */
12018 cli_state_set_uid(cli
, 0);
12020 /* This should succeed. */
12021 status
= cli_tdis(cli
);
12023 if (NT_STATUS_IS_OK(status
)) {
12024 d_printf("First tdis with invalid vuid should succeed.\n");
12026 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
12028 cli
->smb1
.tcon
= tcon_copy
;
12032 cli
->smb1
.tcon
= tcon_copy
;
12033 cli_state_set_uid(cli
, old_vuid
);
12034 cli_state_set_tid(cli
, old_cnum
);
12036 /* This should fail. */
12037 status
= cli_tdis(cli
);
12038 if (NT_STATUS_IS_OK(status
)) {
12039 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
12043 /* Should be bad tid. */
12044 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
12045 NT_STATUS_NETWORK_NAME_DELETED
)) {
12051 cli_rmdir(cli
, "\\uid_reg_test");
12060 static const char *illegal_chars
= "*\\/?<>|\":";
12061 static char force_shortname_chars
[] = " +,.[];=\177";
12063 static NTSTATUS
shortname_del_fn(struct file_info
*finfo
,
12064 const char *mask
, void *state
)
12066 struct cli_state
*pcli
= (struct cli_state
*)state
;
12068 NTSTATUS status
= NT_STATUS_OK
;
12070 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
12072 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
12073 return NT_STATUS_OK
;
12075 if (finfo
->attr
& FILE_ATTRIBUTE_DIRECTORY
) {
12076 status
= cli_rmdir(pcli
, fname
);
12077 if (!NT_STATUS_IS_OK(status
)) {
12078 printf("del_fn: failed to rmdir %s\n,", fname
);
12081 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
12082 if (!NT_STATUS_IS_OK(status
)) {
12083 printf("del_fn: failed to unlink %s\n,", fname
);
12095 static NTSTATUS
shortname_list_fn(struct file_info
*finfo
,
12096 const char *name
, void *state
)
12098 struct sn_state
*s
= (struct sn_state
*)state
;
12102 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
12103 i
, finfo
->name
, finfo
->short_name
);
12106 if (strchr(force_shortname_chars
, i
)) {
12107 if (!finfo
->short_name
) {
12108 /* Shortname not created when it should be. */
12109 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
12110 __location__
, finfo
->name
, i
);
12113 } else if (finfo
->short_name
){
12114 /* Shortname created when it should not be. */
12115 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
12116 __location__
, finfo
->short_name
, finfo
->name
);
12120 return NT_STATUS_OK
;
12123 static bool run_shortname_test(int dummy
)
12125 static struct cli_state
*cli
;
12126 bool correct
= True
;
12132 printf("starting shortname test\n");
12134 if (!torture_open_connection(&cli
, 0)) {
12138 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
12140 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
12141 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
12142 cli_rmdir(cli
, "\\shortname");
12144 status
= cli_mkdir(cli
, "\\shortname");
12145 if (!NT_STATUS_IS_OK(status
)) {
12146 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
12147 __location__
, nt_errstr(status
));
12152 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
12156 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
12163 for (i
= 32; i
< 128; i
++) {
12164 uint16_t fnum
= (uint16_t)-1;
12168 if (strchr(illegal_chars
, i
)) {
12173 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
12174 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
12175 FILE_OVERWRITE_IF
, 0, 0, &fnum
, NULL
);
12176 if (!NT_STATUS_IS_OK(status
)) {
12177 d_printf("(%s) cli_nt_create of %s failed: %s\n",
12178 __location__
, fname
, nt_errstr(status
));
12182 cli_close(cli
, fnum
);
12185 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
12186 shortname_list_fn
, &s
);
12187 if (s
.matched
!= 1) {
12188 d_printf("(%s) failed to list %s: %s\n",
12189 __location__
, fname
, nt_errstr(status
));
12194 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
12195 if (!NT_STATUS_IS_OK(status
)) {
12196 d_printf("(%s) failed to delete %s: %s\n",
12197 __location__
, fname
, nt_errstr(status
));
12210 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
12211 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
12212 cli_rmdir(cli
, "\\shortname");
12213 torture_close_connection(cli
);
12217 TLDAPRC callback_code
;
12219 static void pagedsearch_cb(struct tevent_req
*req
)
12222 struct tldap_message
*msg
;
12225 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
12226 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12227 d_printf("tldap_search_paged_recv failed: %s\n",
12228 tldap_rc2string(rc
));
12229 callback_code
= rc
;
12232 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
12236 if (!tldap_entry_dn(msg
, &dn
)) {
12237 d_printf("tldap_entry_dn failed\n");
12240 d_printf("%s\n", dn
);
12244 enum tldap_extended_val
{
12251 * Construct an extended dn control with either no value, 0 or 1
12253 * No value and 0 are equivalent (non-hyphenated GUID)
12254 * 1 has the hyphenated GUID
12256 static struct tldap_control
*
12257 tldap_build_extended_control(enum tldap_extended_val val
)
12259 struct tldap_control empty_control
;
12260 struct asn1_data
*data
;
12262 ZERO_STRUCT(empty_control
);
12264 if (val
!= EXTENDED_NONE
) {
12265 data
= asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH
);
12271 if (!asn1_push_tag(data
, ASN1_SEQUENCE(0))) {
12275 if (!asn1_write_Integer(data
, (int)val
)) {
12279 if (!asn1_pop_tag(data
)) {
12283 if (!asn1_blob(data
, &empty_control
.value
)) {
12288 empty_control
.oid
= "1.2.840.113556.1.4.529";
12289 empty_control
.critical
= true;
12291 return tldap_add_control(talloc_tos(), NULL
, 0, &empty_control
);
12295 static bool tldap_test_dn_guid_format(struct tldap_context
*ld
, const char *basedn
,
12296 enum tldap_extended_val control_val
)
12298 struct tldap_control
*control
= tldap_build_extended_control(control_val
);
12300 struct tldap_message
**msg
;
12303 rc
= tldap_search(ld
, basedn
, TLDAP_SCOPE_BASE
,
12304 "(objectClass=*)", NULL
, 0, 0,
12306 0, 0, 0, 0, talloc_tos(), &msg
);
12307 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12308 d_printf("tldap_search for domain DN failed: %s\n",
12309 tldap_errstr(talloc_tos(), ld
, rc
));
12313 if (!tldap_entry_dn(msg
[0], &dn
)) {
12314 d_printf("tldap_search domain DN fetch failed: %s\n",
12315 tldap_errstr(talloc_tos(), ld
, rc
));
12319 d_printf("%s\n", dn
);
12322 uint32_t time_mid
, time_hi_and_version
;
12323 uint32_t clock_seq
[2];
12327 switch (control_val
) {
12328 case EXTENDED_NONE
:
12329 case EXTENDED_ZERO
:
12331 * When reading GUIDs with hyphens, scanf will treat
12332 * hyphen as a hex character (and counts as part of the
12333 * width). This creates leftover GUID string which we
12334 * check will for with 'next' and closing '>'.
12336 if (12 == sscanf(dn
, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
12337 &time_low
, &time_mid
,
12338 &time_hi_and_version
, &clock_seq
[0],
12339 &clock_seq
[1], &node
[0], &node
[1],
12340 &node
[2], &node
[3], &node
[4],
12341 &node
[5], &next
)) {
12342 /* This GUID is good */
12344 d_printf("GUID format in control (no hyphens) doesn't match output\n");
12350 if (12 == sscanf(dn
,
12351 "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
12352 &time_low
, &time_mid
,
12353 &time_hi_and_version
, &clock_seq
[0],
12354 &clock_seq
[1], &node
[0], &node
[1],
12355 &node
[2], &node
[3], &node
[4],
12356 &node
[5], &next
)) {
12357 /* This GUID is good */
12359 d_printf("GUID format in control (with hyphens) doesn't match output\n");
12372 static bool run_tldap(int dummy
)
12374 struct tldap_context
*ld
;
12378 struct sockaddr_storage addr
;
12379 struct tevent_context
*ev
;
12380 struct tevent_req
*req
;
12382 const char *filter
;
12383 struct loadparm_context
*lp_ctx
= NULL
;
12384 int tcp_port
= 389;
12385 bool use_tls
= false;
12386 bool use_starttls
= false;
12387 int wrap_flags
= -1;
12388 uint32_t gensec_features
= 0;
12390 lp_ctx
= loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
12392 wrap_flags
= lpcfg_client_ldap_sasl_wrapping(lp_ctx
);
12394 if (wrap_flags
& ADS_AUTH_SASL_LDAPS
) {
12397 } else if (wrap_flags
& ADS_AUTH_SASL_STARTTLS
) {
12399 use_starttls
= true;
12401 if (wrap_flags
& ADS_AUTH_SASL_SEAL
) {
12402 gensec_features
|= GENSEC_FEATURE_SEAL
;
12404 if (wrap_flags
& ADS_AUTH_SASL_SIGN
) {
12405 gensec_features
|= GENSEC_FEATURE_SIGN
;
12408 if (gensec_features
!= 0) {
12409 gensec_features
|= GENSEC_FEATURE_LDAP_STYLE
;
12412 if (!resolve_name(host
, &addr
, 0, false)) {
12413 d_printf("could not find host %s\n", host
);
12416 status
= open_socket_out(&addr
, tcp_port
, 9999, &fd
);
12417 if (!NT_STATUS_IS_OK(status
)) {
12418 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
12422 ld
= tldap_context_create(talloc_tos(), fd
);
12425 d_printf("tldap_context_create failed\n");
12429 if (use_tls
&& !tldap_has_tls_tstream(ld
)) {
12430 tldap_set_starttls_needed(ld
, use_starttls
);
12432 rc
= tldap_tls_connect(ld
, lp_ctx
, host
);
12433 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12434 DBG_ERR("tldap_tls_connect(%s) failed: %s\n",
12435 host
, tldap_errstr(talloc_tos(), ld
, rc
));
12440 rc
= tldap_fetch_rootdse(ld
);
12441 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12442 d_printf("tldap_fetch_rootdse failed: %s\n",
12443 tldap_errstr(talloc_tos(), ld
, rc
));
12447 basedn
= tldap_talloc_single_attribute(
12448 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
12449 if (basedn
== NULL
) {
12450 d_printf("no defaultNamingContext\n");
12453 d_printf("defaultNamingContext: %s\n", basedn
);
12455 ev
= samba_tevent_context_init(talloc_tos());
12457 d_printf("tevent_context_init failed\n");
12461 rc
= tldap_gensec_bind(ld
, torture_creds
, "ldap", host
, NULL
,
12462 lp_ctx
, gensec_features
);
12463 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12464 d_printf("tldap_gensec_bind failed\n");
12468 callback_code
= TLDAP_SUCCESS
;
12470 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
12471 TLDAP_SCOPE_SUB
, "(objectclass=*)",
12473 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
12475 d_printf("tldap_search_paged_send failed\n");
12478 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
12480 tevent_req_poll(req
, ev
);
12484 rc
= callback_code
;
12486 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12487 d_printf("tldap_search with paging failed: %s\n",
12488 tldap_errstr(talloc_tos(), ld
, rc
));
12492 /* test search filters against rootDSE */
12493 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
12494 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
12496 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
12497 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
12498 talloc_tos(), NULL
);
12499 if (!TLDAP_RC_IS_SUCCESS(rc
)) {
12500 d_printf("tldap_search with complex filter failed: %s\n",
12501 tldap_errstr(talloc_tos(), ld
, rc
));
12506 * Tests to check for regression of:
12508 * https://bugzilla.samba.org/show_bug.cgi?id=14029
12510 * TLDAP used here to pick apart the original string DN (with GUID)
12512 if (!tldap_test_dn_guid_format(ld
, basedn
, EXTENDED_NONE
)) {
12513 d_printf("tldap_search with extended dn (no val) failed: %s\n",
12514 tldap_errstr(talloc_tos(), ld
, rc
));
12517 if (!tldap_test_dn_guid_format(ld
, basedn
, EXTENDED_ZERO
)) {
12518 d_printf("tldap_search with extended dn (0) failed: %s\n",
12519 tldap_errstr(talloc_tos(), ld
, rc
));
12522 if (!tldap_test_dn_guid_format(ld
, basedn
, EXTENDED_ONE
)) {
12523 d_printf("tldap_search with extended dn (1) failed: %s\n",
12524 tldap_errstr(talloc_tos(), ld
, rc
));
12532 /* Torture test to ensure no regression of :
12533 https://bugzilla.samba.org/show_bug.cgi?id=7084
12536 static bool run_dir_createtime(int dummy
)
12538 struct cli_state
*cli
;
12539 const char *dname
= "\\testdir_createtime";
12540 const char *fname
= "\\testdir_createtime\\testfile";
12542 struct timespec create_time
;
12543 struct timespec create_time1
;
12548 if (!torture_open_connection(&cli
, 0)) {
12552 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
12553 /* Ensure ino is zero, SMB2 gets a real one. */
12556 /* Ensure ino is -1, SMB1 never gets a real one. */
12557 ino
= (uint64_t)-1;
12560 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
12561 cli_rmdir(cli
, dname
);
12563 status
= cli_mkdir(cli
, dname
);
12564 if (!NT_STATUS_IS_OK(status
)) {
12565 printf("mkdir failed: %s\n", nt_errstr(status
));
12569 status
= cli_qpathinfo2(cli
,
12579 if (!NT_STATUS_IS_OK(status
)) {
12580 printf("cli_qpathinfo2 returned %s\n",
12581 nt_errstr(status
));
12585 if (smbXcli_conn_protocol(cli
->conn
) >= PROTOCOL_SMB2_02
) {
12586 /* SMB2 should always return an inode. */
12588 printf("SMB2 bad inode (0)\n");
12592 /* SMB1 must always return zero here. */
12594 printf("SMB1 bad inode (!0)\n");
12599 /* Sleep 3 seconds, then create a file. */
12602 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
12604 if (!NT_STATUS_IS_OK(status
)) {
12605 printf("cli_openx failed: %s\n", nt_errstr(status
));
12609 status
= cli_qpathinfo2(cli
,
12619 if (!NT_STATUS_IS_OK(status
)) {
12620 printf("cli_qpathinfo2 (2) returned %s\n",
12621 nt_errstr(status
));
12625 if (timespec_compare(&create_time1
, &create_time
)) {
12626 printf("run_dir_createtime: create time was updated (error)\n");
12628 printf("run_dir_createtime: create time was not updated (correct)\n");
12634 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
12635 cli_rmdir(cli
, dname
);
12636 if (!torture_close_connection(cli
)) {
12643 static bool run_streamerror(int dummy
)
12645 struct cli_state
*cli
;
12646 const char *dname
= "\\testdir_streamerror";
12647 const char *streamname
=
12648 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
12650 time_t change_time
, access_time
, write_time
;
12656 if (!torture_open_connection(&cli
, 0)) {
12660 torture_deltree(cli
, dname
);
12662 status
= cli_mkdir(cli
, dname
);
12663 if (!NT_STATUS_IS_OK(status
)) {
12664 printf("mkdir failed: %s\n", nt_errstr(status
));
12668 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
12669 &write_time
, &size
, &attr
);
12670 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
12671 printf("pathinfo returned %s, expected "
12672 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
12673 nt_errstr(status
));
12677 status
= cli_ntcreate(cli
, streamname
, 0x16,
12678 FILE_READ_DATA
|FILE_READ_EA
|
12679 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
12680 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
12681 FILE_OPEN
, 0, 0, &fnum
, NULL
);
12683 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
12684 printf("ntcreate returned %s, expected "
12685 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
12686 nt_errstr(status
));
12691 cli_rmdir(cli
, dname
);
12695 struct pidtest_state
{
12701 static void pid_echo_done(struct tevent_req
*subreq
);
12703 static struct tevent_req
*pid_echo_send(TALLOC_CTX
*mem_ctx
,
12704 struct tevent_context
*ev
,
12705 struct cli_state
*cli
)
12707 struct tevent_req
*req
, *subreq
;
12708 struct pidtest_state
*state
;
12710 req
= tevent_req_create(mem_ctx
, &state
, struct pidtest_state
);
12715 SSVAL(state
->vwv
, 0, 1);
12716 state
->data
= data_blob_const("hello", 5);
12718 subreq
= smb1cli_req_send(state
,
12722 0, 0, /* *_flags */
12723 0, 0, /* *_flags2 */
12725 0xDEADBEEF, /* pid */
12727 NULL
, /* session */
12728 ARRAY_SIZE(state
->vwv
), state
->vwv
,
12729 state
->data
.length
, state
->data
.data
);
12731 if (tevent_req_nomem(subreq
, req
)) {
12732 return tevent_req_post(req
, ev
);
12734 tevent_req_set_callback(subreq
, pid_echo_done
, req
);
12738 static void pid_echo_done(struct tevent_req
*subreq
)
12740 struct tevent_req
*req
= tevent_req_callback_data(
12741 subreq
, struct tevent_req
);
12742 struct pidtest_state
*state
= tevent_req_data(
12743 req
, struct pidtest_state
);
12745 uint32_t num_bytes
;
12746 uint8_t *bytes
= NULL
;
12747 struct iovec
*recv_iov
= NULL
;
12748 uint8_t *phdr
= NULL
;
12749 uint16_t pidlow
= 0;
12750 uint16_t pidhigh
= 0;
12751 struct smb1cli_req_expected_response expected
[] = {
12753 .status
= NT_STATUS_OK
,
12758 status
= smb1cli_req_recv(subreq
, state
,
12763 NULL
, /* pvwv_offset */
12766 NULL
, /* pbytes_offset */
12768 expected
, ARRAY_SIZE(expected
));
12770 TALLOC_FREE(subreq
);
12772 if (!NT_STATUS_IS_OK(status
)) {
12773 tevent_req_nterror(req
, status
);
12777 if (num_bytes
!= state
->data
.length
) {
12778 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
12782 if (memcmp(bytes
, state
->data
.data
, num_bytes
) != 0) {
12783 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
12787 /* Check pid low/high == DEADBEEF */
12788 pidlow
= SVAL(phdr
, HDR_PID
);
12789 if (pidlow
!= 0xBEEF){
12790 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
12791 (unsigned int)pidlow
);
12792 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
12795 pidhigh
= SVAL(phdr
, HDR_PIDHIGH
);
12796 if (pidhigh
!= 0xDEAD){
12797 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
12798 (unsigned int)pidhigh
);
12799 tevent_req_nterror(req
, NT_STATUS_INVALID_NETWORK_RESPONSE
);
12803 tevent_req_done(req
);
12806 static NTSTATUS
pid_echo_recv(struct tevent_req
*req
)
12808 return tevent_req_simple_recv_ntstatus(req
);
12811 static bool run_pidhigh(int dummy
)
12813 bool success
= false;
12814 struct cli_state
*cli
= NULL
;
12816 struct tevent_context
*ev
= NULL
;
12817 struct tevent_req
*req
= NULL
;
12818 TALLOC_CTX
*frame
= talloc_stackframe();
12820 printf("starting pid high test\n");
12821 if (!torture_open_connection(&cli
, 0)) {
12824 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
12826 ev
= samba_tevent_context_init(frame
);
12831 req
= pid_echo_send(frame
, ev
, cli
);
12836 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
12840 status
= pid_echo_recv(req
);
12841 if (NT_STATUS_IS_OK(status
)) {
12842 printf("pid high test ok\n");
12848 TALLOC_FREE(frame
);
12849 torture_close_connection(cli
);
12854 Test Windows open on a bad POSIX symlink.
12856 static bool run_symlink_open_test(int dummy
)
12858 static struct cli_state
*cli
;
12859 const char *fname
= "non_existant_file";
12860 const char *sname
= "dangling_symlink";
12861 uint16_t fnum
= (uint16_t)-1;
12862 bool correct
= false;
12864 TALLOC_CTX
*frame
= NULL
;
12866 frame
= talloc_stackframe();
12868 printf("Starting Windows bad symlink open test\n");
12870 if (!torture_open_connection(&cli
, 0)) {
12871 TALLOC_FREE(frame
);
12875 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
12877 status
= torture_setup_unix_extensions(cli
);
12878 if (!NT_STATUS_IS_OK(status
)) {
12879 TALLOC_FREE(frame
);
12883 /* Ensure nothing exists. */
12884 cli_setatr(cli
, fname
, 0, 0);
12885 cli_posix_unlink(cli
, fname
);
12886 cli_setatr(cli
, sname
, 0, 0);
12887 cli_posix_unlink(cli
, sname
);
12889 /* Create a symlink pointing nowhere. */
12890 status
= cli_posix_symlink(cli
, fname
, sname
);
12891 if (!NT_STATUS_IS_OK(status
)) {
12892 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
12895 nt_errstr(status
));
12899 /* Now ensure that a Windows open doesn't hang. */
12900 status
= cli_ntcreate(cli
,
12903 FILE_READ_DATA
|FILE_WRITE_DATA
,
12905 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
12913 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
12914 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
12915 * we use O_NOFOLLOW on the server or not.
12917 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) ||
12918 NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_PATH_NOT_FOUND
))
12922 printf("cli_ntcreate of %s returned %s - should return"
12923 " either (%s) or (%s)\n",
12926 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND
),
12927 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND
));
12935 if (fnum
!= (uint16_t)-1) {
12936 cli_close(cli
, fnum
);
12937 fnum
= (uint16_t)-1;
12940 cli_setatr(cli
, sname
, 0, 0);
12941 cli_posix_unlink(cli
, sname
);
12942 cli_setatr(cli
, fname
, 0, 0);
12943 cli_posix_unlink(cli
, fname
);
12945 if (!torture_close_connection(cli
)) {
12949 TALLOC_FREE(frame
);
12953 static NTSTATUS
smb1_wild_mangle_list_fn(struct file_info
*finfo
,
12957 char **mangled_name_return
= (char **)state
;
12958 bool is_mangled
= strchr(finfo
->name
, '~');
12961 *mangled_name_return
= talloc_strdup(NULL
, finfo
->name
);
12962 if (*mangled_name_return
== NULL
) {
12963 return NT_STATUS_NO_MEMORY
;
12966 return NT_STATUS_OK
;
12969 static bool run_smb1_wild_mangle_unlink_test(int dummy
)
12971 static struct cli_state
*cli_posix
= NULL
;
12972 static struct cli_state
*cli
= NULL
;
12973 uint16_t fnum
= (uint16_t)-1;
12974 bool correct
= false;
12975 const char *dname
= "smb1_wild_mangle_unlink";
12976 const char *aname
= "smb1_wild_mangle_unlink/a";
12977 const char *star_name
= "smb1_wild_mangle_unlink/*";
12978 char *windows_unlink_name
= NULL
;
12979 char *mangled_name
= NULL
;
12982 printf("Starting SMB1 wild mangle unlink test\n");
12984 /* Open a Windows connection. */
12985 if (!torture_open_connection(&cli
, 0)) {
12989 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
12991 /* Open a POSIX connection. */
12992 if (!torture_open_connection(&cli_posix
, 0)) {
12996 smbXcli_conn_set_sockopt(cli_posix
->conn
, sockops
);
12998 status
= torture_setup_unix_extensions(cli_posix
);
12999 if (!NT_STATUS_IS_OK(status
)) {
13000 printf("server doesn't support POSIX\n");
13005 torture_deltree(cli
, dname
);
13008 * Create two files - 'a' and '*'.
13009 * We need POSIX extensions for this as '*'
13010 * is not a valid Windows name.
13013 status
= cli_mkdir(cli
, dname
);
13014 if (!NT_STATUS_IS_OK(status
)) {
13015 printf("cli_mkdir of %s returned %s\n",
13017 nt_errstr(status
));
13021 status
= cli_posix_open(cli_posix
,
13023 O_RDWR
|O_CREAT
|O_EXCL
,
13026 if (!NT_STATUS_IS_OK(status
)) {
13027 printf("cli_posix_open (create) of %s returned %s\n",
13029 nt_errstr(status
));
13032 status
= cli_close(cli_posix
, fnum
);
13033 if (!NT_STATUS_IS_OK(status
)) {
13036 status
= cli_posix_open(cli_posix
,
13038 O_RDWR
|O_CREAT
|O_EXCL
,
13041 if (!NT_STATUS_IS_OK(status
)) {
13042 printf("cli_posix_open (create) of %s returned %s\n",
13044 nt_errstr(status
));
13047 status
= cli_close(cli_posix
, fnum
);
13048 if (!NT_STATUS_IS_OK(status
)) {
13052 status
= cli_list(cli
,
13055 smb1_wild_mangle_list_fn
,
13057 if (!NT_STATUS_IS_OK(status
)) {
13058 printf("cli_list of %s returned %s\n",
13060 nt_errstr(status
));
13064 if (mangled_name
== NULL
) {
13068 printf("mangled_name = %s\n",
13072 * Try a Windows unlink with the mangled name.
13073 * This should *NOT* unlink the 'a' name.
13076 windows_unlink_name
= talloc_asprintf(cli_posix
,
13081 status
= cli_unlink(cli
, windows_unlink_name
, 0);
13082 if (!NT_STATUS_IS_OK(status
)) {
13083 printf("cli_unlink of %s returned %s\n",
13084 windows_unlink_name
,
13085 nt_errstr(status
));
13089 /* Does 'a' still exist ? */
13090 status
= cli_posix_open(cli_posix
,
13095 if (!NT_STATUS_IS_OK(status
)) {
13096 printf("cli_posix_open O_RNONLY of %s returned %s\n",
13098 nt_errstr(status
));
13102 status
= cli_close(cli_posix
, fnum
);
13103 if (!NT_STATUS_IS_OK(status
)) {
13111 TALLOC_FREE(windows_unlink_name
);
13112 TALLOC_FREE(mangled_name
);
13115 torture_deltree(cli
, dname
);
13116 torture_close_connection(cli
);
13119 if (cli_posix
!= NULL
) {
13120 torture_close_connection(cli_posix
);
13126 static bool run_smb1_wild_mangle_rename_test(int dummy
)
13128 static struct cli_state
*cli_posix
= NULL
;
13129 static struct cli_state
*cli
= NULL
;
13130 uint16_t fnum
= (uint16_t)-1;
13131 bool correct
= false;
13132 const char *dname
= "smb1_wild_mangle_rename";
13133 const char *fooname
= "smb1_wild_mangle_rename/foo";
13134 const char *foostar_name
= "smb1_wild_mangle_rename/fo*";
13135 const char *wild_name
= "smb1_wild_mangle_rename/*";
13136 char *windows_rename_src
= NULL
;
13137 const char *windows_rename_dst
= "smb1_wild_mangle_rename\\bar";
13138 char *mangled_name
= NULL
;
13141 printf("Starting SMB1 wild mangle rename test\n");
13143 if (!torture_open_connection(&cli_posix
, 0)) {
13147 smbXcli_conn_set_sockopt(cli_posix
->conn
, sockops
);
13149 status
= torture_setup_unix_extensions(cli_posix
);
13150 if (!NT_STATUS_IS_OK(status
)) {
13151 printf("server doesn't support POSIX\n");
13155 /* Open a Windows connection. */
13156 if (!torture_open_connection(&cli
, 0)) {
13160 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
13162 /* Ensure we start from fresh. */
13163 torture_deltree(cli
, dname
);
13166 * Create two files - 'foo' and 'fo*'.
13167 * We need POSIX extensions for this as 'fo*'
13168 * is not a valid Windows name.
13171 status
= cli_posix_mkdir(cli_posix
, dname
, 0770);
13172 if (!NT_STATUS_IS_OK(status
)) {
13173 printf("cli_posix_mkdir of %s returned %s\n",
13175 nt_errstr(status
));
13179 status
= cli_posix_open(cli_posix
,
13181 O_RDWR
|O_CREAT
|O_EXCL
,
13184 if (!NT_STATUS_IS_OK(status
)) {
13185 printf("cli_posix_open (create) of %s returned %s\n",
13187 nt_errstr(status
));
13190 status
= cli_close(cli_posix
, fnum
);
13191 if (!NT_STATUS_IS_OK(status
)) {
13194 status
= cli_posix_open(cli_posix
,
13196 O_RDWR
|O_CREAT
|O_EXCL
,
13199 if (!NT_STATUS_IS_OK(status
)) {
13200 printf("cli_posix_open (create) of %s returned %s\n",
13202 nt_errstr(status
));
13205 status
= cli_close(cli_posix
, fnum
);
13206 if (!NT_STATUS_IS_OK(status
)) {
13211 * Get the mangled name. We can re-use the
13212 * previous smb1_wild_mangle_list_fn for this.
13215 status
= cli_list(cli
,
13218 smb1_wild_mangle_list_fn
,
13220 if (!NT_STATUS_IS_OK(status
)) {
13221 printf("cli_list of %s returned %s\n",
13223 nt_errstr(status
));
13227 if (mangled_name
== NULL
) {
13231 printf("mangled_name = %s\n",
13235 * Try a Windows rename with the mangled name.
13236 * This should *NOT* rename the 'foo' name.
13239 windows_rename_src
= talloc_asprintf(cli_posix
,
13244 status
= cli_rename(cli
,
13245 windows_rename_src
,
13246 windows_rename_dst
,
13248 if (!NT_STATUS_IS_OK(status
)) {
13249 printf("cli_rename of %s -> %s returned %s\n",
13250 windows_rename_src
,
13251 windows_rename_dst
,
13252 nt_errstr(status
));
13256 /* Does 'foo' still exist ? */
13257 status
= cli_posix_open(cli_posix
,
13262 if (!NT_STATUS_IS_OK(status
)) {
13263 printf("cli_posix_open O_RNONLY of %s returned %s\n",
13265 nt_errstr(status
));
13269 status
= cli_close(cli_posix
, fnum
);
13270 if (!NT_STATUS_IS_OK(status
)) {
13278 TALLOC_FREE(mangled_name
);
13279 TALLOC_FREE(windows_rename_src
);
13282 torture_deltree(cli
, dname
);
13283 torture_close_connection(cli
);
13286 torture_close_connection(cli_posix
);
13292 * Only testing minimal time strings, as the others
13293 * need (locale-dependent) guessing at what strftime does and
13294 * even may differ in builds.
13296 static bool timesubst_test(void)
13298 TALLOC_CTX
*ctx
= NULL
;
13299 /* Sa 23. Dez 04:33:20 CET 2017 */
13300 const struct timeval tv
= { 1514000000, 123 };
13301 const char* expect_minimal
= "20171223_033320";
13302 const char* expect_minus
= "20171223_033320_000123";
13304 char *env_tz
, *orig_tz
= NULL
;
13305 bool result
= true;
13307 ctx
= talloc_new(NULL
);
13309 env_tz
= getenv("TZ");
13311 orig_tz
= talloc_strdup(ctx
, env_tz
);
13313 setenv("TZ", "UTC", 1);
13315 s
= minimal_timeval_string(ctx
, &tv
, false);
13317 if(!s
|| strcmp(s
, expect_minimal
)) {
13318 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
13319 "[%s]\n", s
? s
: "<nil>", expect_minimal
);
13323 s
= minimal_timeval_string(ctx
, &tv
, true);
13324 if(!s
|| strcmp(s
, expect_minus
)) {
13325 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
13326 "[%s]\n", s
? s
: "<nil>", expect_minus
);
13332 setenv("TZ", orig_tz
, 1);
13339 static bool run_local_substitute(int dummy
)
13343 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
13344 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
13345 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
13346 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
13347 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
13348 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
13349 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
13350 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
13351 ok
&= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
13352 /* Substitution depends on current time, so better test the underlying
13353 formatting function. At least covers %t. */
13354 ok
&= timesubst_test();
13356 /* Different captialization rules in sub_basic... */
13358 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
13364 static bool run_local_base64(int dummy
)
13369 for (i
=1; i
<2000; i
++) {
13370 DATA_BLOB blob1
, blob2
;
13373 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
13375 generate_random_buffer(blob1
.data
, blob1
.length
);
13377 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
13379 d_fprintf(stderr
, "base64_encode_data_blob failed "
13380 "for %d bytes\n", i
);
13383 blob2
= base64_decode_data_blob(b64
);
13386 if (data_blob_cmp(&blob1
, &blob2
)) {
13387 d_fprintf(stderr
, "data_blob_cmp failed for %d "
13391 TALLOC_FREE(blob1
.data
);
13392 data_blob_free(&blob2
);
13397 static void parse_fn(const struct gencache_timeout
*t
,
13399 void *private_data
)
13404 static bool run_local_gencache(int dummy
)
13410 struct memcache
*mem
;
13413 mem
= memcache_init(NULL
, 0);
13415 d_printf("%s: memcache_init failed\n", __location__
);
13418 memcache_set_global(mem
);
13420 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
13421 d_printf("%s: gencache_set() failed\n", __location__
);
13425 if (!gencache_get("foo", NULL
, NULL
, NULL
)) {
13426 d_printf("%s: gencache_get() failed\n", __location__
);
13430 for (i
=0; i
<1000000; i
++) {
13431 gencache_parse("foo", parse_fn
, NULL
);
13434 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
13435 d_printf("%s: gencache_get() failed\n", __location__
);
13440 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
13441 d_printf("%s: gencache_get() failed\n", __location__
);
13445 if (strcmp(val
, "bar") != 0) {
13446 d_printf("%s: gencache_get() returned %s, expected %s\n",
13447 __location__
, val
, "bar");
13454 if (!gencache_del("foo")) {
13455 d_printf("%s: gencache_del() failed\n", __location__
);
13458 if (gencache_del("foo")) {
13459 d_printf("%s: second gencache_del() succeeded\n",
13464 if (gencache_get("foo", talloc_tos(), &val
, &tm
)) {
13465 d_printf("%s: gencache_get() on deleted entry "
13466 "succeeded\n", __location__
);
13470 blob
= data_blob_string_const_null("bar");
13471 tm
= time(NULL
) + 60;
13473 if (!gencache_set_data_blob("foo", blob
, tm
)) {
13474 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
13478 if (!gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
13479 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
13483 if (strcmp((const char *)blob
.data
, "bar") != 0) {
13484 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
13485 __location__
, (const char *)blob
.data
, "bar");
13486 data_blob_free(&blob
);
13490 data_blob_free(&blob
);
13492 if (!gencache_del("foo")) {
13493 d_printf("%s: gencache_del() failed\n", __location__
);
13496 if (gencache_del("foo")) {
13497 d_printf("%s: second gencache_del() succeeded\n",
13502 if (gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
13503 d_printf("%s: gencache_get_data_blob() on deleted entry "
13504 "succeeded\n", __location__
);
13509 blob
.data
= (uint8_t *)&v
;
13510 blob
.length
= sizeof(v
);
13512 if (!gencache_set_data_blob("blob", blob
, tm
)) {
13513 d_printf("%s: gencache_set_data_blob() failed\n",
13517 if (gencache_get("blob", talloc_tos(), &val
, &tm
)) {
13518 d_printf("%s: gencache_get succeeded\n", __location__
);
13525 static bool rbt_testflags(struct db_context
*db
, const char *key
,
13530 struct db_record
*rec
;
13532 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
13534 d_fprintf(stderr
, "fetch_locked failed\n");
13538 status
= dbwrap_record_store(rec
, string_tdb_data(value
), TDB_MODIFY
);
13539 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
13540 d_fprintf(stderr
, "store TDB_MODIFY unexpected status: %s\n",
13541 nt_errstr(status
));
13545 status
= dbwrap_record_store(rec
, string_tdb_data("overwriteme"),
13547 if (!NT_STATUS_IS_OK(status
)) {
13548 d_fprintf(stderr
, "store TDB_INSERT failed: %s\n",
13549 nt_errstr(status
));
13553 status
= dbwrap_record_store(rec
, string_tdb_data(value
), TDB_INSERT
);
13554 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_COLLISION
)) {
13555 d_fprintf(stderr
, "store TDB_INSERT unexpected status: %s\n",
13556 nt_errstr(status
));
13560 status
= dbwrap_record_store(rec
, string_tdb_data(value
), TDB_MODIFY
);
13561 if (!NT_STATUS_IS_OK(status
)) {
13562 d_fprintf(stderr
, "store TDB_MODIFY failed: %s\n",
13563 nt_errstr(status
));
13573 static bool rbt_testval(struct db_context
*db
, const char *key
,
13576 struct db_record
*rec
;
13577 TDB_DATA data
= string_tdb_data(value
);
13582 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
13584 d_fprintf(stderr
, "fetch_locked failed\n");
13587 status
= dbwrap_record_store(rec
, data
, 0);
13588 if (!NT_STATUS_IS_OK(status
)) {
13589 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
13594 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
13596 d_fprintf(stderr
, "second fetch_locked failed\n");
13600 dbvalue
= dbwrap_record_get_value(rec
);
13601 if ((dbvalue
.dsize
!= data
.dsize
)
13602 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
13603 d_fprintf(stderr
, "Got wrong data back\n");
13613 static int local_rbtree_traverse_read(struct db_record
*rec
, void *private_data
)
13615 int *count2
= (int *)private_data
;
13620 static int local_rbtree_traverse_delete(struct db_record
*rec
, void *private_data
)
13622 int *count2
= (int *)private_data
;
13624 dbwrap_record_delete(rec
);
13628 static bool run_local_rbtree(int dummy
)
13630 struct db_context
*db
;
13637 db
= db_open_rbt(NULL
);
13640 d_fprintf(stderr
, "db_open_rbt failed\n");
13644 if (!rbt_testflags(db
, "firstkey", "firstval")) {
13648 for (i
= 0; i
< 999; i
++) {
13649 char key
[sizeof("key-9223372036854775807-1234")];
13650 char value
[sizeof("value-9223372036854775807-1234")];
13652 snprintf(key
, sizeof(key
), "key%ld-%d", random(), i
);
13653 snprintf(value
, sizeof(value
) ,"value%ld-%d", random(), i
);
13655 if (!rbt_testval(db
, key
, value
)) {
13659 snprintf(value
, sizeof(value
) ,"value%ld-%d", random(), i
+ 1);
13661 if (!rbt_testval(db
, key
, value
)) {
13667 count
= 0; count2
= 0;
13668 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
13670 printf("%s: read1: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
13671 if ((count
!= count2
) || (count
!= 1000)) {
13674 count
= 0; count2
= 0;
13675 status
= dbwrap_traverse(db
, local_rbtree_traverse_delete
,
13677 printf("%s: delete: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
13678 if ((count
!= count2
) || (count
!= 1000)) {
13681 count
= 0; count2
= 0;
13682 status
= dbwrap_traverse_read(db
, local_rbtree_traverse_read
,
13684 printf("%s: read2: %d %d, %s\n", __func__
, count
, count2
, nt_errstr(status
));
13685 if ((count
!= count2
) || (count
!= 0)) {
13696 local test for character set functions
13698 This is a very simple test for the functionality in convert_string_error()
13700 static bool run_local_convert_string(int dummy
)
13702 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
13703 const char *test_strings
[2] = { "March", "M\303\244rz" };
13707 for (i
=0; i
<2; i
++) {
13708 const char *str
= test_strings
[i
];
13709 int len
= strlen(str
);
13710 size_t converted_size
;
13713 memset(dst
, 'X', sizeof(dst
));
13715 /* first try with real source length */
13716 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
13721 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
13725 if (converted_size
!= len
) {
13726 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
13727 str
, len
, (int)converted_size
);
13731 if (strncmp(str
, dst
, converted_size
) != 0) {
13732 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
13736 if (strlen(str
) != converted_size
) {
13737 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
13738 (int)strlen(str
), (int)converted_size
);
13742 if (dst
[converted_size
] != 'X') {
13743 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
13747 /* now with srclen==-1, this causes the nul to be
13749 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
13754 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
13758 if (converted_size
!= len
+1) {
13759 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
13760 str
, len
, (int)converted_size
);
13764 if (strncmp(str
, dst
, converted_size
) != 0) {
13765 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
13769 if (len
+1 != converted_size
) {
13770 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
13771 len
+1, (int)converted_size
);
13775 if (dst
[converted_size
] != 'X') {
13776 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
13783 TALLOC_FREE(tmp_ctx
);
13786 TALLOC_FREE(tmp_ctx
);
13790 static bool run_local_string_to_sid(int dummy
) {
13791 struct dom_sid sid
;
13793 if (string_to_sid(&sid
, "S--1-5-32-545")) {
13794 printf("allowing S--1-5-32-545\n");
13797 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
13798 printf("allowing S-1-5-32-+545\n");
13801 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")) {
13802 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
13805 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
13806 printf("allowing S-1-5-32-545-abc\n");
13809 if (string_to_sid(&sid
, "S-300-5-32-545")) {
13810 printf("allowing S-300-5-32-545\n");
13813 if (string_to_sid(&sid
, "S-1-0xfffffffffffffe-32-545")) {
13814 printf("allowing S-1-0xfffffffffffffe-32-545\n");
13817 if (string_to_sid(&sid
, "S-1-0xffffffffffff-5294967297-545")) {
13818 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
13821 if (!string_to_sid(&sid
, "S-1-0xfffffffffffe-32-545")) {
13822 printf("could not parse S-1-0xfffffffffffe-32-545\n");
13825 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
13826 printf("could not parse S-1-5-32-545\n");
13829 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
13830 struct dom_sid_buf buf
;
13831 printf("mis-parsed S-1-5-32-545 as %s\n",
13832 dom_sid_str_buf(&sid
, &buf
));
13838 static bool sid_to_string_test(const char *expected
) {
13841 struct dom_sid sid
;
13843 if (!string_to_sid(&sid
, expected
)) {
13844 printf("could not parse %s\n", expected
);
13848 str
= dom_sid_string(NULL
, &sid
);
13849 if (strcmp(str
, expected
)) {
13850 printf("Comparison failed (%s != %s)\n", str
, expected
);
13857 static bool run_local_sid_to_string(int dummy
) {
13858 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
13860 if (!sid_to_string_test("S-1-545"))
13862 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
13867 static bool run_local_binary_to_sid(int dummy
) {
13869 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
13870 static const uint8_t good_binary_sid
[] = {
13871 0x1, /* revision number */
13872 15, /* num auths */
13873 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
13874 0x1, 0x1, 0x1, 0x1, /* auth[0] */
13875 0x1, 0x1, 0x1, 0x1, /* auth[1] */
13876 0x1, 0x1, 0x1, 0x1, /* auth[2] */
13877 0x1, 0x1, 0x1, 0x1, /* auth[3] */
13878 0x1, 0x1, 0x1, 0x1, /* auth[4] */
13879 0x1, 0x1, 0x1, 0x1, /* auth[5] */
13880 0x1, 0x1, 0x1, 0x1, /* auth[6] */
13881 0x1, 0x1, 0x1, 0x1, /* auth[7] */
13882 0x1, 0x1, 0x1, 0x1, /* auth[8] */
13883 0x1, 0x1, 0x1, 0x1, /* auth[9] */
13884 0x1, 0x1, 0x1, 0x1, /* auth[10] */
13885 0x1, 0x1, 0x1, 0x1, /* auth[11] */
13886 0x1, 0x1, 0x1, 0x1, /* auth[12] */
13887 0x1, 0x1, 0x1, 0x1, /* auth[13] */
13888 0x1, 0x1, 0x1, 0x1, /* auth[14] */
13891 static const uint8_t long_binary_sid
[] = {
13892 0x1, /* revision number */
13893 15, /* num auths */
13894 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
13895 0x1, 0x1, 0x1, 0x1, /* auth[0] */
13896 0x1, 0x1, 0x1, 0x1, /* auth[1] */
13897 0x1, 0x1, 0x1, 0x1, /* auth[2] */
13898 0x1, 0x1, 0x1, 0x1, /* auth[3] */
13899 0x1, 0x1, 0x1, 0x1, /* auth[4] */
13900 0x1, 0x1, 0x1, 0x1, /* auth[5] */
13901 0x1, 0x1, 0x1, 0x1, /* auth[6] */
13902 0x1, 0x1, 0x1, 0x1, /* auth[7] */
13903 0x1, 0x1, 0x1, 0x1, /* auth[8] */
13904 0x1, 0x1, 0x1, 0x1, /* auth[9] */
13905 0x1, 0x1, 0x1, 0x1, /* auth[10] */
13906 0x1, 0x1, 0x1, 0x1, /* auth[11] */
13907 0x1, 0x1, 0x1, 0x1, /* auth[12] */
13908 0x1, 0x1, 0x1, 0x1, /* auth[13] */
13909 0x1, 0x1, 0x1, 0x1, /* auth[14] */
13910 0x1, 0x1, 0x1, 0x1, /* auth[15] */
13911 0x1, 0x1, 0x1, 0x1, /* auth[16] */
13912 0x1, 0x1, 0x1, 0x1, /* auth[17] */
13915 static const uint8_t long_binary_sid2
[] = {
13916 0x1, /* revision number */
13917 32, /* num auths */
13918 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
13919 0x1, 0x1, 0x1, 0x1, /* auth[0] */
13920 0x1, 0x1, 0x1, 0x1, /* auth[1] */
13921 0x1, 0x1, 0x1, 0x1, /* auth[2] */
13922 0x1, 0x1, 0x1, 0x1, /* auth[3] */
13923 0x1, 0x1, 0x1, 0x1, /* auth[4] */
13924 0x1, 0x1, 0x1, 0x1, /* auth[5] */
13925 0x1, 0x1, 0x1, 0x1, /* auth[6] */
13926 0x1, 0x1, 0x1, 0x1, /* auth[7] */
13927 0x1, 0x1, 0x1, 0x1, /* auth[8] */
13928 0x1, 0x1, 0x1, 0x1, /* auth[9] */
13929 0x1, 0x1, 0x1, 0x1, /* auth[10] */
13930 0x1, 0x1, 0x1, 0x1, /* auth[11] */
13931 0x1, 0x1, 0x1, 0x1, /* auth[12] */
13932 0x1, 0x1, 0x1, 0x1, /* auth[13] */
13933 0x1, 0x1, 0x1, 0x1, /* auth[14] */
13934 0x1, 0x1, 0x1, 0x1, /* auth[15] */
13935 0x1, 0x1, 0x1, 0x1, /* auth[16] */
13936 0x1, 0x1, 0x1, 0x1, /* auth[17] */
13937 0x1, 0x1, 0x1, 0x1, /* auth[18] */
13938 0x1, 0x1, 0x1, 0x1, /* auth[19] */
13939 0x1, 0x1, 0x1, 0x1, /* auth[20] */
13940 0x1, 0x1, 0x1, 0x1, /* auth[21] */
13941 0x1, 0x1, 0x1, 0x1, /* auth[22] */
13942 0x1, 0x1, 0x1, 0x1, /* auth[23] */
13943 0x1, 0x1, 0x1, 0x1, /* auth[24] */
13944 0x1, 0x1, 0x1, 0x1, /* auth[25] */
13945 0x1, 0x1, 0x1, 0x1, /* auth[26] */
13946 0x1, 0x1, 0x1, 0x1, /* auth[27] */
13947 0x1, 0x1, 0x1, 0x1, /* auth[28] */
13948 0x1, 0x1, 0x1, 0x1, /* auth[29] */
13949 0x1, 0x1, 0x1, 0x1, /* auth[30] */
13950 0x1, 0x1, 0x1, 0x1, /* auth[31] */
13953 ret
= sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
);
13957 ret
= sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
);
13961 ret
= sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
);
13968 /* Split a path name into filename and stream name components. Canonicalise
13969 * such that an implicit $DATA token is always explicit.
13971 * The "specification" of this function can be found in the
13972 * run_local_stream_name() function in torture.c, I've tried those
13973 * combinations against a W2k3 server.
13976 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
13977 char **pbase
, char **pstream
)
13980 char *stream
= NULL
;
13981 char *sname
; /* stream name */
13982 const char *stype
; /* stream type */
13984 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
13986 sname
= strchr_m(fname
, ':');
13988 if (sname
== NULL
) {
13989 if (pbase
!= NULL
) {
13990 base
= talloc_strdup(mem_ctx
, fname
);
13991 NT_STATUS_HAVE_NO_MEMORY(base
);
13996 if (pbase
!= NULL
) {
13997 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
13998 NT_STATUS_HAVE_NO_MEMORY(base
);
14003 stype
= strchr_m(sname
, ':');
14005 if (stype
== NULL
) {
14006 sname
= talloc_strdup(mem_ctx
, sname
);
14010 if (strcasecmp_m(stype
, ":$DATA") != 0) {
14012 * If there is an explicit stream type, so far we only
14013 * allow $DATA. Is there anything else allowed? -- vl
14015 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
14017 return NT_STATUS_OBJECT_NAME_INVALID
;
14019 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
14023 if (sname
== NULL
) {
14025 return NT_STATUS_NO_MEMORY
;
14028 if (sname
[0] == '\0') {
14030 * no stream name, so no stream
14035 if (pstream
!= NULL
) {
14036 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
14037 if (stream
== NULL
) {
14038 TALLOC_FREE(sname
);
14040 return NT_STATUS_NO_MEMORY
;
14043 * upper-case the type field
14045 (void)strupper_m(strchr_m(stream
, ':')+1);
14049 if (pbase
!= NULL
) {
14052 if (pstream
!= NULL
) {
14055 return NT_STATUS_OK
;
14058 static bool test_stream_name(const char *fname
, const char *expected_base
,
14059 const char *expected_stream
,
14060 NTSTATUS expected_status
)
14064 char *stream
= NULL
;
14066 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
14067 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
14071 if (!NT_STATUS_IS_OK(status
)) {
14075 if (base
== NULL
) goto error
;
14077 if (strcmp(expected_base
, base
) != 0) goto error
;
14079 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
14080 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
14082 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
14086 TALLOC_FREE(stream
);
14090 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
14091 fname
, expected_base
? expected_base
: "<NULL>",
14092 expected_stream
? expected_stream
: "<NULL>",
14093 nt_errstr(expected_status
));
14094 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
14095 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
14096 nt_errstr(status
));
14098 TALLOC_FREE(stream
);
14102 static bool run_local_stream_name(int dummy
)
14106 ret
&= test_stream_name(
14107 "bla", "bla", NULL
, NT_STATUS_OK
);
14108 ret
&= test_stream_name(
14109 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
14110 ret
&= test_stream_name(
14111 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
14112 ret
&= test_stream_name(
14113 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
14114 ret
&= test_stream_name(
14115 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
14116 ret
&= test_stream_name(
14117 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
14118 ret
&= test_stream_name(
14119 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
14120 ret
&= test_stream_name(
14121 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
14126 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
14128 if (a
.length
!= b
.length
) {
14129 printf("a.length=%d != b.length=%d\n",
14130 (int)a
.length
, (int)b
.length
);
14133 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
14134 printf("a.data and b.data differ\n");
14140 static bool run_local_memcache(int dummy
)
14142 struct memcache
*cache
;
14143 DATA_BLOB k1
, k2
, k3
, k4
, k5
;
14147 TALLOC_CTX
*mem_ctx
;
14153 size_t size1
, size2
;
14156 mem_ctx
= talloc_init("foo");
14157 if (mem_ctx
== NULL
) {
14161 /* STAT_CACHE TESTS */
14163 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
14165 if (cache
== NULL
) {
14166 printf("memcache_init failed\n");
14170 d1
= data_blob_const("d1", 2);
14171 d3
= data_blob_const("d3", 2);
14173 k1
= data_blob_const("d1", 2);
14174 k2
= data_blob_const("d2", 2);
14175 k3
= data_blob_const("d3", 2);
14176 k4
= data_blob_const("d4", 2);
14177 k5
= data_blob_const("d5", 2);
14179 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
14181 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
14182 printf("could not find k1\n");
14185 if (!data_blob_equal(d1
, v1
)) {
14189 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
14191 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
14192 printf("could not find replaced k1\n");
14195 if (!data_blob_equal(d3
, v3
)) {
14199 TALLOC_FREE(cache
);
14201 /* GETWD_CACHE TESTS */
14202 str1
= talloc_strdup(mem_ctx
, "string1");
14203 if (str1
== NULL
) {
14206 ptr2
= str1
; /* Keep an alias for comparison. */
14208 str2
= talloc_strdup(mem_ctx
, "string2");
14209 if (str2
== NULL
) {
14213 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
14214 if (cache
== NULL
) {
14215 printf("memcache_init failed\n");
14219 memcache_add_talloc(cache
, GETWD_CACHE
, k2
, &str1
);
14220 /* str1 == NULL now. */
14221 ptr1
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
14222 if (ptr1
== NULL
) {
14223 printf("could not find k2\n");
14226 if (ptr1
!= ptr2
) {
14227 printf("fetch of k2 got wrong string\n");
14231 /* Add a blob to ensure k2 gets purged. */
14232 d3
= data_blob_talloc_zero(mem_ctx
, 180);
14233 memcache_add(cache
, STAT_CACHE
, k3
, d3
);
14235 ptr2
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k2
);
14236 if (ptr2
!= NULL
) {
14237 printf("Did find k2, should have been purged\n");
14242 * Test that talloc size also is accounted in memcache and
14243 * causes purge of other object.
14246 str1
= talloc_zero_size(mem_ctx
, 100);
14247 str2
= talloc_zero_size(mem_ctx
, 100);
14249 memcache_add_talloc(cache
, GETWD_CACHE
, k4
, &str1
);
14250 memcache_add_talloc(cache
, GETWD_CACHE
, k5
, &str1
);
14252 ptr3
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k4
);
14253 if (ptr3
!= NULL
) {
14254 printf("Did find k4, should have been purged\n");
14259 * Test that adding a duplicate non-talloced
14260 * key/value on top of a talloced key/value takes account
14261 * of the talloc_freed value size.
14263 TALLOC_FREE(cache
);
14264 TALLOC_FREE(mem_ctx
);
14266 mem_ctx
= talloc_init("key_replace");
14267 if (mem_ctx
== NULL
) {
14271 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
14272 if (cache
== NULL
) {
14277 * Add a 100 byte talloced string. This will
14278 * store a (4 or 8 byte) pointer and record the
14279 * total talloced size.
14281 str1
= talloc_zero_size(mem_ctx
, 100);
14282 memcache_add_talloc(cache
, GETWD_CACHE
, k4
, &str1
);
14284 * Now overwrite with a small talloced
14285 * value. This should fit in the existing size
14286 * and the total talloced size should be removed
14287 * from the cache size.
14289 str1
= talloc_zero_size(mem_ctx
, 2);
14290 memcache_add_talloc(cache
, GETWD_CACHE
, k4
, &str1
);
14292 * Now store a 20 byte string. If the
14293 * total talloced size wasn't accounted for
14294 * and removed in the overwrite, then this
14297 str2
= talloc_zero_size(mem_ctx
, 20);
14298 memcache_add_talloc(cache
, GETWD_CACHE
, k5
, &str2
);
14300 ptr3
= memcache_lookup_talloc(cache
, GETWD_CACHE
, k4
);
14301 if (ptr3
== NULL
) {
14302 printf("Did not find k4, should not have been purged\n");
14306 TALLOC_FREE(cache
);
14307 TALLOC_FREE(mem_ctx
);
14309 mem_ctx
= talloc_init("foo");
14310 if (mem_ctx
== NULL
) {
14314 cache
= memcache_init(NULL
, 0);
14315 if (cache
== NULL
) {
14319 str1
= talloc_strdup(mem_ctx
, "string1");
14320 if (str1
== NULL
) {
14323 str2
= talloc_strdup(mem_ctx
, "string2");
14324 if (str2
== NULL
) {
14327 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
14328 data_blob_string_const("torture"), &str1
);
14329 size1
= talloc_total_size(cache
);
14331 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
14332 data_blob_string_const("torture"), &str2
);
14333 size2
= talloc_total_size(cache
);
14335 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
14337 if (size2
> size1
) {
14338 printf("memcache leaks memory!\n");
14344 TALLOC_FREE(cache
);
14348 static void wbclient_done(struct tevent_req
*req
)
14351 struct winbindd_response
*wb_resp
;
14352 int *i
= (int *)tevent_req_callback_data_void(req
);
14354 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
14357 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
14360 static bool run_wbclient_multi_ping(int dummy
)
14362 struct tevent_context
*ev
;
14363 struct wb_context
**wb_ctx
;
14364 struct winbindd_request wb_req
;
14365 bool result
= false;
14368 BlockSignals(True
, SIGPIPE
);
14370 ev
= tevent_context_init(talloc_tos());
14375 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
14376 if (wb_ctx
== NULL
) {
14380 ZERO_STRUCT(wb_req
);
14381 wb_req
.cmd
= WINBINDD_PING
;
14383 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
14385 for (i
=0; i
<torture_nprocs
; i
++) {
14386 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
14387 if (wb_ctx
[i
] == NULL
) {
14390 for (j
=0; j
<torture_numops
; j
++) {
14391 struct tevent_req
*req
;
14392 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
14393 (j
% 2) == 0, &wb_req
);
14397 tevent_req_set_callback(req
, wbclient_done
, &i
);
14403 while (i
< torture_nprocs
* torture_numops
) {
14404 tevent_loop_once(ev
);
14413 static bool dbtrans_inc(struct db_context
*db
)
14415 struct db_record
*rec
;
14421 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
14423 printf(__location__
"fetch_lock failed\n");
14427 value
= dbwrap_record_get_value(rec
);
14429 if (value
.dsize
!= sizeof(uint32_t)) {
14430 printf(__location__
"value.dsize = %d\n",
14435 memcpy(&val
, value
.dptr
, sizeof(val
));
14438 status
= dbwrap_record_store(
14439 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
14440 if (!NT_STATUS_IS_OK(status
)) {
14441 printf(__location__
"store failed: %s\n",
14442 nt_errstr(status
));
14452 static bool run_local_dbtrans(int dummy
)
14454 struct db_context
*db
;
14455 struct db_record
*rec
;
14461 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
14462 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
,
14465 printf("Could not open transtest.db\n");
14469 res
= dbwrap_transaction_start(db
);
14471 printf(__location__
"transaction_start failed\n");
14475 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
14477 printf(__location__
"fetch_lock failed\n");
14481 value
= dbwrap_record_get_value(rec
);
14483 if (value
.dptr
== NULL
) {
14485 status
= dbwrap_record_store(
14486 rec
, make_tdb_data((uint8_t *)&initial
,
14489 if (!NT_STATUS_IS_OK(status
)) {
14490 printf(__location__
"store returned %s\n",
14491 nt_errstr(status
));
14498 res
= dbwrap_transaction_commit(db
);
14500 printf(__location__
"transaction_commit failed\n");
14505 uint32_t val
, val2
;
14508 res
= dbwrap_transaction_start(db
);
14510 printf(__location__
"transaction_start failed\n");
14514 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val
);
14515 if (!NT_STATUS_IS_OK(status
)) {
14516 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
14517 nt_errstr(status
));
14521 for (i
=0; i
<10; i
++) {
14522 if (!dbtrans_inc(db
)) {
14527 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val2
);
14528 if (!NT_STATUS_IS_OK(status
)) {
14529 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
14530 nt_errstr(status
));
14534 if (val2
!= val
+ 10) {
14535 printf(__location__
"val=%d, val2=%d\n",
14536 (int)val
, (int)val2
);
14540 printf("val2=%d\r", val2
);
14542 res
= dbwrap_transaction_commit(db
);
14544 printf(__location__
"transaction_commit failed\n");
14554 * Just a dummy test to be run under a debugger. There's no real way
14555 * to inspect the tevent_poll specific function from outside of
14559 static bool run_local_tevent_poll(int dummy
)
14561 struct tevent_context
*ev
;
14562 struct tevent_fd
*fd1
, *fd2
;
14563 bool result
= false;
14565 ev
= tevent_context_init_byname(NULL
, "poll");
14567 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
14571 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
14573 d_fprintf(stderr
, "tevent_add_fd failed\n");
14576 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
14578 d_fprintf(stderr
, "tevent_add_fd failed\n");
14583 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
14585 d_fprintf(stderr
, "tevent_add_fd failed\n");
14595 static bool run_local_hex_encode_buf(int dummy
)
14601 for (i
=0; i
<sizeof(src
); i
++) {
14604 hex_encode_buf(buf
, src
, sizeof(src
));
14605 if (strcmp(buf
, "0001020304050607") != 0) {
14608 hex_encode_buf(buf
, NULL
, 0);
14609 if (buf
[0] != '\0') {
14615 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
14637 "1001:1111:1111:1000:0:1111:1111:1111",
14646 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
14660 "1001:1111:1111:1000:0:1111:1111:1111"
14663 static bool run_local_remove_duplicate_addrs2(int dummy
)
14665 struct samba_sockaddr test_vector
[28];
14668 /* Construct the sockaddr_storage test vector. */
14669 for (i
= 0; i
< 28; i
++) {
14670 struct addrinfo hints
;
14671 struct addrinfo
*res
= NULL
;
14674 memset(&hints
, '\0', sizeof(hints
));
14675 hints
.ai_flags
= AI_NUMERICHOST
;
14676 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
14681 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
14682 remove_duplicate_addrs2_test_strings_vector
[i
]);
14685 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
14686 memcpy(&test_vector
[i
].u
.ss
,
14692 count
= remove_duplicate_addrs2(test_vector
, i
);
14695 fprintf(stderr
, "count wrong (%zu) should be 14\n",
14700 for (i
= 0; i
< count
; i
++) {
14701 char addr
[INET6_ADDRSTRLEN
];
14703 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].u
.ss
);
14705 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
14706 fprintf(stderr
, "mismatch on [%zu] [%s] [%s]\n",
14709 remove_duplicate_addrs2_test_strings_result
[i
]);
14714 printf("run_local_remove_duplicate_addrs2: success\n");
14718 static bool run_local_tdb_opener(int dummy
)
14724 t
= tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST
,
14725 O_RDWR
|O_CREAT
, 0755);
14727 perror("tdb_open failed");
14738 static bool run_local_tdb_writer(int dummy
)
14744 t
= tdb_open("test.tdb", 1000, 0, O_RDWR
|O_CREAT
, 0755);
14746 perror("tdb_open failed");
14750 val
.dptr
= (uint8_t *)&v
;
14751 val
.dsize
= sizeof(v
);
14757 ret
= tdb_store(t
, val
, val
, 0);
14759 printf("%s\n", tdb_errorstr(t
));
14764 data
= tdb_fetch(t
, val
);
14765 if (data
.dptr
!= NULL
) {
14766 SAFE_FREE(data
.dptr
);
14772 static bool run_local_canonicalize_path(int dummy
)
14774 const char *src
[] = {
14781 ".././././../../../boo",
14793 "/foo/bar/../baz/",
14794 "////////////////",
14795 "/////////./././././.",
14796 "/./.././../.boo/../baz",
14797 "/a/component/path",
14798 "/a/component/path/",
14799 "/a/component/path/..",
14800 "/a/component/../path/",
14801 "///a/./././///component/../////path/",
14804 const char *dst
[] = {
14827 "/a/component/path",
14828 "/a/component/path",
14836 for (i
= 0; src
[i
] != NULL
; i
++) {
14837 char *d
= canonicalize_absolute_path(talloc_tos(), src
[i
]);
14839 perror("talloc fail\n");
14842 if (strcmp(d
, dst
[i
]) != 0) {
14844 "canonicalize mismatch %s -> %s != %s",
14845 src
[i
], d
, dst
[i
]);
14852 struct session_setup_nt1_truncated_state
{
14857 static void smb1_session_setup_nt1_truncated_done(struct tevent_req
*subreq
);
14859 static struct tevent_req
*smb1_session_setup_nt1_truncated_send(
14860 TALLOC_CTX
*mem_ctx
,
14861 struct tevent_context
*ev
,
14862 struct smbXcli_conn
*conn
)
14864 uint16_t *vwv
= NULL
;
14865 uint8_t *bytes
= NULL
;
14866 const char *pass
= "12345678";
14867 const char *uname
= "z";
14868 struct session_setup_nt1_truncated_state
*state
= NULL
;
14869 struct tevent_req
*req
= NULL
;
14870 struct tevent_req
*subreq
= NULL
;
14872 req
= tevent_req_create(mem_ctx
,
14874 struct session_setup_nt1_truncated_state
);
14878 vwv
= &state
->vwv
[0];
14879 bytes
= &state
->bytes
[0];
14881 SCVAL(vwv
+0, 0, 0xff);
14882 SCVAL(vwv
+0, 1, 0);
14883 SSVAL(vwv
+1, 0, 0);
14884 SSVAL(vwv
+2, 0, 8192);
14885 SSVAL(vwv
+3, 0, 2);
14886 SSVAL(vwv
+4, 0, 1);
14887 SIVAL(vwv
+5, 0, 0);
14888 SSVAL(vwv
+7, 0, strlen(pass
)); /* OEMPasswordLen */
14889 SSVAL(vwv
+8, 0, 0); /* UnicodePasswordLen */
14890 SSVAL(vwv
+9, 0, 0); /* reserved */
14891 SSVAL(vwv
+10, 0, 0); /* reserved */
14892 SIVAL(vwv
+11, 0, CAP_STATUS32
);
14894 memcpy(bytes
, pass
, strlen(pass
));
14895 bytes
+= strlen(pass
);
14896 memcpy(bytes
, uname
, strlen(uname
)+1);
14898 subreq
= smb1cli_req_send(state
, ev
, conn
,
14900 0, /* additional_flags */
14901 0, /* clear_flags */
14902 0, /* additional_flags2 */
14903 0, /* clear_flags2 */
14904 10000, /* timeout_msec */
14907 NULL
, /* session */
14910 strlen(pass
), /* Truncate length at password. */
14912 if (tevent_req_nomem(subreq
, req
)) {
14913 return tevent_req_post(req
, ev
);
14915 tevent_req_set_callback(subreq
,
14916 smb1_session_setup_nt1_truncated_done
,
14921 static void smb1_session_setup_nt1_truncated_done(struct tevent_req
*subreq
)
14923 struct tevent_req
*req
=
14924 tevent_req_callback_data(subreq
,
14925 struct tevent_req
);
14926 struct session_setup_nt1_truncated_state
*state
=
14927 tevent_req_data(req
,
14928 struct session_setup_nt1_truncated_state
);
14930 struct smb1cli_req_expected_response expected
[] = {
14932 .status
= NT_STATUS_OK
,
14937 status
= smb1cli_req_recv(subreq
, state
,
14942 NULL
, /* pvwv_offset */
14945 NULL
, /* pbytes_offset */
14947 expected
, ARRAY_SIZE(expected
));
14948 TALLOC_FREE(subreq
);
14949 if (tevent_req_nterror(req
, status
)) {
14952 tevent_req_done(req
);
14955 static NTSTATUS
smb1_session_setup_nt1_truncated_recv(struct tevent_req
*req
)
14957 return tevent_req_simple_recv_ntstatus(req
);
14960 static bool run_smb1_truncated_sesssetup(int dummy
)
14962 struct tevent_context
*ev
;
14963 struct tevent_req
*req
;
14964 struct smbXcli_conn
*conn
;
14965 struct sockaddr_storage ss
;
14970 printf("Starting send truncated SMB1 sesssetup.\n");
14972 ok
= resolve_name(host
, &ss
, 0x20, true);
14974 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
14978 status
= open_socket_out(&ss
, 445, 10000, &fd
);
14979 if (!NT_STATUS_IS_OK(status
)) {
14980 d_fprintf(stderr
, "open_socket_out failed: %s\n",
14981 nt_errstr(status
));
14985 conn
= smbXcli_conn_create(talloc_tos(), fd
, host
, SMB_SIGNING_OFF
, 0,
14987 if (conn
== NULL
) {
14988 d_fprintf(stderr
, "smbXcli_conn_create failed\n");
14992 status
= smbXcli_negprot(conn
,
14999 if (!NT_STATUS_IS_OK(status
)) {
15000 d_fprintf(stderr
, "smbXcli_negprot failed!\n");
15004 ev
= samba_tevent_context_init(talloc_tos());
15006 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
15010 req
= smb1_session_setup_nt1_truncated_send(ev
, ev
, conn
);
15012 d_fprintf(stderr
, "smb1_session_setup_nt1_truncated_send failed\n");
15016 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
15018 d_fprintf(stderr
, "tevent_req_poll failed with status %s\n",
15019 nt_errstr(status
));
15023 status
= smb1_session_setup_nt1_truncated_recv(req
);
15024 if (!NT_STATUS_IS_OK(status
)) {
15025 d_fprintf(stderr
, "smb1_session_setup_nt1_truncated_recv returned "
15026 "%s, expected NT_STATUS_OK\n",
15027 nt_errstr(status
));
15035 struct smb1_negotiate_exit_state
{
15039 static void smb1_negotiate_exit_done(struct tevent_req
*subreq
);
15041 static struct tevent_req
*smb1_negotiate_exit_send(
15042 TALLOC_CTX
*mem_ctx
,
15043 struct tevent_context
*ev
,
15044 struct smbXcli_conn
*conn
)
15046 struct smb1_negotiate_exit_state
*state
= NULL
;
15047 struct tevent_req
*req
= NULL
;
15048 struct tevent_req
*subreq
= NULL
;
15050 req
= tevent_req_create(mem_ctx
,
15052 struct smb1_negotiate_exit_state
);
15056 subreq
= smb1cli_req_send(state
, ev
, conn
,
15058 0, /* additional_flags */
15059 0, /* clear_flags */
15060 0, /* additional_flags2 */
15061 0, /* clear_flags2 */
15062 10000, /* timeout_msec */
15065 NULL
, /* session */
15070 if (tevent_req_nomem(subreq
, req
)) {
15071 return tevent_req_post(req
, ev
);
15073 tevent_req_set_callback(subreq
,
15074 smb1_negotiate_exit_done
,
15079 static void smb1_negotiate_exit_done(struct tevent_req
*subreq
)
15081 struct tevent_req
*req
=
15082 tevent_req_callback_data(subreq
,
15083 struct tevent_req
);
15084 struct smb1_negotiate_exit_state
*state
=
15085 tevent_req_data(req
,
15086 struct smb1_negotiate_exit_state
);
15088 struct smb1cli_req_expected_response expected
[] = {
15090 .status
= NT_STATUS_OK
,
15095 status
= smb1cli_req_recv(subreq
, state
,
15100 NULL
, /* pvwv_offset */
15103 NULL
, /* pbytes_offset */
15105 expected
, ARRAY_SIZE(expected
));
15106 TALLOC_FREE(subreq
);
15107 if (tevent_req_nterror(req
, status
)) {
15110 tevent_req_done(req
);
15113 static NTSTATUS
smb1_negotiate_exit_recv(struct tevent_req
*req
)
15115 return tevent_req_simple_recv_ntstatus(req
);
15118 static bool do_smb1_exit(TALLOC_CTX
*mem_ctx
,
15119 struct tevent_context
*ev
,
15120 struct smbXcli_conn
*conn
)
15122 struct tevent_req
*req
;
15125 NTSTATUS expected_status
= NT_STATUS_DOS(ERRSRV
, ERRinvnid
);;
15127 req
= smb1_negotiate_exit_send(ev
, ev
, conn
);
15129 d_fprintf(stderr
, "smb1_negotiate_exit_send failed\n");
15133 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
15135 d_fprintf(stderr
, "tevent_req_poll failed with status %s\n",
15136 nt_errstr(status
));
15140 status
= smb1_negotiate_exit_recv(req
);
15141 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
15142 d_fprintf(stderr
, "smb1_negotiate_exit_recv returned "
15143 "%s, expected ERRSRV, ERRinvnid\n",
15144 nt_errstr(status
));
15150 static bool run_smb1_negotiate_exit(int dummy
)
15152 struct tevent_context
*ev
;
15153 struct smbXcli_conn
*conn
;
15154 struct sockaddr_storage ss
;
15159 printf("Starting send SMB1 negotiate+exit.\n");
15161 ok
= resolve_name(host
, &ss
, 0x20, true);
15163 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
15167 status
= open_socket_out(&ss
, 445, 10000, &fd
);
15168 if (!NT_STATUS_IS_OK(status
)) {
15169 d_fprintf(stderr
, "open_socket_out failed: %s\n",
15170 nt_errstr(status
));
15174 conn
= smbXcli_conn_create(talloc_tos(), fd
, host
, SMB_SIGNING_OFF
, 0,
15176 if (conn
== NULL
) {
15177 d_fprintf(stderr
, "smbXcli_conn_create failed\n");
15181 status
= smbXcli_negprot(conn
,
15188 if (!NT_STATUS_IS_OK(status
)) {
15189 d_fprintf(stderr
, "smbXcli_negprot failed!\n");
15193 ev
= samba_tevent_context_init(talloc_tos());
15195 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
15200 * Call do_smb1_exit twice to catch a server crash, the
15201 * server sends the first return code then crashes.
15203 ok
= do_smb1_exit(ev
, ev
, conn
);
15205 d_fprintf(stderr
, "do_smb1_exit (1) failed\n");
15208 ok
= do_smb1_exit(ev
, ev
, conn
);
15210 d_fprintf(stderr
, "do_smb1_exit (2) failed\n");
15218 static bool run_smb1_negotiate_tcon(int dummy
)
15220 struct cli_state
*cli
= NULL
;
15222 uint16_t max_xmit
= 0;
15225 printf("Starting send SMB1 negotiate+tcon.\n");
15226 cli
= open_nbt_connection();
15228 d_fprintf(stderr
, "open_nbt_connection failed!\n");
15231 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
15233 status
= smbXcli_negprot(cli
->conn
,
15240 if (!NT_STATUS_IS_OK(status
)) {
15241 d_fprintf(stderr
, "smbXcli_negprot failed %s!\n",
15242 nt_errstr(status
));
15245 status
= cli_raw_tcon(cli
,
15251 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
15252 d_fprintf(stderr
, "cli_raw_tcon failed - got %s "
15253 "(should get NT_STATUS_ACCESS_DENIED)!\n",
15254 nt_errstr(status
));
15260 static bool run_ign_bad_negprot(int dummy
)
15262 struct tevent_context
*ev
;
15263 struct tevent_req
*req
;
15264 struct smbXcli_conn
*conn
;
15265 struct sockaddr_storage ss
;
15270 printf("starting ignore bad negprot\n");
15272 ok
= resolve_name(host
, &ss
, 0x20, true);
15274 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
15278 status
= open_socket_out(&ss
, 445, 10000, &fd
);
15279 if (!NT_STATUS_IS_OK(status
)) {
15280 d_fprintf(stderr
, "open_socket_out failed: %s\n",
15281 nt_errstr(status
));
15285 conn
= smbXcli_conn_create(talloc_tos(), fd
, host
, SMB_SIGNING_OFF
, 0,
15287 if (conn
== NULL
) {
15288 d_fprintf(stderr
, "smbXcli_conn_create failed\n");
15292 status
= smbXcli_negprot(conn
,
15299 if (NT_STATUS_IS_OK(status
)) {
15300 d_fprintf(stderr
, "smbXcli_negprot succeeded!\n");
15304 ev
= samba_tevent_context_init(talloc_tos());
15306 d_fprintf(stderr
, "samba_tevent_context_init failed\n");
15310 req
= smb1cli_session_setup_nt1_send(
15311 ev
, ev
, conn
, 0, getpid(), NULL
, 65503, 2, 1, 0, "", "",
15312 data_blob_null
, data_blob_null
, 0x40,
15313 "Windows 2000 2195", "Windows 2000 5.0");
15315 d_fprintf(stderr
, "smb1cli_session_setup_nt1_send failed\n");
15319 ok
= tevent_req_poll_ntstatus(req
, ev
, &status
);
15321 d_fprintf(stderr
, "tevent_req_poll failed\n");
15325 status
= smb1cli_session_setup_nt1_recv(req
, NULL
, NULL
, NULL
, NULL
,
15327 if (!NT_STATUS_EQUAL(status
, NT_STATUS_CONNECTION_RESET
)) {
15328 d_fprintf(stderr
, "smb1cli_session_setup_nt1_recv returned "
15329 "%s, expected NT_STATUS_CONNECTION_RESET\n",
15330 nt_errstr(status
));
15336 printf("starting ignore bad negprot\n");
15342 static double create_procs(bool (*fn
)(int), bool *result
)
15345 volatile pid_t
*child_status
;
15346 volatile bool *child_status_out
;
15349 struct timeval start
;
15353 child_status
= (volatile pid_t
*)anonymous_shared_allocate(sizeof(pid_t
)*torture_nprocs
);
15354 if (!child_status
) {
15355 printf("Failed to setup shared memory\n");
15359 child_status_out
= (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs
);
15360 if (!child_status_out
) {
15361 printf("Failed to setup result status shared memory\n");
15365 for (i
= 0; i
< torture_nprocs
; i
++) {
15366 child_status
[i
] = 0;
15367 child_status_out
[i
] = True
;
15370 start
= timeval_current();
15372 for (i
=0;i
<torture_nprocs
;i
++) {
15375 pid_t mypid
= getpid();
15376 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
15378 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
15381 if (torture_open_connection(¤t_cli
, i
)) break;
15382 if (tries
-- == 0) {
15383 printf("pid %d failed to start\n", (int)getpid());
15389 child_status
[i
] = getpid();
15391 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
15393 child_status_out
[i
] = fn(i
);
15400 for (i
=0;i
<torture_nprocs
;i
++) {
15401 if (child_status
[i
]) synccount
++;
15403 if (synccount
== torture_nprocs
) break;
15405 } while (timeval_elapsed(&start
) < 30);
15407 if (synccount
!= torture_nprocs
) {
15408 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
15410 return timeval_elapsed(&start
);
15413 /* start the client load */
15414 start
= timeval_current();
15416 for (i
=0;i
<torture_nprocs
;i
++) {
15417 child_status
[i
] = 0;
15420 printf("%d clients started\n", torture_nprocs
);
15422 for (i
=0;i
<torture_nprocs
;i
++) {
15423 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
15428 for (i
=0;i
<torture_nprocs
;i
++) {
15429 if (!child_status_out
[i
]) {
15433 return timeval_elapsed(&start
);
15436 #define FLAG_MULTIPROC 1
15442 } torture_ops
[] = {
15445 .fn
= run_fdpasstest
,
15449 .fn
= run_locktest1
,
15453 .fn
= run_locktest2
,
15457 .fn
= run_locktest3
,
15461 .fn
= run_locktest4
,
15465 .fn
= run_locktest5
,
15469 .fn
= run_locktest6
,
15473 .fn
= run_locktest7
,
15477 .fn
= run_locktest8
,
15481 .fn
= run_locktest9a
,
15485 .fn
= run_locktest9b
,
15489 .fn
= run_locktest10
,
15493 .fn
= run_locktest11
,
15497 .fn
= run_locktest12
,
15501 .fn
= run_locktest13
,
15505 .fn
= run_unlinktest
,
15509 .fn
= run_browsetest
,
15513 .fn
= run_attrtest
,
15517 .fn
= run_trans2test
,
15521 .fn
= run_maxfidtest
,
15522 .flags
= FLAG_MULTIPROC
,
15527 .flags
= FLAG_MULTIPROC
,
15530 .name
= "RANDOMIPC",
15531 .fn
= run_randomipc
,
15534 .name
= "NEGNOWAIT",
15535 .fn
= run_negprot_nowait
,
15557 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
15569 .fn
= run_dirtest1
,
15572 .name
= "DIR-CREATETIME",
15573 .fn
= run_dir_createtime
,
15577 .fn
= torture_denytest1
,
15581 .fn
= torture_denytest2
,
15585 .fn
= run_tcon_test
,
15589 .fn
= run_tcon_devtype_test
,
15593 .fn
= run_readwritetest
,
15597 .fn
= run_readwritemulti
,
15598 .flags
= FLAG_MULTIPROC
15602 .fn
= run_readwritelarge
,
15605 .name
= "RW-SIGNING",
15606 .fn
= run_readwritelarge_signtest
,
15610 .fn
= run_opentest
,
15614 .fn
= run_simple_posix_open_test
,
15617 .name
= "POSIX-APPEND",
15618 .fn
= run_posix_append
,
15621 .name
= "POSIX-SYMLINK-ACL",
15622 .fn
= run_acl_symlink_test
,
15625 .name
= "POSIX-SYMLINK-EA",
15626 .fn
= run_ea_symlink_test
,
15629 .name
= "POSIX-STREAM-DELETE",
15630 .fn
= run_posix_stream_delete
,
15633 .name
= "POSIX-OFD-LOCK",
15634 .fn
= run_posix_ofd_lock_test
,
15637 .name
= "POSIX-BLOCKING-LOCK",
15638 .fn
= run_posix_blocking_lock
,
15641 .name
= "POSIX-MKDIR",
15642 .fn
= run_posix_mkdir_test
,
15645 .name
= "POSIX-ACL-OPLOCK",
15646 .fn
= run_posix_acl_oplock_test
,
15649 .name
= "POSIX-ACL-SHAREROOT",
15650 .fn
= run_posix_acl_shareroot_test
,
15653 .name
= "POSIX-LS-WILDCARD",
15654 .fn
= run_posix_ls_wildcard_test
,
15657 .name
= "POSIX-LS-SINGLE",
15658 .fn
= run_posix_ls_single_test
,
15661 .name
= "POSIX-READLINK",
15662 .fn
= run_posix_readlink_test
,
15665 .name
= "POSIX-STAT",
15666 .fn
= run_posix_stat_test
,
15669 .name
= "POSIX-SYMLINK-PARENT",
15670 .fn
= run_posix_symlink_parent_test
,
15673 .name
= "POSIX-SYMLINK-CHMOD",
15674 .fn
= run_posix_symlink_chmod_test
,
15677 .name
= "POSIX-SYMLINK-RENAME",
15678 .fn
= run_posix_symlink_rename_test
,
15681 .name
= "POSIX-DIR-DEFAULT-ACL",
15682 .fn
= run_posix_dir_default_acl_test
,
15685 .name
= "POSIX-SYMLINK-GETPATHINFO",
15686 .fn
= run_posix_symlink_getpathinfo_test
,
15689 .name
= "POSIX-SYMLINK-SETPATHINFO",
15690 .fn
= run_posix_symlink_setpathinfo_test
,
15693 .name
= "WINDOWS-BAD-SYMLINK",
15694 .fn
= run_symlink_open_test
,
15697 .name
= "SMB1-WILD-MANGLE-UNLINK",
15698 .fn
= run_smb1_wild_mangle_unlink_test
,
15701 .name
= "SMB1-WILD-MANGLE-RENAME",
15702 .fn
= run_smb1_wild_mangle_rename_test
,
15705 .name
= "CASE-INSENSITIVE-CREATE",
15706 .fn
= run_case_insensitive_create
,
15709 .name
= "ASYNC-ECHO",
15710 .fn
= run_async_echo
,
15713 .name
= "UID-REGRESSION-TEST",
15714 .fn
= run_uid_regression_test
,
15717 .name
= "SHORTNAME-TEST",
15718 .fn
= run_shortname_test
,
15721 .name
= "ADDRCHANGE",
15722 .fn
= run_addrchange
,
15726 .name
= "OPENATTR",
15727 .fn
= run_openattrtest
,
15739 .name
= "RENAME-ACCESS",
15740 .fn
= run_rename_access
,
15743 .name
= "OWNER-RIGHTS",
15744 .fn
= run_owner_rights
,
15748 .fn
= run_deletetest
,
15751 .name
= "DELETE-STREAM",
15752 .fn
= run_delete_stream
,
15755 .name
= "DELETE-PRINT",
15756 .fn
= run_delete_print_test
,
15759 .name
= "DELETE-LN",
15760 .fn
= run_deletetest_ln
,
15763 .name
= "PROPERTIES",
15764 .fn
= run_properties
,
15768 .fn
= torture_mangle
,
15775 .name
= "MANGLE-ILLEGAL",
15776 .fn
= run_mangle_illegal
,
15783 .name
= "TRANS2SCAN",
15784 .fn
= torture_trans2_scan
,
15787 .name
= "NTTRANSSCAN",
15788 .fn
= torture_nttrans_scan
,
15792 .fn
= torture_utable
,
15795 .name
= "CASETABLE",
15796 .fn
= torture_casetable
,
15799 .name
= "ERRMAPEXTRACT",
15800 .fn
= run_error_map_extract
,
15803 .name
= "PIPE_NUMBER",
15804 .fn
= run_pipe_number
,
15808 .fn
= run_tcon2_test
,
15812 .fn
= torture_ioctl_test
,
15816 .fn
= torture_chkpath_test
,
15820 .fn
= run_fdsesstest
,
15827 .name
= "SESSSETUP_BENCH",
15828 .fn
= run_sesssetup_bench
,
15843 .name
= "WINDOWS-WRITE",
15844 .fn
= run_windows_write
,
15847 .name
= "LARGE_READX",
15848 .fn
= run_large_readx
,
15851 .name
= "MSDFS-ATTRIBUTE",
15852 .fn
= run_msdfs_attribute
,
15855 .name
= "NTTRANS-CREATE",
15856 .fn
= run_nttrans_create
,
15859 .name
= "NTTRANS-FSCTL",
15860 .fn
= run_nttrans_fsctl
,
15863 .name
= "CLI_ECHO",
15864 .fn
= run_cli_echo
,
15867 .name
= "CLI_SPLICE",
15868 .fn
= run_cli_splice
,
15875 .name
= "STREAMERROR",
15876 .fn
= run_streamerror
,
15879 .name
= "NOTIFY-BENCH",
15880 .fn
= run_notify_bench
,
15883 .name
= "NOTIFY-BENCH2",
15884 .fn
= run_notify_bench2
,
15887 .name
= "NOTIFY-BENCH3",
15888 .fn
= run_notify_bench3
,
15891 .name
= "BAD-NBT-SESSION",
15892 .fn
= run_bad_nbt_session
,
15895 .name
= "IGN-BAD-NEGPROT",
15896 .fn
= run_ign_bad_negprot
,
15899 .name
= "SMB-ANY-CONNECT",
15900 .fn
= run_smb_any_connect
,
15903 .name
= "NOTIFY-ONLINE",
15904 .fn
= run_notify_online
,
15907 .name
= "SMB2-BASIC",
15908 .fn
= run_smb2_basic
,
15911 .name
= "SMB2-NEGPROT",
15912 .fn
= run_smb2_negprot
,
15915 .name
= "SMB2-ANONYMOUS",
15916 .fn
= run_smb2_anonymous
,
15919 .name
= "SMB2-SESSION-RECONNECT",
15920 .fn
= run_smb2_session_reconnect
,
15923 .name
= "SMB2-TCON-DEPENDENCE",
15924 .fn
= run_smb2_tcon_dependence
,
15927 .name
= "SMB2-MULTI-CHANNEL",
15928 .fn
= run_smb2_multi_channel
,
15931 .name
= "SMB2-SESSION-REAUTH",
15932 .fn
= run_smb2_session_reauth
,
15935 .name
= "SMB2-FTRUNCATE",
15936 .fn
= run_smb2_ftruncate
,
15939 .name
= "SMB2-DIR-FSYNC",
15940 .fn
= run_smb2_dir_fsync
,
15943 .name
= "SMB2-PATH-SLASH",
15944 .fn
= run_smb2_path_slash
,
15947 .name
= "SMB1-SYSTEM-SECURITY",
15948 .fn
= run_smb1_system_security
,
15951 .name
= "SMB2-SACL",
15952 .fn
= run_smb2_sacl
,
15955 .name
= "SMB2-QUOTA1",
15956 .fn
= run_smb2_quota1
,
15959 .name
= "SMB2-INVALID-PIPENAME",
15960 .fn
= run_smb2_invalid_pipename
,
15963 .name
= "SMB2-STREAM-ACL",
15964 .fn
= run_smb2_stream_acl
,
15967 .name
= "SMB2-LIST-DIR-ASYNC",
15968 .fn
= run_list_dir_async_test
,
15971 .name
= "SMB2-DEL-ON-CLOSE-NONEMPTY",
15972 .fn
= run_delete_on_close_non_empty
,
15975 .name
= "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
15976 .fn
= run_delete_on_close_nonwrite_delete_yes_test
,
15979 .name
= "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
15980 .fn
= run_delete_on_close_nonwrite_delete_no_test
,
15983 .name
= "SMB2-DFS-PATHS",
15984 .fn
= run_smb2_dfs_paths
,
15987 .name
= "SMB2-NON-DFS-SHARE",
15988 .fn
= run_smb2_non_dfs_share
,
15991 .name
= "SMB2-DFS-SHARE-NON-DFS-PATH",
15992 .fn
= run_smb2_dfs_share_non_dfs_path
,
15995 .name
= "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
15996 .fn
= run_smb2_dfs_filename_leading_backslash
,
15999 .name
= "SMB2-PIPE-READ-ASYNC-DISCONNECT",
16000 .fn
= run_smb2_pipe_read_async_disconnect
,
16003 .name
= "SMB1-TRUNCATED-SESSSETUP",
16004 .fn
= run_smb1_truncated_sesssetup
,
16007 .name
= "SMB1-NEGOTIATE-EXIT",
16008 .fn
= run_smb1_negotiate_exit
,
16011 .name
= "SMB1-NEGOTIATE-TCON",
16012 .fn
= run_smb1_negotiate_tcon
,
16015 .name
= "SMB1-DFS-PATHS",
16016 .fn
= run_smb1_dfs_paths
,
16019 .name
= "SMB1-DFS-SEARCH-PATHS",
16020 .fn
= run_smb1_dfs_search_paths
,
16023 .name
= "SMB1-DFS-OPERATIONS",
16024 .fn
= run_smb1_dfs_operations
,
16027 .name
= "SMB1-DFS-BADPATH",
16028 .fn
= run_smb1_dfs_check_badpath
,
16031 .name
= "CLEANUP1",
16032 .fn
= run_cleanup1
,
16035 .name
= "CLEANUP2",
16036 .fn
= run_cleanup2
,
16039 .name
= "CLEANUP4",
16040 .fn
= run_cleanup4
,
16043 .name
= "OPLOCK-CANCEL",
16044 .fn
= run_oplock_cancel
,
16051 .name
= "LOCAL-SUBSTITUTE",
16052 .fn
= run_local_substitute
,
16055 .name
= "LOCAL-GENCACHE",
16056 .fn
= run_local_gencache
,
16059 .name
= "LOCAL-DBWRAP-WATCH1",
16060 .fn
= run_dbwrap_watch1
,
16063 .name
= "LOCAL-DBWRAP-WATCH2",
16064 .fn
= run_dbwrap_watch2
,
16067 .name
= "LOCAL-DBWRAP-WATCH3",
16068 .fn
= run_dbwrap_watch3
,
16071 .name
= "LOCAL-DBWRAP-WATCH4",
16072 .fn
= run_dbwrap_watch4
,
16075 .name
= "LOCAL-DBWRAP-DO-LOCKED1",
16076 .fn
= run_dbwrap_do_locked1
,
16079 .name
= "LOCAL-MESSAGING-READ1",
16080 .fn
= run_messaging_read1
,
16083 .name
= "LOCAL-MESSAGING-READ2",
16084 .fn
= run_messaging_read2
,
16087 .name
= "LOCAL-MESSAGING-READ3",
16088 .fn
= run_messaging_read3
,
16091 .name
= "LOCAL-MESSAGING-READ4",
16092 .fn
= run_messaging_read4
,
16095 .name
= "LOCAL-MESSAGING-FDPASS1",
16096 .fn
= run_messaging_fdpass1
,
16099 .name
= "LOCAL-MESSAGING-FDPASS2",
16100 .fn
= run_messaging_fdpass2
,
16103 .name
= "LOCAL-MESSAGING-FDPASS2a",
16104 .fn
= run_messaging_fdpass2a
,
16107 .name
= "LOCAL-MESSAGING-FDPASS2b",
16108 .fn
= run_messaging_fdpass2b
,
16111 .name
= "LOCAL-MESSAGING-SEND-ALL",
16112 .fn
= run_messaging_send_all
,
16115 .name
= "LOCAL-BASE64",
16116 .fn
= run_local_base64
,
16119 .name
= "LOCAL-RBTREE",
16120 .fn
= run_local_rbtree
,
16123 .name
= "LOCAL-MEMCACHE",
16124 .fn
= run_local_memcache
,
16127 .name
= "LOCAL-STREAM-NAME",
16128 .fn
= run_local_stream_name
,
16131 .name
= "LOCAL-STR-MATCH-MSWILD",
16132 .fn
= run_str_match_mswild
,
16135 .name
= "LOCAL-STR-MATCH-REGEX-SUB1",
16136 .fn
= run_str_match_regex_sub1
,
16139 .name
= "WBCLIENT-MULTI-PING",
16140 .fn
= run_wbclient_multi_ping
,
16143 .name
= "LOCAL-string_to_sid",
16144 .fn
= run_local_string_to_sid
,
16147 .name
= "LOCAL-sid_to_string",
16148 .fn
= run_local_sid_to_string
,
16151 .name
= "LOCAL-binary_to_sid",
16152 .fn
= run_local_binary_to_sid
,
16155 .name
= "LOCAL-DBTRANS",
16156 .fn
= run_local_dbtrans
,
16159 .name
= "LOCAL-TEVENT-POLL",
16160 .fn
= run_local_tevent_poll
,
16163 .name
= "LOCAL-CONVERT-STRING",
16164 .fn
= run_local_convert_string
,
16167 .name
= "LOCAL-CONV-AUTH-INFO",
16168 .fn
= run_local_conv_auth_info
,
16171 .name
= "LOCAL-hex_encode_buf",
16172 .fn
= run_local_hex_encode_buf
,
16175 .name
= "LOCAL-IDMAP-TDB-COMMON",
16176 .fn
= run_idmap_tdb_common_test
,
16179 .name
= "LOCAL-remove_duplicate_addrs2",
16180 .fn
= run_local_remove_duplicate_addrs2
,
16183 .name
= "local-tdb-opener",
16184 .fn
= run_local_tdb_opener
,
16187 .name
= "local-tdb-writer",
16188 .fn
= run_local_tdb_writer
,
16191 .name
= "LOCAL-DBWRAP-CTDB1",
16192 .fn
= run_local_dbwrap_ctdb1
,
16195 .name
= "LOCAL-BENCH-PTHREADPOOL",
16196 .fn
= run_bench_pthreadpool
,
16199 .name
= "LOCAL-PTHREADPOOL-TEVENT",
16200 .fn
= run_pthreadpool_tevent
,
16203 .name
= "LOCAL-G-LOCK1",
16207 .name
= "LOCAL-G-LOCK2",
16211 .name
= "LOCAL-G-LOCK3",
16215 .name
= "LOCAL-G-LOCK4",
16219 .name
= "LOCAL-G-LOCK4A",
16220 .fn
= run_g_lock4a
,
16223 .name
= "LOCAL-G-LOCK5",
16227 .name
= "LOCAL-G-LOCK6",
16231 .name
= "LOCAL-G-LOCK7",
16235 .name
= "LOCAL-G-LOCK8",
16239 .name
= "LOCAL-G-LOCK-PING-PONG",
16240 .fn
= run_g_lock_ping_pong
,
16243 .name
= "LOCAL-CANONICALIZE-PATH",
16244 .fn
= run_local_canonicalize_path
,
16247 .name
= "LOCAL-NAMEMAP-CACHE1",
16248 .fn
= run_local_namemap_cache1
,
16251 .name
= "LOCAL-IDMAP-CACHE1",
16252 .fn
= run_local_idmap_cache1
,
16255 .name
= "qpathinfo-bufsize",
16256 .fn
= run_qpathinfo_bufsize
,
16259 .name
= "hide-new-files-timeout",
16260 .fn
= run_hidenewfiles
,
16263 .name
= "hide-new-files-timeout-showdirs",
16264 .fn
= run_hidenewfiles_showdirs
,
16266 #ifdef CLUSTER_SUPPORT
16268 .name
= "ctdbd-conn1",
16269 .fn
= run_ctdbd_conn1
,
16273 .name
= "readdir-timestamp",
16274 .fn
= run_readdir_timestamp
,
16277 .name
= "rpc-scale",
16278 .fn
= run_rpc_scale
,
16281 .name
= "LOCAL-TDB-VALIDATE",
16282 .fn
= run_tdb_validate
,
16289 /****************************************************************************
16290 run a specified test or "ALL"
16291 ****************************************************************************/
16292 static bool run_test(const char *name
)
16295 bool result
= True
;
16296 bool found
= False
;
16299 if (strequal(name
,"ALL")) {
16300 for (i
=0;torture_ops
[i
].name
;i
++) {
16301 run_test(torture_ops
[i
].name
);
16306 for (i
=0;torture_ops
[i
].name
;i
++) {
16307 fstr_sprintf(randomfname
, "\\XX%x",
16308 (unsigned)random());
16310 if (strequal(name
, torture_ops
[i
].name
)) {
16312 printf("Running %s\n", name
);
16313 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
16314 t
= create_procs(torture_ops
[i
].fn
, &result
);
16317 printf("TEST %s FAILED!\n", name
);
16320 struct timeval start
;
16321 start
= timeval_current();
16322 if (!torture_ops
[i
].fn(0)) {
16324 printf("TEST %s FAILED!\n", name
);
16326 t
= timeval_elapsed(&start
);
16328 printf("%s took %g secs\n\n", name
, t
);
16333 printf("Did not find a test named %s\n", name
);
16341 static void usage(void)
16345 printf("WARNING samba4 test suite is much more complete nowadays.\n");
16346 printf("Please use samba4 torture.\n\n");
16348 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
16350 printf("\t-d debuglevel\n");
16351 printf("\t-U user%%pass\n");
16352 printf("\t-k use kerberos\n");
16353 printf("\t-N numprocs\n");
16354 printf("\t-n my_netbios_name\n");
16355 printf("\t-W workgroup\n");
16356 printf("\t-o num_operations\n");
16357 printf("\t-O socket_options\n");
16358 printf("\t-m maximum protocol\n");
16359 printf("\t-L use oplocks\n");
16360 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
16361 printf("\t-A showall\n");
16362 printf("\t-p port\n");
16363 printf("\t-s seed\n");
16364 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
16365 printf("\t-f filename filename to test\n");
16366 printf("\t-e encrypt\n");
16367 printf("\t-T 'OPTION=VALUE' smb.conf option line\n");
16370 printf("tests are:");
16371 for (i
=0;torture_ops
[i
].name
;i
++) {
16372 printf(" %s", torture_ops
[i
].name
);
16376 printf("default test is ALL\n");
16381 /****************************************************************************
16383 ****************************************************************************/
16384 int main(int argc
,char *argv
[])
16390 bool correct
= True
;
16391 TALLOC_CTX
*frame
= talloc_stackframe();
16392 int seed
= time(NULL
);
16393 struct loadparm_context
*lp_ctx
= NULL
;
16395 #ifdef HAVE_SETBUFFER
16396 setbuffer(stdout
, NULL
, 0);
16399 setup_logging("smbtorture", DEBUG_STDOUT
);
16404 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
16405 if (lp_ctx
== NULL
) {
16407 "Failed to initialise the global parameter structure.\n");
16411 if (is_default_dyn_CONFIGFILE()) {
16412 if(getenv("SMB_CONF_PATH")) {
16413 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
16416 lp_load_global(get_dyn_CONFIGFILE());
16423 for(p
= argv
[1]; *p
; p
++)
16427 if (strncmp(argv
[1], "//", 2)) {
16431 fstrcpy(host
, &argv
[1][2]);
16432 p
= strchr_m(&host
[2],'/');
16437 fstrcpy(share
, p
+1);
16439 fstrcpy(myname
, get_myname(talloc_tos()));
16441 fprintf(stderr
, "Failed to get my hostname.\n");
16445 if (*username
== 0 && getenv("LOGNAME")) {
16446 fstrcpy(username
,getenv("LOGNAME"));
16452 fstrcpy(workgroup
, lp_workgroup());
16454 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:T:"))
16458 port_to_use
= atoi(optarg
);
16461 seed
= atoi(optarg
);
16464 fstrcpy(workgroup
,optarg
);
16467 lpcfg_set_cmdline(lp_ctx
, "client max protocol", optarg
);
16470 torture_nprocs
= atoi(optarg
);
16473 torture_numops
= atoi(optarg
);
16476 lpcfg_set_cmdline(lp_ctx
, "log level", optarg
);
16482 use_oplocks
= True
;
16485 local_path
= optarg
;
16488 torture_showall
= True
;
16491 fstrcpy(myname
, optarg
);
16494 client_txt
= optarg
;
16501 use_kerberos
= True
;
16503 d_printf("No kerberos support compiled in\n");
16509 fstrcpy(username
,optarg
);
16510 p
= strchr_m(username
,'%');
16513 fstrcpy(password
, p
+1);
16518 fstrcpy(multishare_conn_fname
, optarg
);
16519 use_multishare_conn
= True
;
16522 torture_blocksize
= atoi(optarg
);
16525 test_filename
= SMB_STRDUP(optarg
);
16528 lpcfg_set_option(lp_ctx
, optarg
);
16531 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
16536 d_printf("using seed %d\n", seed
);
16540 if(use_kerberos
&& !gotuser
) gotpass
= True
;
16543 char pwd
[256] = {0};
16546 rc
= samba_getpass("Password:", pwd
, sizeof(pwd
), false, false);
16548 fstrcpy(password
, pwd
);
16555 printf("host=%s share=%s user=%s myname=%s\n",
16556 host
, share
, username
, myname
);
16558 torture_creds
= cli_session_creds_init(frame
,
16564 false, /* fallback_after_kerberos */
16565 false, /* use_ccache */
16566 false); /* password_is_nt_hash */
16567 if (torture_creds
== NULL
) {
16568 d_printf("cli_session_creds_init() failed.\n");
16572 if (argc
== optind
) {
16573 correct
= run_test("ALL");
16575 for (i
=optind
;i
<argc
;i
++) {
16576 if (!run_test(argv
[i
])) {
16582 TALLOC_FREE(frame
);