2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/sys_rw_data.h"
49 fstring host
, workgroup
, share
, password
, username
, myname
;
50 static const char *sockops
="TCP_NODELAY";
52 static int port_to_use
=0;
53 int torture_numops
=100;
54 int torture_blocksize
=1024*1024;
55 static int procnum
; /* records process count number when forking */
56 static struct cli_state
*current_cli
;
57 static fstring randomfname
;
58 static bool use_oplocks
;
59 static bool use_level_II_oplocks
;
60 static const char *client_txt
= "client_oplocks.txt";
61 static bool disable_spnego
;
62 static bool use_kerberos
;
63 static bool force_dos_errors
;
64 static fstring multishare_conn_fname
;
65 static bool use_multishare_conn
= False
;
66 static bool do_encrypt
;
67 static const char *local_path
= NULL
;
68 static enum smb_signing_setting signing_state
= SMB_SIGNING_DEFAULT
;
71 bool torture_showall
= False
;
73 static double create_procs(bool (*fn
)(int), bool *result
);
75 /********************************************************************
76 Ensure a connection is encrypted.
77 ********************************************************************/
79 static bool force_cli_encryption(struct cli_state
*c
,
80 const char *sharename
)
82 uint16_t major
, minor
;
83 uint32_t caplow
, caphigh
;
86 if (!SERVER_HAS_UNIX_CIFS(c
)) {
87 d_printf("Encryption required and "
88 "server that doesn't support "
89 "UNIX extensions - failing connect\n");
93 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
95 if (!NT_STATUS_IS_OK(status
)) {
96 d_printf("Encryption required and "
97 "can't get UNIX CIFS extensions "
98 "version from server: %s\n", nt_errstr(status
));
102 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
103 d_printf("Encryption required and "
104 "share %s doesn't support "
105 "encryption.\n", sharename
);
109 if (c
->use_kerberos
) {
110 status
= cli_gss_smb_encryption_start(c
);
112 status
= cli_raw_ntlm_smb_encryption_start(c
,
118 if (!NT_STATUS_IS_OK(status
)) {
119 d_printf("Encryption required and "
120 "setup failed with error %s.\n",
129 static struct cli_state
*open_nbt_connection(void)
135 if (disable_spnego
) {
136 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
140 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
143 if (use_level_II_oplocks
) {
144 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
148 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
151 if (force_dos_errors
) {
152 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
155 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
156 signing_state
, flags
, &c
);
157 if (!NT_STATUS_IS_OK(status
)) {
158 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
162 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
167 /****************************************************************************
168 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
169 ****************************************************************************/
171 static bool cli_bad_session_request(int fd
,
172 struct nmb_name
*calling
, struct nmb_name
*called
)
181 uint8_t message_type
;
183 struct tevent_context
*ev
;
184 struct tevent_req
*req
;
186 frame
= talloc_stackframe();
188 iov
[0].iov_base
= len_buf
;
189 iov
[0].iov_len
= sizeof(len_buf
);
191 /* put in the destination name */
193 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
195 if (iov
[1].iov_base
== NULL
) {
198 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
199 talloc_get_size(iov
[1].iov_base
));
203 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
205 if (iov
[2].iov_base
== NULL
) {
208 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
209 talloc_get_size(iov
[2].iov_base
));
211 /* Deliberately corrupt the name len (first byte) */
212 *((uint8_t *)iov
[2].iov_base
) = 100;
214 /* send a session request (RFC 1002) */
215 /* setup the packet length
216 * Remove four bytes from the length count, since the length
217 * field in the NBT Session Service header counts the number
218 * of bytes which follow. The cli_send_smb() function knows
219 * about this and accounts for those four bytes.
223 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
224 SCVAL(len_buf
,0,0x81);
226 len
= write_data_iov(fd
, iov
, 3);
231 ev
= samba_tevent_context_init(frame
);
235 req
= read_smb_send(frame
, ev
, fd
);
239 if (!tevent_req_poll(req
, ev
)) {
242 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
249 message_type
= CVAL(inbuf
, 0);
250 if (message_type
!= 0x83) {
251 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
256 if (smb_len(inbuf
) != 1) {
257 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
258 (int)smb_len(inbuf
));
262 error
= CVAL(inbuf
, 4);
264 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
275 /* Insert a NULL at the first separator of the given path and return a pointer
276 * to the remainder of the string.
279 terminate_path_at_separator(char * path
)
287 if ((p
= strchr_m(path
, '/'))) {
292 if ((p
= strchr_m(path
, '\\'))) {
302 parse a //server/share type UNC name
304 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
305 char **hostname
, char **sharename
)
309 *hostname
= *sharename
= NULL
;
311 if (strncmp(unc_name
, "\\\\", 2) &&
312 strncmp(unc_name
, "//", 2)) {
316 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
317 p
= terminate_path_at_separator(*hostname
);
320 *sharename
= talloc_strdup(mem_ctx
, p
);
321 terminate_path_at_separator(*sharename
);
324 if (*hostname
&& *sharename
) {
328 TALLOC_FREE(*hostname
);
329 TALLOC_FREE(*sharename
);
333 static bool torture_open_connection_share(struct cli_state
**c
,
334 const char *hostname
,
335 const char *sharename
)
341 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
343 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
344 if (use_level_II_oplocks
)
345 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
347 status
= cli_full_connection(c
, myname
,
348 hostname
, NULL
, port_to_use
,
351 password
, flags
, signing_state
);
352 if (!NT_STATUS_IS_OK(status
)) {
353 printf("failed to open share connection: //%s/%s port:%d - %s\n",
354 hostname
, sharename
, port_to_use
, nt_errstr(status
));
358 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
361 return force_cli_encryption(*c
,
367 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
369 char **unc_list
= NULL
;
370 int num_unc_names
= 0;
373 if (use_multishare_conn
==True
) {
375 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
376 if (!unc_list
|| num_unc_names
<= 0) {
377 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
381 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
383 printf("Failed to parse UNC name %s\n",
384 unc_list
[conn_index
% num_unc_names
]);
385 TALLOC_FREE(unc_list
);
389 result
= torture_open_connection_share(c
, h
, s
);
391 /* h, s were copied earlier */
392 TALLOC_FREE(unc_list
);
396 return torture_open_connection_share(c
, host
, share
);
399 bool torture_init_connection(struct cli_state
**pcli
)
401 struct cli_state
*cli
;
403 cli
= open_nbt_connection();
412 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16_t *new_vuid
)
414 uint16_t old_vuid
= cli_state_get_uid(cli
);
415 size_t passlen
= strlen(password
);
419 cli_state_set_uid(cli
, 0);
420 status
= cli_session_setup(cli
, username
,
424 ret
= NT_STATUS_IS_OK(status
);
425 *new_vuid
= cli_state_get_uid(cli
);
426 cli_state_set_uid(cli
, old_vuid
);
431 bool torture_close_connection(struct cli_state
*c
)
436 status
= cli_tdis(c
);
437 if (!NT_STATUS_IS_OK(status
)) {
438 printf("tdis failed (%s)\n", nt_errstr(status
));
448 /* check if the server produced the expected dos or nt error code */
449 static bool check_both_error(int line
, NTSTATUS status
,
450 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
452 if (NT_STATUS_IS_DOS(status
)) {
456 /* Check DOS error */
457 cclass
= NT_STATUS_DOS_CLASS(status
);
458 num
= NT_STATUS_DOS_CODE(status
);
460 if (eclass
!= cclass
|| ecode
!= num
) {
461 printf("unexpected error code class=%d code=%d\n",
462 (int)cclass
, (int)num
);
463 printf(" expected %d/%d %s (line=%d)\n",
464 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
469 if (!NT_STATUS_EQUAL(nterr
, status
)) {
470 printf("unexpected error code %s\n",
472 printf(" expected %s (line=%d)\n",
473 nt_errstr(nterr
), line
);
482 /* check if the server produced the expected error code */
483 static bool check_error(int line
, NTSTATUS status
,
484 uint8_t eclass
, uint32_t ecode
, NTSTATUS nterr
)
486 if (NT_STATUS_IS_DOS(status
)) {
490 /* Check DOS error */
492 cclass
= NT_STATUS_DOS_CLASS(status
);
493 num
= NT_STATUS_DOS_CODE(status
);
495 if (eclass
!= cclass
|| ecode
!= num
) {
496 printf("unexpected error code class=%d code=%d\n",
497 (int)cclass
, (int)num
);
498 printf(" expected %d/%d %s (line=%d)\n",
499 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
507 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
508 printf("unexpected error code %s\n",
510 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
520 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
524 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
526 while (!NT_STATUS_IS_OK(status
)) {
527 if (!check_both_error(__LINE__
, status
, ERRDOS
,
528 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
532 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
539 static bool rw_torture(struct cli_state
*c
)
541 const char *lockfname
= "\\torture.lck";
545 pid_t pid2
, pid
= getpid();
552 memset(buf
, '\0', sizeof(buf
));
554 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
556 if (!NT_STATUS_IS_OK(status
)) {
557 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
559 if (!NT_STATUS_IS_OK(status
)) {
560 printf("open of %s failed (%s)\n",
561 lockfname
, nt_errstr(status
));
565 for (i
=0;i
<torture_numops
;i
++) {
566 unsigned n
= (unsigned)sys_random()%10;
569 printf("%d\r", i
); fflush(stdout
);
571 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
573 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
577 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
579 if (!NT_STATUS_IS_OK(status
)) {
580 printf("open failed (%s)\n", nt_errstr(status
));
585 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
587 if (!NT_STATUS_IS_OK(status
)) {
588 printf("write failed (%s)\n", nt_errstr(status
));
593 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
594 sizeof(pid
)+(j
*sizeof(buf
)),
596 if (!NT_STATUS_IS_OK(status
)) {
597 printf("write failed (%s)\n",
605 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
607 if (!NT_STATUS_IS_OK(status
)) {
608 printf("read failed (%s)\n", nt_errstr(status
));
610 } else if (nread
!= sizeof(pid
)) {
611 printf("read/write compare failed: "
612 "recv %ld req %ld\n", (unsigned long)nread
,
613 (unsigned long)sizeof(pid
));
618 printf("data corruption!\n");
622 status
= cli_close(c
, fnum
);
623 if (!NT_STATUS_IS_OK(status
)) {
624 printf("close failed (%s)\n", nt_errstr(status
));
628 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
629 if (!NT_STATUS_IS_OK(status
)) {
630 printf("unlink failed (%s)\n", nt_errstr(status
));
634 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
635 if (!NT_STATUS_IS_OK(status
)) {
636 printf("unlock failed (%s)\n", nt_errstr(status
));
642 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
649 static bool run_torture(int dummy
)
651 struct cli_state
*cli
;
656 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
658 ret
= rw_torture(cli
);
660 if (!torture_close_connection(cli
)) {
667 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
669 uint16_t fnum
= (uint16_t)-1;
674 unsigned countprev
= 0;
677 NTSTATUS status
= NT_STATUS_OK
;
680 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32_t))
682 SIVAL(buf
, i
, sys_random());
689 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
690 if (!NT_STATUS_IS_OK(status
)) {
691 printf("unlink failed (%s) (normal, this file should "
692 "not exist)\n", nt_errstr(status
));
695 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
697 if (!NT_STATUS_IS_OK(status
)) {
698 printf("first open read/write of %s failed (%s)\n",
699 lockfname
, nt_errstr(status
));
705 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
707 status
= cli_openx(c
, lockfname
, O_RDONLY
,
709 if (NT_STATUS_IS_OK(status
)) {
714 if (!NT_STATUS_IS_OK(status
)) {
715 printf("second open read-only of %s failed (%s)\n",
716 lockfname
, nt_errstr(status
));
722 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
724 if (count
>= countprev
) {
725 printf("%d %8d\r", i
, count
);
728 countprev
+= (sizeof(buf
) / 20);
733 sent
= ((unsigned)sys_random()%(20))+ 1;
734 if (sent
> sizeof(buf
) - count
)
736 sent
= sizeof(buf
) - count
;
739 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
741 if (!NT_STATUS_IS_OK(status
)) {
742 printf("write failed (%s)\n",
749 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
750 sizeof(buf
)-count
, &sent
);
751 if(!NT_STATUS_IS_OK(status
)) {
752 printf("read failed offset:%d size:%ld (%s)\n",
753 count
, (unsigned long)sizeof(buf
)-count
,
757 } else if (sent
> 0) {
758 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
760 printf("read/write compare failed\n");
761 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
770 status
= cli_close(c
, fnum
);
771 if (!NT_STATUS_IS_OK(status
)) {
772 printf("close failed (%s)\n", nt_errstr(status
));
779 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
781 const char *lockfname
= "\\torture2.lck";
791 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
792 if (!NT_STATUS_IS_OK(status
)) {
793 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
796 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
798 if (!NT_STATUS_IS_OK(status
)) {
799 printf("first open read/write of %s failed (%s)\n",
800 lockfname
, nt_errstr(status
));
804 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
805 if (!NT_STATUS_IS_OK(status
)) {
806 printf("second open read-only of %s failed (%s)\n",
807 lockfname
, nt_errstr(status
));
808 cli_close(c1
, fnum1
);
812 for (i
= 0; i
< torture_numops
; i
++)
814 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
816 printf("%d\r", i
); fflush(stdout
);
819 generate_random_buffer((unsigned char *)buf
, buf_size
);
821 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
823 if (!NT_STATUS_IS_OK(status
)) {
824 printf("write failed (%s)\n", nt_errstr(status
));
829 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
830 if(!NT_STATUS_IS_OK(status
)) {
831 printf("read failed (%s)\n", nt_errstr(status
));
834 } else if (bytes_read
!= buf_size
) {
835 printf("read failed\n");
836 printf("read %ld, expected %ld\n",
837 (unsigned long)bytes_read
,
838 (unsigned long)buf_size
);
843 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
845 printf("read/write compare failed\n");
851 status
= cli_close(c2
, fnum2
);
852 if (!NT_STATUS_IS_OK(status
)) {
853 printf("close failed (%s)\n", nt_errstr(status
));
857 status
= cli_close(c1
, fnum1
);
858 if (!NT_STATUS_IS_OK(status
)) {
859 printf("close failed (%s)\n", nt_errstr(status
));
863 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
864 if (!NT_STATUS_IS_OK(status
)) {
865 printf("unlink failed (%s)\n", nt_errstr(status
));
872 static bool run_readwritetest(int dummy
)
874 struct cli_state
*cli1
, *cli2
;
875 bool test1
, test2
= False
;
877 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
880 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
881 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
883 printf("starting readwritetest\n");
885 test1
= rw_torture2(cli1
, cli2
);
886 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
889 test2
= rw_torture2(cli1
, cli1
);
890 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
893 if (!torture_close_connection(cli1
)) {
897 if (!torture_close_connection(cli2
)) {
901 return (test1
&& test2
);
904 static bool run_readwritemulti(int dummy
)
906 struct cli_state
*cli
;
911 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
913 printf("run_readwritemulti: fname %s\n", randomfname
);
914 test
= rw_torture3(cli
, randomfname
);
916 if (!torture_close_connection(cli
)) {
923 static bool run_readwritelarge_internal(void)
925 static struct cli_state
*cli1
;
927 const char *lockfname
= "\\large.dat";
933 if (!torture_open_connection(&cli1
, 0)) {
936 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
937 memset(buf
,'\0',sizeof(buf
));
939 printf("starting readwritelarge_internal\n");
941 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
943 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
945 if (!NT_STATUS_IS_OK(status
)) {
946 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
950 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
952 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
954 if (!NT_STATUS_IS_OK(status
)) {
955 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
959 if (fsize
== sizeof(buf
))
960 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
961 (unsigned long)fsize
);
963 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
964 (unsigned long)fsize
);
968 status
= cli_close(cli1
, fnum1
);
969 if (!NT_STATUS_IS_OK(status
)) {
970 printf("close failed (%s)\n", nt_errstr(status
));
974 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
975 if (!NT_STATUS_IS_OK(status
)) {
976 printf("unlink failed (%s)\n", nt_errstr(status
));
980 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
982 if (!NT_STATUS_IS_OK(status
)) {
983 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
987 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
989 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
991 if (!NT_STATUS_IS_OK(status
)) {
992 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
996 if (fsize
== sizeof(buf
))
997 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
998 (unsigned long)fsize
);
1000 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1001 (unsigned long)fsize
);
1006 /* ToDo - set allocation. JRA */
1007 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1008 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1011 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1013 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1017 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1020 status
= cli_close(cli1
, fnum1
);
1021 if (!NT_STATUS_IS_OK(status
)) {
1022 printf("close failed (%s)\n", nt_errstr(status
));
1026 if (!torture_close_connection(cli1
)) {
1032 static bool run_readwritelarge(int dummy
)
1034 return run_readwritelarge_internal();
1037 static bool run_readwritelarge_signtest(int dummy
)
1040 signing_state
= SMB_SIGNING_REQUIRED
;
1041 ret
= run_readwritelarge_internal();
1042 signing_state
= SMB_SIGNING_DEFAULT
;
1049 #define ival(s) strtol(s, NULL, 0)
1051 /* run a test that simulates an approximate netbench client load */
1052 static bool run_netbench(int client
)
1054 struct cli_state
*cli
;
1059 const char *params
[20];
1060 bool correct
= True
;
1066 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1070 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1072 f
= fopen(client_txt
, "r");
1079 while (fgets(line
, sizeof(line
)-1, f
)) {
1083 line
[strlen(line
)-1] = 0;
1085 /* printf("[%d] %s\n", line_count, line); */
1087 all_string_sub(line
,"client1", cname
, sizeof(line
));
1089 /* parse the command parameters */
1090 params
[0] = strtok_r(line
, " ", &saveptr
);
1092 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1096 if (i
< 2) continue;
1098 if (!strncmp(params
[0],"SMB", 3)) {
1099 printf("ERROR: You are using a dbench 1 load file\n");
1103 if (!strcmp(params
[0],"NTCreateX")) {
1104 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1106 } else if (!strcmp(params
[0],"Close")) {
1107 nb_close(ival(params
[1]));
1108 } else if (!strcmp(params
[0],"Rename")) {
1109 nb_rename(params
[1], params
[2]);
1110 } else if (!strcmp(params
[0],"Unlink")) {
1111 nb_unlink(params
[1]);
1112 } else if (!strcmp(params
[0],"Deltree")) {
1113 nb_deltree(params
[1]);
1114 } else if (!strcmp(params
[0],"Rmdir")) {
1115 nb_rmdir(params
[1]);
1116 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1117 nb_qpathinfo(params
[1]);
1118 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1119 nb_qfileinfo(ival(params
[1]));
1120 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1121 nb_qfsinfo(ival(params
[1]));
1122 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1123 nb_findfirst(params
[1]);
1124 } else if (!strcmp(params
[0],"WriteX")) {
1125 nb_writex(ival(params
[1]),
1126 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1127 } else if (!strcmp(params
[0],"ReadX")) {
1128 nb_readx(ival(params
[1]),
1129 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1130 } else if (!strcmp(params
[0],"Flush")) {
1131 nb_flush(ival(params
[1]));
1133 printf("Unknown operation %s\n", params
[0]);
1141 if (!torture_close_connection(cli
)) {
1149 /* run a test that simulates an approximate netbench client load */
1150 static bool run_nbench(int dummy
)
1153 bool correct
= True
;
1155 nbio_shmem(torture_nprocs
);
1159 signal(SIGALRM
, nb_alarm
);
1161 t
= create_procs(run_netbench
, &correct
);
1164 printf("\nThroughput %g MB/sec\n",
1165 1.0e-6 * nbio_total() / t
);
1171 This test checks for two things:
1173 1) correct support for retaining locks over a close (ie. the server
1174 must not use posix semantics)
1175 2) support for lock timeouts
1177 static bool run_locktest1(int dummy
)
1179 struct cli_state
*cli1
, *cli2
;
1180 const char *fname
= "\\lockt1.lck";
1181 uint16_t fnum1
, fnum2
, fnum3
;
1183 unsigned lock_timeout
;
1186 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1189 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1190 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1192 printf("starting locktest1\n");
1194 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1196 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1198 if (!NT_STATUS_IS_OK(status
)) {
1199 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1203 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1204 if (!NT_STATUS_IS_OK(status
)) {
1205 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1209 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1210 if (!NT_STATUS_IS_OK(status
)) {
1211 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1215 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1216 if (!NT_STATUS_IS_OK(status
)) {
1217 printf("lock1 failed (%s)\n", nt_errstr(status
));
1221 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1222 if (NT_STATUS_IS_OK(status
)) {
1223 printf("lock2 succeeded! This is a locking bug\n");
1226 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1227 NT_STATUS_LOCK_NOT_GRANTED
)) {
1232 lock_timeout
= (1 + (random() % 20));
1233 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1235 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1236 if (NT_STATUS_IS_OK(status
)) {
1237 printf("lock3 succeeded! This is a locking bug\n");
1240 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1241 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1247 if (ABS(t2
- t1
) < lock_timeout
-1) {
1248 printf("error: This server appears not to support timed lock requests\n");
1251 printf("server slept for %u seconds for a %u second timeout\n",
1252 (unsigned int)(t2
-t1
), lock_timeout
);
1254 status
= cli_close(cli1
, fnum2
);
1255 if (!NT_STATUS_IS_OK(status
)) {
1256 printf("close1 failed (%s)\n", nt_errstr(status
));
1260 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1261 if (NT_STATUS_IS_OK(status
)) {
1262 printf("lock4 succeeded! This is a locking bug\n");
1265 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1266 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1271 status
= cli_close(cli1
, fnum1
);
1272 if (!NT_STATUS_IS_OK(status
)) {
1273 printf("close2 failed (%s)\n", nt_errstr(status
));
1277 status
= cli_close(cli2
, fnum3
);
1278 if (!NT_STATUS_IS_OK(status
)) {
1279 printf("close3 failed (%s)\n", nt_errstr(status
));
1283 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1284 if (!NT_STATUS_IS_OK(status
)) {
1285 printf("unlink failed (%s)\n", nt_errstr(status
));
1290 if (!torture_close_connection(cli1
)) {
1294 if (!torture_close_connection(cli2
)) {
1298 printf("Passed locktest1\n");
1303 this checks to see if a secondary tconx can use open files from an
1306 static bool run_tcon_test(int dummy
)
1308 static struct cli_state
*cli
;
1309 const char *fname
= "\\tcontest.tmp";
1311 uint16_t cnum1
, cnum2
, cnum3
;
1312 uint16_t vuid1
, vuid2
;
1317 memset(buf
, '\0', sizeof(buf
));
1319 if (!torture_open_connection(&cli
, 0)) {
1322 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1324 printf("starting tcontest\n");
1326 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1328 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1329 if (!NT_STATUS_IS_OK(status
)) {
1330 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1334 cnum1
= cli_state_get_tid(cli
);
1335 vuid1
= cli_state_get_uid(cli
);
1337 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 printf("initial write failed (%s)", nt_errstr(status
));
1343 status
= cli_tree_connect(cli
, share
, "?????",
1344 password
, strlen(password
)+1);
1345 if (!NT_STATUS_IS_OK(status
)) {
1346 printf("%s refused 2nd tree connect (%s)\n", host
,
1352 cnum2
= cli_state_get_tid(cli
);
1353 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1354 vuid2
= cli_state_get_uid(cli
) + 1;
1356 /* try a write with the wrong tid */
1357 cli_state_set_tid(cli
, cnum2
);
1359 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1360 if (NT_STATUS_IS_OK(status
)) {
1361 printf("* server allows write with wrong TID\n");
1364 printf("server fails write with wrong TID : %s\n",
1369 /* try a write with an invalid tid */
1370 cli_state_set_tid(cli
, cnum3
);
1372 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1373 if (NT_STATUS_IS_OK(status
)) {
1374 printf("* server allows write with invalid TID\n");
1377 printf("server fails write with invalid TID : %s\n",
1381 /* try a write with an invalid vuid */
1382 cli_state_set_uid(cli
, vuid2
);
1383 cli_state_set_tid(cli
, cnum1
);
1385 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1386 if (NT_STATUS_IS_OK(status
)) {
1387 printf("* server allows write with invalid VUID\n");
1390 printf("server fails write with invalid VUID : %s\n",
1394 cli_state_set_tid(cli
, cnum1
);
1395 cli_state_set_uid(cli
, vuid1
);
1397 status
= cli_close(cli
, fnum1
);
1398 if (!NT_STATUS_IS_OK(status
)) {
1399 printf("close failed (%s)\n", nt_errstr(status
));
1403 cli_state_set_tid(cli
, cnum2
);
1405 status
= cli_tdis(cli
);
1406 if (!NT_STATUS_IS_OK(status
)) {
1407 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1411 cli_state_set_tid(cli
, cnum1
);
1413 if (!torture_close_connection(cli
)) {
1422 checks for old style tcon support
1424 static bool run_tcon2_test(int dummy
)
1426 static struct cli_state
*cli
;
1427 uint16_t cnum
, max_xmit
;
1431 if (!torture_open_connection(&cli
, 0)) {
1434 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1436 printf("starting tcon2 test\n");
1438 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1442 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1446 if (!NT_STATUS_IS_OK(status
)) {
1447 printf("tcon2 failed : %s\n", nt_errstr(status
));
1449 printf("tcon OK : max_xmit=%d cnum=%d\n",
1450 (int)max_xmit
, (int)cnum
);
1453 if (!torture_close_connection(cli
)) {
1457 printf("Passed tcon2 test\n");
1461 static bool tcon_devtest(struct cli_state
*cli
,
1462 const char *myshare
, const char *devtype
,
1463 const char *return_devtype
,
1464 NTSTATUS expected_error
)
1469 status
= cli_tree_connect(cli
, myshare
, devtype
,
1470 password
, strlen(password
)+1);
1472 if (NT_STATUS_IS_OK(expected_error
)) {
1473 if (NT_STATUS_IS_OK(status
)) {
1474 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1477 printf("tconX to share %s with type %s "
1478 "succeeded but returned the wrong "
1479 "device type (got [%s] but should have got [%s])\n",
1480 myshare
, devtype
, cli
->dev
, return_devtype
);
1484 printf("tconX to share %s with type %s "
1485 "should have succeeded but failed\n",
1491 if (NT_STATUS_IS_OK(status
)) {
1492 printf("tconx to share %s with type %s "
1493 "should have failed but succeeded\n",
1497 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1500 printf("Returned unexpected error\n");
1509 checks for correct tconX support
1511 static bool run_tcon_devtype_test(int dummy
)
1513 static struct cli_state
*cli1
= NULL
;
1518 status
= cli_full_connection(&cli1
, myname
,
1519 host
, NULL
, port_to_use
,
1521 username
, workgroup
,
1522 password
, flags
, signing_state
);
1524 if (!NT_STATUS_IS_OK(status
)) {
1525 printf("could not open connection\n");
1529 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1532 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1535 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1538 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1541 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1544 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1547 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1550 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1553 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1556 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1562 printf("Passed tcondevtest\n");
1569 This test checks that
1571 1) the server supports multiple locking contexts on the one SMB
1572 connection, distinguished by PID.
1574 2) the server correctly fails overlapping locks made by the same PID (this
1575 goes against POSIX behaviour, which is why it is tricky to implement)
1577 3) the server denies unlock requests by an incorrect client PID
1579 static bool run_locktest2(int dummy
)
1581 static struct cli_state
*cli
;
1582 const char *fname
= "\\lockt2.lck";
1583 uint16_t fnum1
, fnum2
, fnum3
;
1584 bool correct
= True
;
1587 if (!torture_open_connection(&cli
, 0)) {
1591 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1593 printf("starting locktest2\n");
1595 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1599 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1600 if (!NT_STATUS_IS_OK(status
)) {
1601 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1605 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1606 if (!NT_STATUS_IS_OK(status
)) {
1607 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1613 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1614 if (!NT_STATUS_IS_OK(status
)) {
1615 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1621 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1622 if (!NT_STATUS_IS_OK(status
)) {
1623 printf("lock1 failed (%s)\n", nt_errstr(status
));
1627 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1628 if (NT_STATUS_IS_OK(status
)) {
1629 printf("WRITE lock1 succeeded! This is a locking bug\n");
1632 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1633 NT_STATUS_LOCK_NOT_GRANTED
)) {
1638 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1639 if (NT_STATUS_IS_OK(status
)) {
1640 printf("WRITE lock2 succeeded! This is a locking bug\n");
1643 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1644 NT_STATUS_LOCK_NOT_GRANTED
)) {
1649 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1650 if (NT_STATUS_IS_OK(status
)) {
1651 printf("READ lock2 succeeded! This is a locking bug\n");
1654 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1655 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1660 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1661 if (!NT_STATUS_IS_OK(status
)) {
1662 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1665 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1666 printf("unlock at 100 succeeded! This is a locking bug\n");
1670 status
= cli_unlock(cli
, fnum1
, 0, 4);
1671 if (NT_STATUS_IS_OK(status
)) {
1672 printf("unlock1 succeeded! This is a locking bug\n");
1675 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1676 NT_STATUS_RANGE_NOT_LOCKED
)) {
1681 status
= cli_unlock(cli
, fnum1
, 0, 8);
1682 if (NT_STATUS_IS_OK(status
)) {
1683 printf("unlock2 succeeded! This is a locking bug\n");
1686 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1687 NT_STATUS_RANGE_NOT_LOCKED
)) {
1692 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1693 if (NT_STATUS_IS_OK(status
)) {
1694 printf("lock3 succeeded! This is a locking bug\n");
1697 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1698 NT_STATUS_LOCK_NOT_GRANTED
)) {
1705 status
= cli_close(cli
, fnum1
);
1706 if (!NT_STATUS_IS_OK(status
)) {
1707 printf("close1 failed (%s)\n", nt_errstr(status
));
1711 status
= cli_close(cli
, fnum2
);
1712 if (!NT_STATUS_IS_OK(status
)) {
1713 printf("close2 failed (%s)\n", nt_errstr(status
));
1717 status
= cli_close(cli
, fnum3
);
1718 if (!NT_STATUS_IS_OK(status
)) {
1719 printf("close3 failed (%s)\n", nt_errstr(status
));
1723 if (!torture_close_connection(cli
)) {
1727 printf("locktest2 finished\n");
1734 This test checks that
1736 1) the server supports the full offset range in lock requests
1738 static bool run_locktest3(int dummy
)
1740 static struct cli_state
*cli1
, *cli2
;
1741 const char *fname
= "\\lockt3.lck";
1742 uint16_t fnum1
, fnum2
;
1745 bool correct
= True
;
1748 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1750 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1753 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1754 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1756 printf("starting locktest3\n");
1758 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1760 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1762 if (!NT_STATUS_IS_OK(status
)) {
1763 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1767 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1768 if (!NT_STATUS_IS_OK(status
)) {
1769 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1773 for (offset
=i
=0;i
<torture_numops
;i
++) {
1776 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1777 if (!NT_STATUS_IS_OK(status
)) {
1778 printf("lock1 %d failed (%s)\n",
1784 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1785 if (!NT_STATUS_IS_OK(status
)) {
1786 printf("lock2 %d failed (%s)\n",
1793 for (offset
=i
=0;i
<torture_numops
;i
++) {
1796 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1797 if (NT_STATUS_IS_OK(status
)) {
1798 printf("error: lock1 %d succeeded!\n", i
);
1802 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1803 if (NT_STATUS_IS_OK(status
)) {
1804 printf("error: lock2 %d succeeded!\n", i
);
1808 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1809 if (NT_STATUS_IS_OK(status
)) {
1810 printf("error: lock3 %d succeeded!\n", i
);
1814 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1815 if (NT_STATUS_IS_OK(status
)) {
1816 printf("error: lock4 %d succeeded!\n", i
);
1821 for (offset
=i
=0;i
<torture_numops
;i
++) {
1824 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1825 if (!NT_STATUS_IS_OK(status
)) {
1826 printf("unlock1 %d failed (%s)\n",
1832 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1833 if (!NT_STATUS_IS_OK(status
)) {
1834 printf("unlock2 %d failed (%s)\n",
1841 status
= cli_close(cli1
, fnum1
);
1842 if (!NT_STATUS_IS_OK(status
)) {
1843 printf("close1 failed (%s)\n", nt_errstr(status
));
1847 status
= cli_close(cli2
, fnum2
);
1848 if (!NT_STATUS_IS_OK(status
)) {
1849 printf("close2 failed (%s)\n", nt_errstr(status
));
1853 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1854 if (!NT_STATUS_IS_OK(status
)) {
1855 printf("unlink failed (%s)\n", nt_errstr(status
));
1859 if (!torture_close_connection(cli1
)) {
1863 if (!torture_close_connection(cli2
)) {
1867 printf("finished locktest3\n");
1872 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1873 char *buf
, off_t offset
, size_t size
,
1874 size_t *nread
, size_t expect
)
1879 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1881 if(!NT_STATUS_IS_OK(status
)) {
1883 } else if (l_nread
!= expect
) {
1894 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1895 printf("** "); correct = False; \
1899 looks at overlapping locks
1901 static bool run_locktest4(int dummy
)
1903 static struct cli_state
*cli1
, *cli2
;
1904 const char *fname
= "\\lockt4.lck";
1905 uint16_t fnum1
, fnum2
, f
;
1908 bool correct
= True
;
1911 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1915 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1916 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1918 printf("starting locktest4\n");
1920 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1922 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1923 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1925 memset(buf
, 0, sizeof(buf
));
1927 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1929 if (!NT_STATUS_IS_OK(status
)) {
1930 printf("Failed to create file: %s\n", nt_errstr(status
));
1935 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1936 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1937 EXPECTED(ret
, False
);
1938 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1940 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
1941 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
1942 EXPECTED(ret
, True
);
1943 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1945 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
1946 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
1947 EXPECTED(ret
, False
);
1948 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1950 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
1951 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
1952 EXPECTED(ret
, True
);
1953 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1955 ret
= (cli_setpid(cli1
, 1),
1956 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
1957 (cli_setpid(cli1
, 2),
1958 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
1959 EXPECTED(ret
, False
);
1960 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1962 ret
= (cli_setpid(cli1
, 1),
1963 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
1964 (cli_setpid(cli1
, 2),
1965 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
1966 EXPECTED(ret
, True
);
1967 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1969 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
1970 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
1971 EXPECTED(ret
, True
);
1972 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1974 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
1975 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
1976 EXPECTED(ret
, False
);
1977 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1979 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
1980 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
1981 EXPECTED(ret
, False
);
1982 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1984 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
1985 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
1986 EXPECTED(ret
, True
);
1987 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1989 ret
= (cli_setpid(cli1
, 1),
1990 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
1991 (cli_setpid(cli1
, 2),
1992 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
1993 EXPECTED(ret
, False
);
1994 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1996 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
1998 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1999 EXPECTED(ret
, False
);
2000 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2003 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2004 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2005 EXPECTED(ret
, False
);
2006 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2008 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2009 ret
= NT_STATUS_IS_OK(status
);
2011 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2013 ret
= NT_STATUS_IS_OK(status
);
2015 EXPECTED(ret
, False
);
2016 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2019 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2020 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2021 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2022 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2023 EXPECTED(ret
, True
);
2024 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2027 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2028 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2029 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2030 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2031 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2033 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2034 EXPECTED(ret
, True
);
2035 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2037 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2038 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2039 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2041 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2042 EXPECTED(ret
, True
);
2043 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2045 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2047 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2049 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2050 EXPECTED(ret
, True
);
2051 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2053 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2054 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2055 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2056 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2058 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2059 EXPECTED(ret
, True
);
2060 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2062 cli_close(cli1
, fnum1
);
2063 cli_close(cli2
, fnum2
);
2064 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2065 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2066 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2067 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2068 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2069 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2070 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2072 cli_close(cli1
, fnum1
);
2073 EXPECTED(ret
, True
);
2074 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2077 cli_close(cli1
, fnum1
);
2078 cli_close(cli2
, fnum2
);
2079 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2080 torture_close_connection(cli1
);
2081 torture_close_connection(cli2
);
2083 printf("finished locktest4\n");
2088 looks at lock upgrade/downgrade.
2090 static bool run_locktest5(int dummy
)
2092 static struct cli_state
*cli1
, *cli2
;
2093 const char *fname
= "\\lockt5.lck";
2094 uint16_t fnum1
, fnum2
, fnum3
;
2097 bool correct
= True
;
2100 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2104 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2105 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2107 printf("starting locktest5\n");
2109 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2111 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2112 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2113 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2115 memset(buf
, 0, sizeof(buf
));
2117 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2119 if (!NT_STATUS_IS_OK(status
)) {
2120 printf("Failed to create file: %s\n", nt_errstr(status
));
2125 /* Check for NT bug... */
2126 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2127 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2128 cli_close(cli1
, fnum1
);
2129 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2130 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2131 ret
= NT_STATUS_IS_OK(status
);
2132 EXPECTED(ret
, True
);
2133 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2134 cli_close(cli1
, fnum1
);
2135 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2136 cli_unlock(cli1
, fnum3
, 0, 1);
2138 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2139 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2140 EXPECTED(ret
, True
);
2141 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2143 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2144 ret
= NT_STATUS_IS_OK(status
);
2145 EXPECTED(ret
, False
);
2147 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2149 /* Unlock the process 2 lock. */
2150 cli_unlock(cli2
, fnum2
, 0, 4);
2152 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2153 ret
= NT_STATUS_IS_OK(status
);
2154 EXPECTED(ret
, False
);
2156 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2158 /* Unlock the process 1 fnum3 lock. */
2159 cli_unlock(cli1
, fnum3
, 0, 4);
2161 /* Stack 2 more locks here. */
2162 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2163 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2165 EXPECTED(ret
, True
);
2166 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2168 /* Unlock the first process lock, then check this was the WRITE lock that was
2171 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2172 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2174 EXPECTED(ret
, True
);
2175 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2177 /* Unlock the process 2 lock. */
2178 cli_unlock(cli2
, fnum2
, 0, 4);
2180 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2182 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2183 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2184 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2186 EXPECTED(ret
, True
);
2187 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2189 /* Ensure the next unlock fails. */
2190 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2191 EXPECTED(ret
, False
);
2192 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2194 /* Ensure connection 2 can get a write lock. */
2195 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2196 ret
= NT_STATUS_IS_OK(status
);
2197 EXPECTED(ret
, True
);
2199 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2203 cli_close(cli1
, fnum1
);
2204 cli_close(cli2
, fnum2
);
2205 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2206 if (!torture_close_connection(cli1
)) {
2209 if (!torture_close_connection(cli2
)) {
2213 printf("finished locktest5\n");
2219 tries the unusual lockingX locktype bits
2221 static bool run_locktest6(int dummy
)
2223 static struct cli_state
*cli
;
2224 const char *fname
[1] = { "\\lock6.txt" };
2229 if (!torture_open_connection(&cli
, 0)) {
2233 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2235 printf("starting locktest6\n");
2238 printf("Testing %s\n", fname
[i
]);
2240 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2242 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2243 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2244 cli_close(cli
, fnum
);
2245 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2247 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2248 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2249 cli_close(cli
, fnum
);
2250 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2252 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2255 torture_close_connection(cli
);
2257 printf("finished locktest6\n");
2261 static bool run_locktest7(int dummy
)
2263 struct cli_state
*cli1
;
2264 const char *fname
= "\\lockt7.lck";
2267 bool correct
= False
;
2271 if (!torture_open_connection(&cli1
, 0)) {
2275 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2277 printf("starting locktest7\n");
2279 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2281 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2283 memset(buf
, 0, sizeof(buf
));
2285 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2287 if (!NT_STATUS_IS_OK(status
)) {
2288 printf("Failed to create file: %s\n", nt_errstr(status
));
2292 cli_setpid(cli1
, 1);
2294 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2295 if (!NT_STATUS_IS_OK(status
)) {
2296 printf("Unable to apply read lock on range 130:4, "
2297 "error was %s\n", nt_errstr(status
));
2300 printf("pid1 successfully locked range 130:4 for READ\n");
2303 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2304 if (!NT_STATUS_IS_OK(status
)) {
2305 printf("pid1 unable to read the range 130:4, error was %s\n",
2308 } else if (nread
!= 4) {
2309 printf("pid1 unable to read the range 130:4, "
2310 "recv %ld req %d\n", (unsigned long)nread
, 4);
2313 printf("pid1 successfully read the range 130:4\n");
2316 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2317 if (!NT_STATUS_IS_OK(status
)) {
2318 printf("pid1 unable to write to the range 130:4, error was "
2319 "%s\n", nt_errstr(status
));
2320 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2321 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2325 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2329 cli_setpid(cli1
, 2);
2331 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2332 if (!NT_STATUS_IS_OK(status
)) {
2333 printf("pid2 unable to read the range 130:4, error was %s\n",
2336 } else if (nread
!= 4) {
2337 printf("pid2 unable to read the range 130:4, "
2338 "recv %ld req %d\n", (unsigned long)nread
, 4);
2341 printf("pid2 successfully read the range 130:4\n");
2344 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2345 if (!NT_STATUS_IS_OK(status
)) {
2346 printf("pid2 unable to write to the range 130:4, error was "
2347 "%s\n", nt_errstr(status
));
2348 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2349 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2353 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2357 cli_setpid(cli1
, 1);
2358 cli_unlock(cli1
, fnum1
, 130, 4);
2360 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2361 if (!NT_STATUS_IS_OK(status
)) {
2362 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2365 printf("pid1 successfully locked range 130:4 for WRITE\n");
2368 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2369 if (!NT_STATUS_IS_OK(status
)) {
2370 printf("pid1 unable to read the range 130:4, error was %s\n",
2373 } else if (nread
!= 4) {
2374 printf("pid1 unable to read the range 130:4, "
2375 "recv %ld req %d\n", (unsigned long)nread
, 4);
2378 printf("pid1 successfully read the range 130:4\n");
2381 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2382 if (!NT_STATUS_IS_OK(status
)) {
2383 printf("pid1 unable to write to the range 130:4, error was "
2384 "%s\n", nt_errstr(status
));
2387 printf("pid1 successfully wrote to the range 130:4\n");
2390 cli_setpid(cli1
, 2);
2392 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2393 if (!NT_STATUS_IS_OK(status
)) {
2394 printf("pid2 unable to read the range 130:4, error was "
2395 "%s\n", nt_errstr(status
));
2396 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2397 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2401 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2402 (unsigned long)nread
);
2406 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2407 if (!NT_STATUS_IS_OK(status
)) {
2408 printf("pid2 unable to write to the range 130:4, error was "
2409 "%s\n", nt_errstr(status
));
2410 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2411 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2415 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2419 cli_unlock(cli1
, fnum1
, 130, 0);
2423 cli_close(cli1
, fnum1
);
2424 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2425 torture_close_connection(cli1
);
2427 printf("finished locktest7\n");
2432 * This demonstrates a problem with our use of GPFS share modes: A file
2433 * descriptor sitting in the pending close queue holding a GPFS share mode
2434 * blocks opening a file another time. Happens with Word 2007 temp files.
2435 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2436 * open is denied with NT_STATUS_SHARING_VIOLATION.
2439 static bool run_locktest8(int dummy
)
2441 struct cli_state
*cli1
;
2442 const char *fname
= "\\lockt8.lck";
2443 uint16_t fnum1
, fnum2
;
2445 bool correct
= False
;
2448 if (!torture_open_connection(&cli1
, 0)) {
2452 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2454 printf("starting locktest8\n");
2456 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2458 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2460 if (!NT_STATUS_IS_OK(status
)) {
2461 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2465 memset(buf
, 0, sizeof(buf
));
2467 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2468 if (!NT_STATUS_IS_OK(status
)) {
2469 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2474 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2475 if (!NT_STATUS_IS_OK(status
)) {
2476 printf("Unable to apply read lock on range 1:1, error was "
2477 "%s\n", nt_errstr(status
));
2481 status
= cli_close(cli1
, fnum1
);
2482 if (!NT_STATUS_IS_OK(status
)) {
2483 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2487 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2488 if (!NT_STATUS_IS_OK(status
)) {
2489 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2497 cli_close(cli1
, fnum1
);
2498 cli_close(cli1
, fnum2
);
2499 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2500 torture_close_connection(cli1
);
2502 printf("finished locktest8\n");
2507 * This test is designed to be run in conjunction with
2508 * external NFS or POSIX locks taken in the filesystem.
2509 * It checks that the smbd server will block until the
2510 * lock is released and then acquire it. JRA.
2513 static bool got_alarm
;
2514 static struct cli_state
*alarm_cli
;
2516 static void alarm_handler(int dummy
)
2521 static void alarm_handler_parent(int dummy
)
2523 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_OK
);
2526 static void do_local_lock(int read_fd
, int write_fd
)
2531 const char *local_pathname
= NULL
;
2534 local_pathname
= talloc_asprintf(talloc_tos(),
2535 "%s/lockt9.lck", local_path
);
2536 if (!local_pathname
) {
2537 printf("child: alloc fail\n");
2541 unlink(local_pathname
);
2542 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2544 printf("child: open of %s failed %s.\n",
2545 local_pathname
, strerror(errno
));
2549 /* Now take a fcntl lock. */
2550 lock
.l_type
= F_WRLCK
;
2551 lock
.l_whence
= SEEK_SET
;
2554 lock
.l_pid
= getpid();
2556 ret
= fcntl(fd
,F_SETLK
,&lock
);
2558 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2559 local_pathname
, strerror(errno
));
2562 printf("child: got lock 0:4 on file %s.\n",
2567 CatchSignal(SIGALRM
, alarm_handler
);
2569 /* Signal the parent. */
2570 if (write(write_fd
, &c
, 1) != 1) {
2571 printf("child: start signal fail %s.\n",
2578 /* Wait for the parent to be ready. */
2579 if (read(read_fd
, &c
, 1) != 1) {
2580 printf("child: reply signal fail %s.\n",
2588 printf("child: released lock 0:4 on file %s.\n",
2594 static bool run_locktest9(int dummy
)
2596 struct cli_state
*cli1
;
2597 const char *fname
= "\\lockt9.lck";
2599 bool correct
= False
;
2600 int pipe_in
[2], pipe_out
[2];
2604 struct timeval start
;
2608 printf("starting locktest9\n");
2610 if (local_path
== NULL
) {
2611 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2615 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2620 if (child_pid
== -1) {
2624 if (child_pid
== 0) {
2626 do_local_lock(pipe_out
[0], pipe_in
[1]);
2636 ret
= read(pipe_in
[0], &c
, 1);
2638 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2643 if (!torture_open_connection(&cli1
, 0)) {
2647 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2649 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
,
2651 if (!NT_STATUS_IS_OK(status
)) {
2652 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2656 /* Ensure the child has the lock. */
2657 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2658 if (NT_STATUS_IS_OK(status
)) {
2659 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2662 d_printf("Child has the lock.\n");
2665 /* Tell the child to wait 5 seconds then exit. */
2666 ret
= write(pipe_out
[1], &c
, 1);
2668 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2673 /* Wait 20 seconds for the lock. */
2675 CatchSignal(SIGALRM
, alarm_handler_parent
);
2678 start
= timeval_current();
2680 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2681 if (!NT_STATUS_IS_OK(status
)) {
2682 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2683 "%s\n", nt_errstr(status
));
2688 seconds
= timeval_elapsed(&start
);
2690 printf("Parent got the lock after %.2f seconds.\n",
2693 status
= cli_close(cli1
, fnum
);
2694 if (!NT_STATUS_IS_OK(status
)) {
2695 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2702 cli_close(cli1
, fnum
);
2703 torture_close_connection(cli1
);
2707 printf("finished locktest9\n");
2712 test whether fnums and tids open on one VC are available on another (a major
2715 static bool run_fdpasstest(int dummy
)
2717 struct cli_state
*cli1
, *cli2
;
2718 const char *fname
= "\\fdpass.tst";
2723 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2726 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2727 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2729 printf("starting fdpasstest\n");
2731 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2733 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2735 if (!NT_STATUS_IS_OK(status
)) {
2736 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2740 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2742 if (!NT_STATUS_IS_OK(status
)) {
2743 printf("write failed (%s)\n", nt_errstr(status
));
2747 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2748 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2749 cli_setpid(cli2
, cli_getpid(cli1
));
2751 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2752 printf("read succeeded! nasty security hole [%s]\n", buf
);
2756 cli_close(cli1
, fnum1
);
2757 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2759 torture_close_connection(cli1
);
2760 torture_close_connection(cli2
);
2762 printf("finished fdpasstest\n");
2766 static bool run_fdsesstest(int dummy
)
2768 struct cli_state
*cli
;
2770 uint16_t saved_vuid
;
2772 uint16_t saved_cnum
;
2773 const char *fname
= "\\fdsess.tst";
2774 const char *fname1
= "\\fdsess1.tst";
2781 if (!torture_open_connection(&cli
, 0))
2783 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2785 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2788 saved_cnum
= cli_state_get_tid(cli
);
2789 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", "", 1)))
2791 new_cnum
= cli_state_get_tid(cli
);
2792 cli_state_set_tid(cli
, saved_cnum
);
2794 printf("starting fdsesstest\n");
2796 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2797 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2799 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2800 if (!NT_STATUS_IS_OK(status
)) {
2801 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2805 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2807 if (!NT_STATUS_IS_OK(status
)) {
2808 printf("write failed (%s)\n", nt_errstr(status
));
2812 saved_vuid
= cli_state_get_uid(cli
);
2813 cli_state_set_uid(cli
, new_vuid
);
2815 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2816 printf("read succeeded with different vuid! "
2817 "nasty security hole [%s]\n", buf
);
2820 /* Try to open a file with different vuid, samba cnum. */
2821 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2822 printf("create with different vuid, same cnum succeeded.\n");
2823 cli_close(cli
, fnum2
);
2824 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2826 printf("create with different vuid, same cnum failed.\n");
2827 printf("This will cause problems with service clients.\n");
2831 cli_state_set_uid(cli
, saved_vuid
);
2833 /* Try with same vuid, different cnum. */
2834 cli_state_set_tid(cli
, new_cnum
);
2836 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2837 printf("read succeeded with different cnum![%s]\n", buf
);
2841 cli_state_set_tid(cli
, saved_cnum
);
2842 cli_close(cli
, fnum1
);
2843 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2845 torture_close_connection(cli
);
2847 printf("finished fdsesstest\n");
2852 This test checks that
2854 1) the server does not allow an unlink on a file that is open
2856 static bool run_unlinktest(int dummy
)
2858 struct cli_state
*cli
;
2859 const char *fname
= "\\unlink.tst";
2861 bool correct
= True
;
2864 if (!torture_open_connection(&cli
, 0)) {
2868 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2870 printf("starting unlink test\n");
2872 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2876 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2877 if (!NT_STATUS_IS_OK(status
)) {
2878 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2882 status
= cli_unlink(cli
, fname
,
2883 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2884 if (NT_STATUS_IS_OK(status
)) {
2885 printf("error: server allowed unlink on an open file\n");
2888 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2889 NT_STATUS_SHARING_VIOLATION
);
2892 cli_close(cli
, fnum
);
2893 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2895 if (!torture_close_connection(cli
)) {
2899 printf("unlink test finished\n");
2906 test how many open files this server supports on the one socket
2908 static bool run_maxfidtest(int dummy
)
2910 struct cli_state
*cli
;
2912 uint16_t fnums
[0x11000];
2915 bool correct
= True
;
2921 printf("failed to connect\n");
2925 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2927 for (i
=0; i
<0x11000; i
++) {
2928 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2929 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2931 if (!NT_STATUS_IS_OK(status
)) {
2932 printf("open of %s failed (%s)\n",
2933 fname
, nt_errstr(status
));
2934 printf("maximum fnum is %d\n", i
);
2942 printf("cleaning up\n");
2944 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2945 cli_close(cli
, fnums
[i
]);
2947 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2948 if (!NT_STATUS_IS_OK(status
)) {
2949 printf("unlink of %s failed (%s)\n",
2950 fname
, nt_errstr(status
));
2957 printf("maxfid test finished\n");
2958 if (!torture_close_connection(cli
)) {
2964 /* generate a random buffer */
2965 static void rand_buf(char *buf
, int len
)
2968 *buf
= (char)sys_random();
2973 /* send smb negprot commands, not reading the response */
2974 static bool run_negprot_nowait(int dummy
)
2976 struct tevent_context
*ev
;
2978 struct cli_state
*cli
;
2979 bool correct
= True
;
2981 printf("starting negprot nowait test\n");
2983 ev
= samba_tevent_context_init(talloc_tos());
2988 if (!(cli
= open_nbt_connection())) {
2993 for (i
=0;i
<50000;i
++) {
2994 struct tevent_req
*req
;
2996 req
= smbXcli_negprot_send(ev
, ev
, cli
->conn
, cli
->timeout
,
2997 PROTOCOL_CORE
, PROTOCOL_NT1
);
3002 if (!tevent_req_poll(req
, ev
)) {
3003 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3011 if (torture_close_connection(cli
)) {
3015 printf("finished negprot nowait test\n");
3020 /* send smb negprot commands, not reading the response */
3021 static bool run_bad_nbt_session(int dummy
)
3023 struct nmb_name called
, calling
;
3024 struct sockaddr_storage ss
;
3029 printf("starting bad nbt session test\n");
3031 make_nmb_name(&calling
, myname
, 0x0);
3032 make_nmb_name(&called
, host
, 0x20);
3034 if (!resolve_name(host
, &ss
, 0x20, true)) {
3035 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3039 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
3040 if (!NT_STATUS_IS_OK(status
)) {
3041 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3046 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3049 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3054 printf("finished bad nbt session test\n");
3058 /* send random IPC commands */
3059 static bool run_randomipc(int dummy
)
3061 char *rparam
= NULL
;
3063 unsigned int rdrcnt
,rprcnt
;
3065 int api
, param_len
, i
;
3066 struct cli_state
*cli
;
3067 bool correct
= True
;
3070 printf("starting random ipc test\n");
3072 if (!torture_open_connection(&cli
, 0)) {
3076 for (i
=0;i
<count
;i
++) {
3077 api
= sys_random() % 500;
3078 param_len
= (sys_random() % 64);
3080 rand_buf(param
, param_len
);
3085 param
, param_len
, 8,
3086 NULL
, 0, CLI_BUFFER_SIZE
,
3090 printf("%d/%d\r", i
,count
);
3093 printf("%d/%d\n", i
, count
);
3095 if (!torture_close_connection(cli
)) {
3102 printf("finished random ipc test\n");
3109 static void browse_callback(const char *sname
, uint32_t stype
,
3110 const char *comment
, void *state
)
3112 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3118 This test checks the browse list code
3121 static bool run_browsetest(int dummy
)
3123 static struct cli_state
*cli
;
3124 bool correct
= True
;
3126 printf("starting browse test\n");
3128 if (!torture_open_connection(&cli
, 0)) {
3132 printf("domain list:\n");
3133 cli_NetServerEnum(cli
, cli
->server_domain
,
3134 SV_TYPE_DOMAIN_ENUM
,
3135 browse_callback
, NULL
);
3137 printf("machine list:\n");
3138 cli_NetServerEnum(cli
, cli
->server_domain
,
3140 browse_callback
, NULL
);
3142 if (!torture_close_connection(cli
)) {
3146 printf("browse test finished\n");
3154 This checks how the getatr calls works
3156 static bool run_attrtest(int dummy
)
3158 struct cli_state
*cli
;
3161 const char *fname
= "\\attrib123456789.tst";
3162 bool correct
= True
;
3165 printf("starting attrib test\n");
3167 if (!torture_open_connection(&cli
, 0)) {
3171 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3172 cli_openx(cli
, fname
,
3173 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3174 cli_close(cli
, fnum
);
3176 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3177 if (!NT_STATUS_IS_OK(status
)) {
3178 printf("getatr failed (%s)\n", nt_errstr(status
));
3182 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3183 printf("ERROR: SMBgetatr bug. time is %s",
3189 t2
= t
-60*60*24; /* 1 day ago */
3191 status
= cli_setatr(cli
, fname
, 0, t2
);
3192 if (!NT_STATUS_IS_OK(status
)) {
3193 printf("setatr failed (%s)\n", nt_errstr(status
));
3197 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3198 if (!NT_STATUS_IS_OK(status
)) {
3199 printf("getatr failed (%s)\n", nt_errstr(status
));
3204 printf("ERROR: getatr/setatr bug. times are\n%s",
3206 printf("%s", ctime(&t2
));
3210 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3212 if (!torture_close_connection(cli
)) {
3216 printf("attrib test finished\n");
3223 This checks a couple of trans2 calls
3225 static bool run_trans2test(int dummy
)
3227 struct cli_state
*cli
;
3230 time_t c_time
, a_time
, m_time
;
3231 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3232 const char *fname
= "\\trans2.tst";
3233 const char *dname
= "\\trans2";
3234 const char *fname2
= "\\trans2\\trans2.tst";
3236 bool correct
= True
;
3240 printf("starting trans2 test\n");
3242 if (!torture_open_connection(&cli
, 0)) {
3246 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3247 if (!NT_STATUS_IS_OK(status
)) {
3248 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3253 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3254 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3255 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3256 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3257 if (!NT_STATUS_IS_OK(status
)) {
3258 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3262 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3263 if (!NT_STATUS_IS_OK(status
)) {
3264 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3267 else if (strcmp(pname
, fname
)) {
3268 printf("qfilename gave different name? [%s] [%s]\n",
3273 cli_close(cli
, fnum
);
3277 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3278 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3280 if (!NT_STATUS_IS_OK(status
)) {
3281 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3284 cli_close(cli
, fnum
);
3286 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3288 if (!NT_STATUS_IS_OK(status
)) {
3289 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3292 time_t t
= time(NULL
);
3294 if (c_time
!= m_time
) {
3295 printf("create time=%s", ctime(&c_time
));
3296 printf("modify time=%s", ctime(&m_time
));
3297 printf("This system appears to have sticky create times\n");
3299 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3300 printf("access time=%s", ctime(&a_time
));
3301 printf("This system appears to set a midnight access time\n");
3305 if (abs(m_time
- t
) > 60*60*24*7) {
3306 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3312 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3313 cli_openx(cli
, fname
,
3314 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3315 cli_close(cli
, fnum
);
3316 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3317 &m_time_ts
, &size
, NULL
, NULL
);
3318 if (!NT_STATUS_IS_OK(status
)) {
3319 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3322 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3323 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3324 printf("This system appears to set a initial 0 write time\n");
3329 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3332 /* check if the server updates the directory modification time
3333 when creating a new file */
3334 status
= cli_mkdir(cli
, dname
);
3335 if (!NT_STATUS_IS_OK(status
)) {
3336 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3340 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3341 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3342 if (!NT_STATUS_IS_OK(status
)) {
3343 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3347 cli_openx(cli
, fname2
,
3348 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3349 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3350 cli_close(cli
, fnum
);
3351 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3352 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3353 if (!NT_STATUS_IS_OK(status
)) {
3354 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3357 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3359 printf("This system does not update directory modification times\n");
3363 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3364 cli_rmdir(cli
, dname
);
3366 if (!torture_close_connection(cli
)) {
3370 printf("trans2 test finished\n");
3376 This checks new W2K calls.
3379 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3381 uint8_t *buf
= NULL
;
3385 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3386 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3387 if (!NT_STATUS_IS_OK(status
)) {
3388 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3391 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3392 dump_data(0, (uint8_t *)buf
, len
);
3399 static bool run_w2ktest(int dummy
)
3401 struct cli_state
*cli
;
3403 const char *fname
= "\\w2ktest\\w2k.tst";
3405 bool correct
= True
;
3407 printf("starting w2k test\n");
3409 if (!torture_open_connection(&cli
, 0)) {
3413 cli_openx(cli
, fname
,
3414 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3416 for (level
= 1004; level
< 1040; level
++) {
3417 new_trans(cli
, fnum
, level
);
3420 cli_close(cli
, fnum
);
3422 if (!torture_close_connection(cli
)) {
3426 printf("w2k test finished\n");
3433 this is a harness for some oplock tests
3435 static bool run_oplock1(int dummy
)
3437 struct cli_state
*cli1
;
3438 const char *fname
= "\\lockt1.lck";
3440 bool correct
= True
;
3443 printf("starting oplock test 1\n");
3445 if (!torture_open_connection(&cli1
, 0)) {
3449 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3451 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3453 cli1
->use_oplocks
= True
;
3455 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3457 if (!NT_STATUS_IS_OK(status
)) {
3458 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3462 cli1
->use_oplocks
= False
;
3464 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3465 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3467 status
= cli_close(cli1
, fnum1
);
3468 if (!NT_STATUS_IS_OK(status
)) {
3469 printf("close2 failed (%s)\n", nt_errstr(status
));
3473 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3474 if (!NT_STATUS_IS_OK(status
)) {
3475 printf("unlink failed (%s)\n", nt_errstr(status
));
3479 if (!torture_close_connection(cli1
)) {
3483 printf("finished oplock test 1\n");
3488 static bool run_oplock2(int dummy
)
3490 struct cli_state
*cli1
, *cli2
;
3491 const char *fname
= "\\lockt2.lck";
3492 uint16_t fnum1
, fnum2
;
3493 int saved_use_oplocks
= use_oplocks
;
3495 bool correct
= True
;
3496 volatile bool *shared_correct
;
3500 shared_correct
= (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3501 *shared_correct
= True
;
3503 use_level_II_oplocks
= True
;
3506 printf("starting oplock test 2\n");
3508 if (!torture_open_connection(&cli1
, 0)) {
3509 use_level_II_oplocks
= False
;
3510 use_oplocks
= saved_use_oplocks
;
3514 if (!torture_open_connection(&cli2
, 1)) {
3515 use_level_II_oplocks
= False
;
3516 use_oplocks
= saved_use_oplocks
;
3520 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3522 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3523 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3525 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3527 if (!NT_STATUS_IS_OK(status
)) {
3528 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3532 /* Don't need the globals any more. */
3533 use_level_II_oplocks
= False
;
3534 use_oplocks
= saved_use_oplocks
;
3538 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3539 if (!NT_STATUS_IS_OK(status
)) {
3540 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3541 *shared_correct
= False
;
3547 status
= cli_close(cli2
, fnum2
);
3548 if (!NT_STATUS_IS_OK(status
)) {
3549 printf("close2 failed (%s)\n", nt_errstr(status
));
3550 *shared_correct
= False
;
3558 /* Ensure cli1 processes the break. Empty file should always return 0
3560 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3561 if (!NT_STATUS_IS_OK(status
)) {
3562 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3564 } else if (nread
!= 0) {
3565 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3566 (unsigned long)nread
, 0);
3570 /* Should now be at level II. */
3571 /* Test if sending a write locks causes a break to none. */
3572 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3573 if (!NT_STATUS_IS_OK(status
)) {
3574 printf("lock failed (%s)\n", nt_errstr(status
));
3578 cli_unlock(cli1
, fnum1
, 0, 4);
3582 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3583 if (!NT_STATUS_IS_OK(status
)) {
3584 printf("lock failed (%s)\n", nt_errstr(status
));
3588 cli_unlock(cli1
, fnum1
, 0, 4);
3592 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3594 status
= cli_close(cli1
, fnum1
);
3595 if (!NT_STATUS_IS_OK(status
)) {
3596 printf("close1 failed (%s)\n", nt_errstr(status
));
3602 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3603 if (!NT_STATUS_IS_OK(status
)) {
3604 printf("unlink failed (%s)\n", nt_errstr(status
));
3608 if (!torture_close_connection(cli1
)) {
3612 if (!*shared_correct
) {
3616 printf("finished oplock test 2\n");
3621 struct oplock4_state
{
3622 struct tevent_context
*ev
;
3623 struct cli_state
*cli
;
3628 static void oplock4_got_break(struct tevent_req
*req
);
3629 static void oplock4_got_open(struct tevent_req
*req
);
3631 static bool run_oplock4(int dummy
)
3633 struct tevent_context
*ev
;
3634 struct cli_state
*cli1
, *cli2
;
3635 struct tevent_req
*oplock_req
, *open_req
;
3636 const char *fname
= "\\lockt4.lck";
3637 const char *fname_ln
= "\\lockt4_ln.lck";
3638 uint16_t fnum1
, fnum2
;
3639 int saved_use_oplocks
= use_oplocks
;
3641 bool correct
= true;
3645 struct oplock4_state
*state
;
3647 printf("starting oplock test 4\n");
3649 if (!torture_open_connection(&cli1
, 0)) {
3650 use_level_II_oplocks
= false;
3651 use_oplocks
= saved_use_oplocks
;
3655 if (!torture_open_connection(&cli2
, 1)) {
3656 use_level_II_oplocks
= false;
3657 use_oplocks
= saved_use_oplocks
;
3661 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3662 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3664 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3665 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3667 /* Create the file. */
3668 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3670 if (!NT_STATUS_IS_OK(status
)) {
3671 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3675 status
= cli_close(cli1
, fnum1
);
3676 if (!NT_STATUS_IS_OK(status
)) {
3677 printf("close1 failed (%s)\n", nt_errstr(status
));
3681 /* Now create a hardlink. */
3682 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3683 if (!NT_STATUS_IS_OK(status
)) {
3684 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3688 /* Prove that opening hardlinks cause deny modes to conflict. */
3689 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3690 if (!NT_STATUS_IS_OK(status
)) {
3691 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3695 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3696 if (NT_STATUS_IS_OK(status
)) {
3697 printf("open of %s succeeded - should fail with sharing violation.\n",
3702 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3703 printf("open of %s should fail with sharing violation. Got %s\n",
3704 fname_ln
, nt_errstr(status
));
3708 status
= cli_close(cli1
, fnum1
);
3709 if (!NT_STATUS_IS_OK(status
)) {
3710 printf("close1 failed (%s)\n", nt_errstr(status
));
3714 cli1
->use_oplocks
= true;
3715 cli2
->use_oplocks
= true;
3717 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3718 if (!NT_STATUS_IS_OK(status
)) {
3719 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3723 ev
= samba_tevent_context_init(talloc_tos());
3725 printf("tevent_context_init failed\n");
3729 state
= talloc(ev
, struct oplock4_state
);
3730 if (state
== NULL
) {
3731 printf("talloc failed\n");
3736 state
->got_break
= &got_break
;
3737 state
->fnum2
= &fnum2
;
3739 oplock_req
= cli_smb_oplock_break_waiter_send(
3740 talloc_tos(), ev
, cli1
);
3741 if (oplock_req
== NULL
) {
3742 printf("cli_smb_oplock_break_waiter_send failed\n");
3745 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3747 open_req
= cli_openx_send(
3748 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3749 if (open_req
== NULL
) {
3750 printf("cli_openx_send failed\n");
3753 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3758 while (!got_break
|| fnum2
== 0xffff) {
3760 ret
= tevent_loop_once(ev
);
3762 printf("tevent_loop_once failed: %s\n",
3768 status
= cli_close(cli2
, fnum2
);
3769 if (!NT_STATUS_IS_OK(status
)) {
3770 printf("close2 failed (%s)\n", nt_errstr(status
));
3774 status
= cli_close(cli1
, fnum1
);
3775 if (!NT_STATUS_IS_OK(status
)) {
3776 printf("close1 failed (%s)\n", nt_errstr(status
));
3780 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3781 if (!NT_STATUS_IS_OK(status
)) {
3782 printf("unlink failed (%s)\n", nt_errstr(status
));
3786 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3787 if (!NT_STATUS_IS_OK(status
)) {
3788 printf("unlink failed (%s)\n", nt_errstr(status
));
3792 if (!torture_close_connection(cli1
)) {
3800 printf("finished oplock test 4\n");
3805 static void oplock4_got_break(struct tevent_req
*req
)
3807 struct oplock4_state
*state
= tevent_req_callback_data(
3808 req
, struct oplock4_state
);
3813 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3815 if (!NT_STATUS_IS_OK(status
)) {
3816 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3820 *state
->got_break
= true;
3822 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3825 printf("cli_oplock_ack_send failed\n");
3830 static void oplock4_got_open(struct tevent_req
*req
)
3832 struct oplock4_state
*state
= tevent_req_callback_data(
3833 req
, struct oplock4_state
);
3836 status
= cli_openx_recv(req
, state
->fnum2
);
3837 if (!NT_STATUS_IS_OK(status
)) {
3838 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
3839 *state
->fnum2
= 0xffff;
3844 Test delete on close semantics.
3846 static bool run_deletetest(int dummy
)
3848 struct cli_state
*cli1
= NULL
;
3849 struct cli_state
*cli2
= NULL
;
3850 const char *fname
= "\\delete.file";
3851 uint16_t fnum1
= (uint16_t)-1;
3852 uint16_t fnum2
= (uint16_t)-1;
3853 bool correct
= false;
3856 printf("starting delete test\n");
3858 if (!torture_open_connection(&cli1
, 0)) {
3862 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3864 /* Test 1 - this should delete the file on close. */
3866 cli_setatr(cli1
, fname
, 0, 0);
3867 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3869 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3870 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3871 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
3872 if (!NT_STATUS_IS_OK(status
)) {
3873 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3877 status
= cli_close(cli1
, fnum1
);
3878 if (!NT_STATUS_IS_OK(status
)) {
3879 printf("[1] close failed (%s)\n", nt_errstr(status
));
3883 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3884 if (NT_STATUS_IS_OK(status
)) {
3885 printf("[1] open of %s succeeded (should fail)\n", fname
);
3889 printf("first delete on close test succeeded.\n");
3891 /* Test 2 - this should delete the file on close. */
3893 cli_setatr(cli1
, fname
, 0, 0);
3894 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3896 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3897 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3898 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3899 if (!NT_STATUS_IS_OK(status
)) {
3900 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3904 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3905 if (!NT_STATUS_IS_OK(status
)) {
3906 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3910 status
= cli_close(cli1
, fnum1
);
3911 if (!NT_STATUS_IS_OK(status
)) {
3912 printf("[2] close failed (%s)\n", nt_errstr(status
));
3916 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3917 if (NT_STATUS_IS_OK(status
)) {
3918 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3919 status
= cli_close(cli1
, fnum1
);
3920 if (!NT_STATUS_IS_OK(status
)) {
3921 printf("[2] close failed (%s)\n", nt_errstr(status
));
3923 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3927 printf("second delete on close test succeeded.\n");
3930 cli_setatr(cli1
, fname
, 0, 0);
3931 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3933 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3934 FILE_ATTRIBUTE_NORMAL
,
3935 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3936 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
3937 if (!NT_STATUS_IS_OK(status
)) {
3938 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
3942 /* This should fail with a sharing violation - open for delete is only compatible
3943 with SHARE_DELETE. */
3945 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3946 FILE_ATTRIBUTE_NORMAL
,
3947 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3948 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3949 if (NT_STATUS_IS_OK(status
)) {
3950 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3954 /* This should succeed. */
3955 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3956 FILE_ATTRIBUTE_NORMAL
,
3957 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3958 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
3959 if (!NT_STATUS_IS_OK(status
)) {
3960 printf("[3] open - 3 of %s failed (%s)\n", fname
, nt_errstr(status
));
3964 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3965 if (!NT_STATUS_IS_OK(status
)) {
3966 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3970 status
= cli_close(cli1
, fnum1
);
3971 if (!NT_STATUS_IS_OK(status
)) {
3972 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
3976 status
= cli_close(cli1
, fnum2
);
3977 if (!NT_STATUS_IS_OK(status
)) {
3978 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
3982 /* This should fail - file should no longer be there. */
3984 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
3985 if (NT_STATUS_IS_OK(status
)) {
3986 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3987 status
= cli_close(cli1
, fnum1
);
3988 if (!NT_STATUS_IS_OK(status
)) {
3989 printf("[3] close failed (%s)\n", nt_errstr(status
));
3991 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3995 printf("third delete on close test succeeded.\n");
3998 cli_setatr(cli1
, fname
, 0, 0);
3999 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4001 status
= cli_ntcreate(cli1
, fname
, 0,
4002 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4003 FILE_ATTRIBUTE_NORMAL
,
4004 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4005 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4006 if (!NT_STATUS_IS_OK(status
)) {
4007 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4011 /* This should succeed. */
4012 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4013 FILE_ATTRIBUTE_NORMAL
,
4014 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4015 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4016 if (!NT_STATUS_IS_OK(status
)) {
4017 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4021 status
= cli_close(cli1
, fnum2
);
4022 if (!NT_STATUS_IS_OK(status
)) {
4023 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4027 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4028 if (!NT_STATUS_IS_OK(status
)) {
4029 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4033 /* This should fail - no more opens once delete on close set. */
4034 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4035 FILE_ATTRIBUTE_NORMAL
,
4036 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4037 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4038 if (NT_STATUS_IS_OK(status
)) {
4039 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4043 status
= cli_close(cli1
, fnum1
);
4044 if (!NT_STATUS_IS_OK(status
)) {
4045 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4049 printf("fourth delete on close test succeeded.\n");
4052 cli_setatr(cli1
, fname
, 0, 0);
4053 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4055 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4056 if (!NT_STATUS_IS_OK(status
)) {
4057 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4061 /* This should fail - only allowed on NT opens with DELETE access. */
4063 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4064 if (NT_STATUS_IS_OK(status
)) {
4065 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4069 status
= cli_close(cli1
, fnum1
);
4070 if (!NT_STATUS_IS_OK(status
)) {
4071 printf("[5] close failed (%s)\n", nt_errstr(status
));
4075 printf("fifth delete on close test succeeded.\n");
4078 cli_setatr(cli1
, fname
, 0, 0);
4079 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4081 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4082 FILE_ATTRIBUTE_NORMAL
,
4083 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4084 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4085 if (!NT_STATUS_IS_OK(status
)) {
4086 printf("[6] open of %s failed (%s)\n", fname
,
4091 /* This should fail - only allowed on NT opens with DELETE access. */
4093 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4094 if (NT_STATUS_IS_OK(status
)) {
4095 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4099 status
= cli_close(cli1
, fnum1
);
4100 if (!NT_STATUS_IS_OK(status
)) {
4101 printf("[6] close failed (%s)\n", nt_errstr(status
));
4105 printf("sixth delete on close test succeeded.\n");
4108 cli_setatr(cli1
, fname
, 0, 0);
4109 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4111 status
= cli_ntcreate(cli1
, fname
, 0,
4112 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4113 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4114 0, 0, &fnum1
, NULL
);
4115 if (!NT_STATUS_IS_OK(status
)) {
4116 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4120 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4121 if (!NT_STATUS_IS_OK(status
)) {
4122 printf("[7] setting delete_on_close on file failed !\n");
4126 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4127 if (!NT_STATUS_IS_OK(status
)) {
4128 printf("[7] unsetting delete_on_close on file failed !\n");
4132 status
= cli_close(cli1
, fnum1
);
4133 if (!NT_STATUS_IS_OK(status
)) {
4134 printf("[7] close - 1 failed (%s)\n", nt_errstr(status
));
4138 /* This next open should succeed - we reset the flag. */
4139 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4140 if (!NT_STATUS_IS_OK(status
)) {
4141 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4145 status
= cli_close(cli1
, fnum1
);
4146 if (!NT_STATUS_IS_OK(status
)) {
4147 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4151 printf("seventh delete on close test succeeded.\n");
4154 cli_setatr(cli1
, fname
, 0, 0);
4155 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4157 if (!torture_open_connection(&cli2
, 1)) {
4158 printf("[8] failed to open second connection.\n");
4162 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4164 status
= cli_ntcreate(cli1
, fname
, 0,
4165 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4166 FILE_ATTRIBUTE_NORMAL
,
4167 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4168 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4169 if (!NT_STATUS_IS_OK(status
)) {
4170 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4174 status
= cli_ntcreate(cli2
, fname
, 0,
4175 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4176 FILE_ATTRIBUTE_NORMAL
,
4177 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4178 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4179 if (!NT_STATUS_IS_OK(status
)) {
4180 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4184 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4185 if (!NT_STATUS_IS_OK(status
)) {
4186 printf("[8] setting delete_on_close on file failed !\n");
4190 status
= cli_close(cli1
, fnum1
);
4191 if (!NT_STATUS_IS_OK(status
)) {
4192 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4196 status
= cli_close(cli2
, fnum2
);
4197 if (!NT_STATUS_IS_OK(status
)) {
4198 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4202 /* This should fail.. */
4203 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4204 if (NT_STATUS_IS_OK(status
)) {
4205 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4209 printf("eighth delete on close test succeeded.\n");
4213 /* This should fail - we need to set DELETE_ACCESS. */
4214 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4215 FILE_ATTRIBUTE_NORMAL
,
4218 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4219 if (NT_STATUS_IS_OK(status
)) {
4220 printf("[9] open of %s succeeded should have failed!\n", fname
);
4224 printf("ninth delete on close test succeeded.\n");
4228 status
= cli_ntcreate(cli1
, fname
, 0,
4229 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4230 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4231 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4233 if (!NT_STATUS_IS_OK(status
)) {
4234 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4238 /* This should delete the file. */
4239 status
= cli_close(cli1
, fnum1
);
4240 if (!NT_STATUS_IS_OK(status
)) {
4241 printf("[10] close failed (%s)\n", nt_errstr(status
));
4245 /* This should fail.. */
4246 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4247 if (NT_STATUS_IS_OK(status
)) {
4248 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4252 printf("tenth delete on close test succeeded.\n");
4256 cli_setatr(cli1
, fname
, 0, 0);
4257 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4259 /* Can we open a read-only file with delete access? */
4261 /* Create a readonly file. */
4262 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4263 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4264 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4265 if (!NT_STATUS_IS_OK(status
)) {
4266 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4270 status
= cli_close(cli1
, fnum1
);
4271 if (!NT_STATUS_IS_OK(status
)) {
4272 printf("[11] close failed (%s)\n", nt_errstr(status
));
4276 /* Now try open for delete access. */
4277 status
= cli_ntcreate(cli1
, fname
, 0,
4278 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4280 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4281 FILE_OPEN
, 0, 0, &fnum1
, NULL
);
4282 if (!NT_STATUS_IS_OK(status
)) {
4283 printf("[11] open of %s failed: %s\n", fname
, nt_errstr(status
));
4287 cli_close(cli1
, fnum1
);
4289 printf("eleventh delete on close test succeeded.\n");
4293 * like test 4 but with initial delete on close
4296 cli_setatr(cli1
, fname
, 0, 0);
4297 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4299 status
= cli_ntcreate(cli1
, fname
, 0,
4300 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4301 FILE_ATTRIBUTE_NORMAL
,
4302 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4304 FILE_DELETE_ON_CLOSE
, 0, &fnum1
, NULL
);
4305 if (!NT_STATUS_IS_OK(status
)) {
4306 printf("[12] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4310 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4311 FILE_ATTRIBUTE_NORMAL
,
4312 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4313 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4314 if (!NT_STATUS_IS_OK(status
)) {
4315 printf("[12] open 2 of %s failed(%s).\n", fname
, nt_errstr(status
));
4319 status
= cli_close(cli1
, fnum2
);
4320 if (!NT_STATUS_IS_OK(status
)) {
4321 printf("[12] close 1 failed (%s)\n", nt_errstr(status
));
4325 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4326 if (!NT_STATUS_IS_OK(status
)) {
4327 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4331 /* This should fail - no more opens once delete on close set. */
4332 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4333 FILE_ATTRIBUTE_NORMAL
,
4334 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4335 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4336 if (NT_STATUS_IS_OK(status
)) {
4337 printf("[12] open 3 of %s succeeded - should fail).\n", fname
);
4341 status
= cli_nt_delete_on_close(cli1
, fnum1
, false);
4342 if (!NT_STATUS_IS_OK(status
)) {
4343 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status
));
4347 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4348 FILE_ATTRIBUTE_NORMAL
,
4349 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4350 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4351 if (!NT_STATUS_IS_OK(status
)) {
4352 printf("[12] open 4 of %s failed (%s)\n", fname
, nt_errstr(status
));
4356 status
= cli_close(cli1
, fnum2
);
4357 if (!NT_STATUS_IS_OK(status
)) {
4358 printf("[12] close 2 failed (%s)\n", nt_errstr(status
));
4362 status
= cli_close(cli1
, fnum1
);
4363 if (!NT_STATUS_IS_OK(status
)) {
4364 printf("[12] close 3 failed (%s)\n", nt_errstr(status
));
4369 * setting delete on close on the handle does
4370 * not unset the initial delete on close...
4372 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4373 FILE_ATTRIBUTE_NORMAL
,
4374 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4375 FILE_OPEN
, 0, 0, &fnum2
, NULL
);
4376 if (NT_STATUS_IS_OK(status
)) {
4377 printf("[12] open 5 of %s succeeded - should fail).\n", fname
);
4379 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4380 printf("ntcreate returned %s, expected "
4381 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4386 printf("twelfth delete on close test succeeded.\n");
4389 printf("finished delete test\n");
4394 /* FIXME: This will crash if we aborted before cli2 got
4395 * intialized, because these functions don't handle
4396 * uninitialized connections. */
4398 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4399 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4400 cli_setatr(cli1
, fname
, 0, 0);
4401 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4403 if (cli1
&& !torture_close_connection(cli1
)) {
4406 if (cli2
&& !torture_close_connection(cli2
)) {
4412 static bool run_deletetest_ln(int dummy
)
4414 struct cli_state
*cli
;
4415 const char *fname
= "\\delete1";
4416 const char *fname_ln
= "\\delete1_ln";
4420 bool correct
= true;
4423 printf("starting deletetest-ln\n");
4425 if (!torture_open_connection(&cli
, 0)) {
4429 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4430 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4432 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4434 /* Create the file. */
4435 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4436 if (!NT_STATUS_IS_OK(status
)) {
4437 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4441 status
= cli_close(cli
, fnum
);
4442 if (!NT_STATUS_IS_OK(status
)) {
4443 printf("close1 failed (%s)\n", nt_errstr(status
));
4447 /* Now create a hardlink. */
4448 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4449 if (!NT_STATUS_IS_OK(status
)) {
4450 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4454 /* Open the original file. */
4455 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4456 FILE_ATTRIBUTE_NORMAL
,
4457 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4458 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4459 if (!NT_STATUS_IS_OK(status
)) {
4460 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4464 /* Unlink the hard link path. */
4465 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4466 FILE_ATTRIBUTE_NORMAL
,
4467 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4468 FILE_OPEN_IF
, 0, 0, &fnum1
, NULL
);
4469 if (!NT_STATUS_IS_OK(status
)) {
4470 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4473 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4476 __location__
, fname_ln
, nt_errstr(status
));
4480 status
= cli_close(cli
, fnum1
);
4481 if (!NT_STATUS_IS_OK(status
)) {
4482 printf("close %s failed (%s)\n",
4483 fname_ln
, nt_errstr(status
));
4487 status
= cli_close(cli
, fnum
);
4488 if (!NT_STATUS_IS_OK(status
)) {
4489 printf("close %s failed (%s)\n",
4490 fname
, nt_errstr(status
));
4494 /* Ensure the original file is still there. */
4495 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4496 if (!NT_STATUS_IS_OK(status
)) {
4497 printf("%s getatr on file %s failed (%s)\n",
4504 /* Ensure the link path is gone. */
4505 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4506 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4507 printf("%s, getatr for file %s returned wrong error code %s "
4508 "- should have been deleted\n",
4510 fname_ln
, nt_errstr(status
));
4514 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4515 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4517 if (!torture_close_connection(cli
)) {
4521 printf("finished deletetest-ln\n");
4527 print out server properties
4529 static bool run_properties(int dummy
)
4531 struct cli_state
*cli
;
4532 bool correct
= True
;
4534 printf("starting properties test\n");
4538 if (!torture_open_connection(&cli
, 0)) {
4542 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4544 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
4546 if (!torture_close_connection(cli
)) {
4555 /* FIRST_DESIRED_ACCESS 0xf019f */
4556 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4557 FILE_READ_EA| /* 0xf */ \
4558 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4559 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4560 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4561 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4562 /* SECOND_DESIRED_ACCESS 0xe0080 */
4563 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4564 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4565 WRITE_OWNER_ACCESS /* 0xe0000 */
4568 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4569 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4571 WRITE_OWNER_ACCESS /* */
4575 Test ntcreate calls made by xcopy
4577 static bool run_xcopy(int dummy
)
4579 static struct cli_state
*cli1
;
4580 const char *fname
= "\\test.txt";
4581 bool correct
= True
;
4582 uint16_t fnum1
, fnum2
;
4585 printf("starting xcopy test\n");
4587 if (!torture_open_connection(&cli1
, 0)) {
4591 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4592 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4593 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
, NULL
);
4594 if (!NT_STATUS_IS_OK(status
)) {
4595 printf("First open failed - %s\n", nt_errstr(status
));
4599 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4600 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4601 FILE_OPEN
, 0x200000, 0, &fnum2
, NULL
);
4602 if (!NT_STATUS_IS_OK(status
)) {
4603 printf("second open failed - %s\n", nt_errstr(status
));
4607 if (!torture_close_connection(cli1
)) {
4615 Test rename on files open with share delete and no share delete.
4617 static bool run_rename(int dummy
)
4619 static struct cli_state
*cli1
;
4620 const char *fname
= "\\test.txt";
4621 const char *fname1
= "\\test1.txt";
4622 bool correct
= True
;
4627 printf("starting rename test\n");
4629 if (!torture_open_connection(&cli1
, 0)) {
4633 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4634 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4636 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4637 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4638 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4639 if (!NT_STATUS_IS_OK(status
)) {
4640 printf("First open failed - %s\n", nt_errstr(status
));
4644 status
= cli_rename(cli1
, fname
, fname1
);
4645 if (!NT_STATUS_IS_OK(status
)) {
4646 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4648 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4652 status
= cli_close(cli1
, fnum1
);
4653 if (!NT_STATUS_IS_OK(status
)) {
4654 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4658 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4659 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4660 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4662 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4664 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4666 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4667 if (!NT_STATUS_IS_OK(status
)) {
4668 printf("Second open failed - %s\n", nt_errstr(status
));
4672 status
= cli_rename(cli1
, fname
, fname1
);
4673 if (!NT_STATUS_IS_OK(status
)) {
4674 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4677 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4680 status
= cli_close(cli1
, fnum1
);
4681 if (!NT_STATUS_IS_OK(status
)) {
4682 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4686 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4687 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4689 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4690 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4691 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4692 if (!NT_STATUS_IS_OK(status
)) {
4693 printf("Third open failed - %s\n", nt_errstr(status
));
4702 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4703 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
, NULL
))) {
4704 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4707 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4708 printf("[8] setting delete_on_close on file failed !\n");
4712 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4713 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4719 status
= cli_rename(cli1
, fname
, fname1
);
4720 if (!NT_STATUS_IS_OK(status
)) {
4721 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4724 printf("Third rename succeeded (SHARE_NONE)\n");
4727 status
= cli_close(cli1
, fnum1
);
4728 if (!NT_STATUS_IS_OK(status
)) {
4729 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4733 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4734 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4738 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4739 FILE_ATTRIBUTE_NORMAL
,
4740 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4741 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4742 if (!NT_STATUS_IS_OK(status
)) {
4743 printf("Fourth open failed - %s\n", nt_errstr(status
));
4747 status
= cli_rename(cli1
, fname
, fname1
);
4748 if (!NT_STATUS_IS_OK(status
)) {
4749 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4751 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4755 status
= cli_close(cli1
, fnum1
);
4756 if (!NT_STATUS_IS_OK(status
)) {
4757 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4761 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4762 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4766 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4767 FILE_ATTRIBUTE_NORMAL
,
4768 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4769 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
4770 if (!NT_STATUS_IS_OK(status
)) {
4771 printf("Fifth open failed - %s\n", nt_errstr(status
));
4775 status
= cli_rename(cli1
, fname
, fname1
);
4776 if (!NT_STATUS_IS_OK(status
)) {
4777 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4780 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4784 * Now check if the first name still exists ...
4787 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4788 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4789 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4790 printf("Opening original file after rename of open file fails: %s\n",
4794 printf("Opening original file after rename of open file works ...\n");
4795 (void)cli_close(cli1, fnum2);
4799 status
= cli_close(cli1
, fnum1
);
4800 if (!NT_STATUS_IS_OK(status
)) {
4801 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4805 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4806 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4807 if (!NT_STATUS_IS_OK(status
)) {
4808 printf("getatr on file %s failed - %s ! \n",
4809 fname1
, nt_errstr(status
));
4812 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4813 printf("Renamed file %s has wrong attr 0x%x "
4814 "(should be 0x%x)\n",
4817 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4820 printf("Renamed file %s has archive bit set\n", fname1
);
4824 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4825 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4827 if (!torture_close_connection(cli1
)) {
4834 static bool run_pipe_number(int dummy
)
4836 struct cli_state
*cli1
;
4837 const char *pipe_name
= "\\SPOOLSS";
4842 printf("starting pipenumber test\n");
4843 if (!torture_open_connection(&cli1
, 0)) {
4847 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4849 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4850 FILE_ATTRIBUTE_NORMAL
,
4851 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4852 FILE_OPEN_IF
, 0, 0, &fnum
, NULL
);
4853 if (!NT_STATUS_IS_OK(status
)) {
4854 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4858 printf("\r%6d", num_pipes
);
4861 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4862 torture_close_connection(cli1
);
4867 Test open mode returns on read-only files.
4869 static bool run_opentest(int dummy
)
4871 static struct cli_state
*cli1
;
4872 static struct cli_state
*cli2
;
4873 const char *fname
= "\\readonly.file";
4874 uint16_t fnum1
, fnum2
;
4877 bool correct
= True
;
4881 printf("starting open test\n");
4883 if (!torture_open_connection(&cli1
, 0)) {
4887 cli_setatr(cli1
, fname
, 0, 0);
4888 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4890 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4892 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4893 if (!NT_STATUS_IS_OK(status
)) {
4894 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4898 status
= cli_close(cli1
, fnum1
);
4899 if (!NT_STATUS_IS_OK(status
)) {
4900 printf("close2 failed (%s)\n", nt_errstr(status
));
4904 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4905 if (!NT_STATUS_IS_OK(status
)) {
4906 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4910 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4911 if (!NT_STATUS_IS_OK(status
)) {
4912 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4916 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4917 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4919 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
4920 NT_STATUS_ACCESS_DENIED
)) {
4921 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4924 printf("finished open test 1\n");
4926 cli_close(cli1
, fnum1
);
4928 /* Now try not readonly and ensure ERRbadshare is returned. */
4930 cli_setatr(cli1
, fname
, 0, 0);
4932 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4933 if (!NT_STATUS_IS_OK(status
)) {
4934 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4938 /* This will fail - but the error should be ERRshare. */
4939 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4941 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
4942 NT_STATUS_SHARING_VIOLATION
)) {
4943 printf("correct error code ERRDOS/ERRbadshare returned\n");
4946 status
= cli_close(cli1
, fnum1
);
4947 if (!NT_STATUS_IS_OK(status
)) {
4948 printf("close2 failed (%s)\n", nt_errstr(status
));
4952 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4954 printf("finished open test 2\n");
4956 /* Test truncate open disposition on file opened for read. */
4957 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4958 if (!NT_STATUS_IS_OK(status
)) {
4959 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
4963 /* write 20 bytes. */
4965 memset(buf
, '\0', 20);
4967 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4968 if (!NT_STATUS_IS_OK(status
)) {
4969 printf("write failed (%s)\n", nt_errstr(status
));
4973 status
= cli_close(cli1
, fnum1
);
4974 if (!NT_STATUS_IS_OK(status
)) {
4975 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
4979 /* Ensure size == 20. */
4980 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4981 if (!NT_STATUS_IS_OK(status
)) {
4982 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4987 printf("(3) file size != 20\n");
4991 /* Now test if we can truncate a file opened for readonly. */
4992 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
4993 if (!NT_STATUS_IS_OK(status
)) {
4994 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
4998 status
= cli_close(cli1
, fnum1
);
4999 if (!NT_STATUS_IS_OK(status
)) {
5000 printf("close2 failed (%s)\n", nt_errstr(status
));
5004 /* Ensure size == 0. */
5005 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
5006 if (!NT_STATUS_IS_OK(status
)) {
5007 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
5012 printf("(3) file size != 0\n");
5015 printf("finished open test 3\n");
5017 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5019 printf("Do ctemp tests\n");
5020 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
5021 if (!NT_STATUS_IS_OK(status
)) {
5022 printf("ctemp failed (%s)\n", nt_errstr(status
));
5026 printf("ctemp gave path %s\n", tmp_path
);
5027 status
= cli_close(cli1
, fnum1
);
5028 if (!NT_STATUS_IS_OK(status
)) {
5029 printf("close of temp failed (%s)\n", nt_errstr(status
));
5032 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5033 if (!NT_STATUS_IS_OK(status
)) {
5034 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5037 /* Test the non-io opens... */
5039 if (!torture_open_connection(&cli2
, 1)) {
5043 cli_setatr(cli2
, fname
, 0, 0);
5044 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5046 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
5048 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5049 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5050 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5051 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5052 if (!NT_STATUS_IS_OK(status
)) {
5053 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5057 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5058 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5059 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5060 if (!NT_STATUS_IS_OK(status
)) {
5061 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5065 status
= cli_close(cli1
, fnum1
);
5066 if (!NT_STATUS_IS_OK(status
)) {
5067 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5071 status
= cli_close(cli2
, fnum2
);
5072 if (!NT_STATUS_IS_OK(status
)) {
5073 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5077 printf("non-io open test #1 passed.\n");
5079 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5081 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5083 status
= cli_ntcreate(cli1
, fname
, 0,
5084 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5085 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5086 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5087 if (!NT_STATUS_IS_OK(status
)) {
5088 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5092 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5093 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5094 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5095 if (!NT_STATUS_IS_OK(status
)) {
5096 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5100 status
= cli_close(cli1
, fnum1
);
5101 if (!NT_STATUS_IS_OK(status
)) {
5102 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5106 status
= cli_close(cli2
, fnum2
);
5107 if (!NT_STATUS_IS_OK(status
)) {
5108 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5112 printf("non-io open test #2 passed.\n");
5114 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5116 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5118 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5119 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5120 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5121 if (!NT_STATUS_IS_OK(status
)) {
5122 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5126 status
= cli_ntcreate(cli2
, fname
, 0,
5127 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5128 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5129 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5130 if (!NT_STATUS_IS_OK(status
)) {
5131 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5135 status
= cli_close(cli1
, fnum1
);
5136 if (!NT_STATUS_IS_OK(status
)) {
5137 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5141 status
= cli_close(cli2
, fnum2
);
5142 if (!NT_STATUS_IS_OK(status
)) {
5143 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5147 printf("non-io open test #3 passed.\n");
5149 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5151 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5153 status
= cli_ntcreate(cli1
, fname
, 0,
5154 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5155 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5156 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5157 if (!NT_STATUS_IS_OK(status
)) {
5158 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5162 status
= cli_ntcreate(cli2
, fname
, 0,
5163 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5164 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5165 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5166 if (NT_STATUS_IS_OK(status
)) {
5167 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5171 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5173 status
= cli_close(cli1
, fnum1
);
5174 if (!NT_STATUS_IS_OK(status
)) {
5175 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5179 printf("non-io open test #4 passed.\n");
5181 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5183 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5185 status
= cli_ntcreate(cli1
, fname
, 0,
5186 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5187 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5188 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5189 if (!NT_STATUS_IS_OK(status
)) {
5190 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5194 status
= cli_ntcreate(cli2
, fname
, 0,
5195 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5196 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5197 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5198 if (!NT_STATUS_IS_OK(status
)) {
5199 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5203 status
= cli_close(cli1
, fnum1
);
5204 if (!NT_STATUS_IS_OK(status
)) {
5205 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5209 status
= cli_close(cli2
, fnum2
);
5210 if (!NT_STATUS_IS_OK(status
)) {
5211 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5215 printf("non-io open test #5 passed.\n");
5217 printf("TEST #6 testing 1 non-io open, one io open\n");
5219 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5221 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5222 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5223 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5224 if (!NT_STATUS_IS_OK(status
)) {
5225 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5229 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5230 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5231 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5232 if (!NT_STATUS_IS_OK(status
)) {
5233 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5237 status
= cli_close(cli1
, fnum1
);
5238 if (!NT_STATUS_IS_OK(status
)) {
5239 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5243 status
= cli_close(cli2
, fnum2
);
5244 if (!NT_STATUS_IS_OK(status
)) {
5245 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5249 printf("non-io open test #6 passed.\n");
5251 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5253 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5255 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5256 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5257 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5258 if (!NT_STATUS_IS_OK(status
)) {
5259 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5263 status
= cli_ntcreate(cli2
, fname
, 0,
5264 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5265 FILE_ATTRIBUTE_NORMAL
,
5266 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5267 FILE_OPEN_IF
, 0, 0, &fnum2
, NULL
);
5268 if (NT_STATUS_IS_OK(status
)) {
5269 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5273 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5275 status
= cli_close(cli1
, fnum1
);
5276 if (!NT_STATUS_IS_OK(status
)) {
5277 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5281 printf("non-io open test #7 passed.\n");
5283 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5285 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5286 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5287 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5288 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5289 if (!NT_STATUS_IS_OK(status
)) {
5290 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5295 /* Write to ensure we have to update the file time. */
5296 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5298 if (!NT_STATUS_IS_OK(status
)) {
5299 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5304 status
= cli_close(cli1
, fnum1
);
5305 if (!NT_STATUS_IS_OK(status
)) {
5306 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5312 if (!torture_close_connection(cli1
)) {
5315 if (!torture_close_connection(cli2
)) {
5322 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5324 uint16_t major
, minor
;
5325 uint32_t caplow
, caphigh
;
5328 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5329 printf("Server doesn't support UNIX CIFS extensions.\n");
5330 return NT_STATUS_NOT_SUPPORTED
;
5333 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5335 if (!NT_STATUS_IS_OK(status
)) {
5336 printf("Server didn't return UNIX CIFS extensions: %s\n",
5341 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5343 if (!NT_STATUS_IS_OK(status
)) {
5344 printf("Server doesn't support setting UNIX CIFS extensions: "
5345 "%s.\n", nt_errstr(status
));
5349 return NT_STATUS_OK
;
5353 Test POSIX open /mkdir calls.
5355 static bool run_simple_posix_open_test(int dummy
)
5357 static struct cli_state
*cli1
;
5358 const char *fname
= "posix:file";
5359 const char *hname
= "posix:hlink";
5360 const char *sname
= "posix:symlink";
5361 const char *dname
= "posix:dir";
5364 uint16_t fnum1
= (uint16_t)-1;
5365 SMB_STRUCT_STAT sbuf
;
5366 bool correct
= false;
5369 const char *fname_windows
= "windows_file";
5370 uint16_t fnum2
= (uint16_t)-1;
5372 printf("Starting simple POSIX open test\n");
5374 if (!torture_open_connection(&cli1
, 0)) {
5378 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5380 status
= torture_setup_unix_extensions(cli1
);
5381 if (!NT_STATUS_IS_OK(status
)) {
5385 cli_setatr(cli1
, fname
, 0, 0);
5386 cli_posix_unlink(cli1
, fname
);
5387 cli_setatr(cli1
, dname
, 0, 0);
5388 cli_posix_rmdir(cli1
, dname
);
5389 cli_setatr(cli1
, hname
, 0, 0);
5390 cli_posix_unlink(cli1
, hname
);
5391 cli_setatr(cli1
, sname
, 0, 0);
5392 cli_posix_unlink(cli1
, sname
);
5393 cli_setatr(cli1
, fname_windows
, 0, 0);
5394 cli_posix_unlink(cli1
, fname_windows
);
5396 /* Create a directory. */
5397 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5398 if (!NT_STATUS_IS_OK(status
)) {
5399 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5403 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5405 if (!NT_STATUS_IS_OK(status
)) {
5406 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5410 /* Test ftruncate - set file size. */
5411 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5412 if (!NT_STATUS_IS_OK(status
)) {
5413 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5417 /* Ensure st_size == 1000 */
5418 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5419 if (!NT_STATUS_IS_OK(status
)) {
5420 printf("stat failed (%s)\n", nt_errstr(status
));
5424 if (sbuf
.st_ex_size
!= 1000) {
5425 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5429 /* Ensure st_mode == 0600 */
5430 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
5431 printf("posix_open - bad permissions 0%o != 0600\n",
5432 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5436 /* Test ftruncate - set file size back to zero. */
5437 status
= cli_ftruncate(cli1
, fnum1
, 0);
5438 if (!NT_STATUS_IS_OK(status
)) {
5439 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5443 status
= cli_close(cli1
, fnum1
);
5444 if (!NT_STATUS_IS_OK(status
)) {
5445 printf("close failed (%s)\n", nt_errstr(status
));
5449 /* Now open the file again for read only. */
5450 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5451 if (!NT_STATUS_IS_OK(status
)) {
5452 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5456 /* Now unlink while open. */
5457 status
= cli_posix_unlink(cli1
, fname
);
5458 if (!NT_STATUS_IS_OK(status
)) {
5459 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5463 status
= cli_close(cli1
, fnum1
);
5464 if (!NT_STATUS_IS_OK(status
)) {
5465 printf("close(2) failed (%s)\n", nt_errstr(status
));
5469 /* Ensure the file has gone. */
5470 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5471 if (NT_STATUS_IS_OK(status
)) {
5472 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5476 /* Create again to test open with O_TRUNC. */
5477 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5478 if (!NT_STATUS_IS_OK(status
)) {
5479 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5483 /* Test ftruncate - set file size. */
5484 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5485 if (!NT_STATUS_IS_OK(status
)) {
5486 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5490 /* Ensure st_size == 1000 */
5491 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5492 if (!NT_STATUS_IS_OK(status
)) {
5493 printf("stat failed (%s)\n", nt_errstr(status
));
5497 if (sbuf
.st_ex_size
!= 1000) {
5498 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5502 status
= cli_close(cli1
, fnum1
);
5503 if (!NT_STATUS_IS_OK(status
)) {
5504 printf("close(2) failed (%s)\n", nt_errstr(status
));
5508 /* Re-open with O_TRUNC. */
5509 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5510 if (!NT_STATUS_IS_OK(status
)) {
5511 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5515 /* Ensure st_size == 0 */
5516 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5517 if (!NT_STATUS_IS_OK(status
)) {
5518 printf("stat failed (%s)\n", nt_errstr(status
));
5522 if (sbuf
.st_ex_size
!= 0) {
5523 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5527 status
= cli_close(cli1
, fnum1
);
5528 if (!NT_STATUS_IS_OK(status
)) {
5529 printf("close failed (%s)\n", nt_errstr(status
));
5533 status
= cli_posix_unlink(cli1
, fname
);
5534 if (!NT_STATUS_IS_OK(status
)) {
5535 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5539 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5540 if (!NT_STATUS_IS_OK(status
)) {
5541 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5542 dname
, nt_errstr(status
));
5546 cli_close(cli1
, fnum1
);
5548 /* What happens when we try and POSIX open a directory for write ? */
5549 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5550 if (NT_STATUS_IS_OK(status
)) {
5551 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5554 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5555 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5560 /* Create the file. */
5561 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5563 if (!NT_STATUS_IS_OK(status
)) {
5564 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5568 /* Write some data into it. */
5569 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5571 if (!NT_STATUS_IS_OK(status
)) {
5572 printf("cli_write failed: %s\n", nt_errstr(status
));
5576 cli_close(cli1
, fnum1
);
5578 /* Now create a hardlink. */
5579 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5580 if (!NT_STATUS_IS_OK(status
)) {
5581 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5585 /* Now create a symlink. */
5586 status
= cli_posix_symlink(cli1
, fname
, sname
);
5587 if (!NT_STATUS_IS_OK(status
)) {
5588 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5592 /* Open the hardlink for read. */
5593 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5594 if (!NT_STATUS_IS_OK(status
)) {
5595 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5599 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5600 if (!NT_STATUS_IS_OK(status
)) {
5601 printf("POSIX read of %s failed (%s)\n", hname
,
5604 } else if (nread
!= 10) {
5605 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5606 hname
, (unsigned long)nread
, 10);
5610 if (memcmp(buf
, "TEST DATA\n", 10)) {
5611 printf("invalid data read from hardlink\n");
5615 /* Do a POSIX lock/unlock. */
5616 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5617 if (!NT_STATUS_IS_OK(status
)) {
5618 printf("POSIX lock failed %s\n", nt_errstr(status
));
5622 /* Punch a hole in the locked area. */
5623 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5624 if (!NT_STATUS_IS_OK(status
)) {
5625 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5629 cli_close(cli1
, fnum1
);
5631 /* Open the symlink for read - this should fail. A POSIX
5632 client should not be doing opens on a symlink. */
5633 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5634 if (NT_STATUS_IS_OK(status
)) {
5635 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5638 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5639 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5640 printf("POSIX open of %s should have failed "
5641 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5642 "failed with %s instead.\n",
5643 sname
, nt_errstr(status
));
5648 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5649 if (!NT_STATUS_IS_OK(status
)) {
5650 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5654 if (strcmp(namebuf
, fname
) != 0) {
5655 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5656 sname
, fname
, namebuf
);
5660 status
= cli_posix_rmdir(cli1
, dname
);
5661 if (!NT_STATUS_IS_OK(status
)) {
5662 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5666 /* Check directory opens with a specific permission. */
5667 status
= cli_posix_mkdir(cli1
, dname
, 0700);
5668 if (!NT_STATUS_IS_OK(status
)) {
5669 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5673 /* Ensure st_mode == 0700 */
5674 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
5675 if (!NT_STATUS_IS_OK(status
)) {
5676 printf("stat failed (%s)\n", nt_errstr(status
));
5680 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
5681 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5682 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5687 * Now create a Windows file, and attempt a POSIX unlink.
5688 * This should fail with a sharing violation but due to:
5690 * [Bug 9571] Unlink after open causes smbd to panic
5692 * ensure we've fixed the lock ordering violation.
5695 status
= cli_ntcreate(cli1
, fname_windows
, 0,
5696 FILE_READ_DATA
|FILE_WRITE_DATA
, 0,
5697 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5699 0x0, 0x0, &fnum2
, NULL
);
5700 if (!NT_STATUS_IS_OK(status
)) {
5701 printf("Windows create of %s failed (%s)\n", fname_windows
,
5706 /* Now try posix_unlink. */
5707 status
= cli_posix_unlink(cli1
, fname_windows
);
5708 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
5709 printf("POSIX unlink of %s should fail "
5710 "with NT_STATUS_SHARING_VIOLATION "
5711 "got %s instead !\n",
5717 cli_close(cli1
, fnum2
);
5719 printf("Simple POSIX open test passed\n");
5724 if (fnum1
!= (uint16_t)-1) {
5725 cli_close(cli1
, fnum1
);
5726 fnum1
= (uint16_t)-1;
5729 if (fnum2
!= (uint16_t)-1) {
5730 cli_close(cli1
, fnum2
);
5731 fnum2
= (uint16_t)-1;
5734 cli_setatr(cli1
, sname
, 0, 0);
5735 cli_posix_unlink(cli1
, sname
);
5736 cli_setatr(cli1
, hname
, 0, 0);
5737 cli_posix_unlink(cli1
, hname
);
5738 cli_setatr(cli1
, fname
, 0, 0);
5739 cli_posix_unlink(cli1
, fname
);
5740 cli_setatr(cli1
, dname
, 0, 0);
5741 cli_posix_rmdir(cli1
, dname
);
5742 cli_setatr(cli1
, fname_windows
, 0, 0);
5743 cli_posix_unlink(cli1
, fname_windows
);
5745 if (!torture_close_connection(cli1
)) {
5753 static uint32_t open_attrs_table
[] = {
5754 FILE_ATTRIBUTE_NORMAL
,
5755 FILE_ATTRIBUTE_ARCHIVE
,
5756 FILE_ATTRIBUTE_READONLY
,
5757 FILE_ATTRIBUTE_HIDDEN
,
5758 FILE_ATTRIBUTE_SYSTEM
,
5760 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5761 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5762 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5763 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5764 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5765 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5767 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5768 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5769 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5770 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5773 struct trunc_open_results
{
5776 uint32_t trunc_attr
;
5777 uint32_t result_attr
;
5780 static struct trunc_open_results attr_results
[] = {
5781 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5782 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5783 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5784 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5785 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5786 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5787 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5788 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5789 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5790 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5791 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5792 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5793 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5794 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5795 { 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
},
5796 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5797 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5798 { 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
},
5799 { 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
},
5800 { 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
},
5801 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5802 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5803 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5804 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5805 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5806 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5809 static bool run_openattrtest(int dummy
)
5811 static struct cli_state
*cli1
;
5812 const char *fname
= "\\openattr.file";
5814 bool correct
= True
;
5816 unsigned int i
, j
, k
, l
;
5819 printf("starting open attr test\n");
5821 if (!torture_open_connection(&cli1
, 0)) {
5825 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5827 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32_t); i
++) {
5828 cli_setatr(cli1
, fname
, 0, 0);
5829 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5831 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5832 open_attrs_table
[i
], FILE_SHARE_NONE
,
5833 FILE_OVERWRITE_IF
, 0, 0, &fnum1
, NULL
);
5834 if (!NT_STATUS_IS_OK(status
)) {
5835 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5839 status
= cli_close(cli1
, fnum1
);
5840 if (!NT_STATUS_IS_OK(status
)) {
5841 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5845 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32_t); j
++) {
5846 status
= cli_ntcreate(cli1
, fname
, 0,
5847 FILE_READ_DATA
|FILE_WRITE_DATA
,
5848 open_attrs_table
[j
],
5849 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5850 0, 0, &fnum1
, NULL
);
5851 if (!NT_STATUS_IS_OK(status
)) {
5852 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5853 if (attr_results
[l
].num
== k
) {
5854 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5855 k
, open_attrs_table
[i
],
5856 open_attrs_table
[j
],
5857 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5862 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5863 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5864 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5869 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5875 status
= cli_close(cli1
, fnum1
);
5876 if (!NT_STATUS_IS_OK(status
)) {
5877 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5881 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5882 if (!NT_STATUS_IS_OK(status
)) {
5883 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5888 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5889 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5892 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5893 if (attr_results
[l
].num
== k
) {
5894 if (attr
!= attr_results
[l
].result_attr
||
5895 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5896 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5897 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5898 open_attrs_table
[i
],
5899 open_attrs_table
[j
],
5901 attr_results
[l
].result_attr
);
5911 cli_setatr(cli1
, fname
, 0, 0);
5912 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5914 printf("open attr test %s.\n", correct
? "passed" : "failed");
5916 if (!torture_close_connection(cli1
)) {
5922 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5923 const char *name
, void *state
)
5925 int *matched
= (int *)state
;
5926 if (matched
!= NULL
) {
5929 return NT_STATUS_OK
;
5933 test directory listing speed
5935 static bool run_dirtest(int dummy
)
5938 static struct cli_state
*cli
;
5940 struct timeval core_start
;
5941 bool correct
= True
;
5944 printf("starting directory test\n");
5946 if (!torture_open_connection(&cli
, 0)) {
5950 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5953 for (i
=0;i
<torture_numops
;i
++) {
5955 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5956 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5957 fprintf(stderr
,"Failed to open %s\n", fname
);
5960 cli_close(cli
, fnum
);
5963 core_start
= timeval_current();
5966 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5967 printf("Matched %d\n", matched
);
5970 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5971 printf("Matched %d\n", matched
);
5974 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5975 printf("Matched %d\n", matched
);
5977 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5980 for (i
=0;i
<torture_numops
;i
++) {
5982 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5983 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5986 if (!torture_close_connection(cli
)) {
5990 printf("finished dirtest\n");
5995 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5998 struct cli_state
*pcli
= (struct cli_state
*)state
;
6000 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
6002 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6003 return NT_STATUS_OK
;
6005 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
6006 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
6007 printf("del_fn: failed to rmdir %s\n,", fname
);
6009 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
6010 printf("del_fn: failed to unlink %s\n,", fname
);
6012 return NT_STATUS_OK
;
6017 sees what IOCTLs are supported
6019 bool torture_ioctl_test(int dummy
)
6021 static struct cli_state
*cli
;
6022 uint16_t device
, function
;
6024 const char *fname
= "\\ioctl.dat";
6028 if (!torture_open_connection(&cli
, 0)) {
6032 printf("starting ioctl test\n");
6034 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6036 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
6037 if (!NT_STATUS_IS_OK(status
)) {
6038 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
6042 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
6043 printf("ioctl device info: %s\n", nt_errstr(status
));
6045 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
6046 printf("ioctl job info: %s\n", nt_errstr(status
));
6048 for (device
=0;device
<0x100;device
++) {
6049 printf("ioctl test with device = 0x%x\n", device
);
6050 for (function
=0;function
<0x100;function
++) {
6051 uint32_t code
= (device
<<16) | function
;
6053 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
6055 if (NT_STATUS_IS_OK(status
)) {
6056 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
6058 data_blob_free(&blob
);
6063 if (!torture_close_connection(cli
)) {
6072 tries varients of chkpath
6074 bool torture_chkpath_test(int dummy
)
6076 static struct cli_state
*cli
;
6081 if (!torture_open_connection(&cli
, 0)) {
6085 printf("starting chkpath test\n");
6087 /* cleanup from an old run */
6088 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6089 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6090 cli_rmdir(cli
, "\\chkpath.dir");
6092 status
= cli_mkdir(cli
, "\\chkpath.dir");
6093 if (!NT_STATUS_IS_OK(status
)) {
6094 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6098 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6099 if (!NT_STATUS_IS_OK(status
)) {
6100 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6104 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6106 if (!NT_STATUS_IS_OK(status
)) {
6107 printf("open1 failed (%s)\n", nt_errstr(status
));
6110 cli_close(cli
, fnum
);
6112 status
= cli_chkpath(cli
, "\\chkpath.dir");
6113 if (!NT_STATUS_IS_OK(status
)) {
6114 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6118 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6119 if (!NT_STATUS_IS_OK(status
)) {
6120 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6124 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6125 if (!NT_STATUS_IS_OK(status
)) {
6126 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6127 NT_STATUS_NOT_A_DIRECTORY
);
6129 printf("* chkpath on a file should fail\n");
6133 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6134 if (!NT_STATUS_IS_OK(status
)) {
6135 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6136 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6138 printf("* chkpath on a non existent file should fail\n");
6142 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6143 if (!NT_STATUS_IS_OK(status
)) {
6144 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6145 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6147 printf("* chkpath on a non existent component should fail\n");
6151 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6152 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6153 cli_rmdir(cli
, "\\chkpath.dir");
6155 if (!torture_close_connection(cli
)) {
6162 static bool run_eatest(int dummy
)
6164 static struct cli_state
*cli
;
6165 const char *fname
= "\\eatest.txt";
6166 bool correct
= True
;
6170 struct ea_struct
*ea_list
= NULL
;
6171 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6174 printf("starting eatest\n");
6176 if (!torture_open_connection(&cli
, 0)) {
6177 talloc_destroy(mem_ctx
);
6181 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6183 status
= cli_ntcreate(cli
, fname
, 0,
6184 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6185 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6186 0x4044, 0, &fnum
, NULL
);
6187 if (!NT_STATUS_IS_OK(status
)) {
6188 printf("open failed - %s\n", nt_errstr(status
));
6189 talloc_destroy(mem_ctx
);
6193 for (i
= 0; i
< 10; i
++) {
6194 fstring ea_name
, ea_val
;
6196 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6197 memset(ea_val
, (char)i
+1, i
+1);
6198 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6199 if (!NT_STATUS_IS_OK(status
)) {
6200 printf("ea_set of name %s failed - %s\n", ea_name
,
6202 talloc_destroy(mem_ctx
);
6207 cli_close(cli
, fnum
);
6208 for (i
= 0; i
< 10; i
++) {
6209 fstring ea_name
, ea_val
;
6211 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6212 memset(ea_val
, (char)i
+1, i
+1);
6213 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6214 if (!NT_STATUS_IS_OK(status
)) {
6215 printf("ea_set of name %s failed - %s\n", ea_name
,
6217 talloc_destroy(mem_ctx
);
6222 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6223 if (!NT_STATUS_IS_OK(status
)) {
6224 printf("ea_get list failed - %s\n", nt_errstr(status
));
6228 printf("num_eas = %d\n", (int)num_eas
);
6230 if (num_eas
!= 20) {
6231 printf("Should be 20 EA's stored... failing.\n");
6235 for (i
= 0; i
< num_eas
; i
++) {
6236 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6237 dump_data(0, ea_list
[i
].value
.data
,
6238 ea_list
[i
].value
.length
);
6241 /* Setting EA's to zero length deletes them. Test this */
6242 printf("Now deleting all EA's - case indepenent....\n");
6245 cli_set_ea_path(cli
, fname
, "", "", 0);
6247 for (i
= 0; i
< 20; i
++) {
6249 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6250 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6251 if (!NT_STATUS_IS_OK(status
)) {
6252 printf("ea_set of name %s failed - %s\n", ea_name
,
6254 talloc_destroy(mem_ctx
);
6260 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6261 if (!NT_STATUS_IS_OK(status
)) {
6262 printf("ea_get list failed - %s\n", nt_errstr(status
));
6266 printf("num_eas = %d\n", (int)num_eas
);
6267 for (i
= 0; i
< num_eas
; i
++) {
6268 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6269 dump_data(0, ea_list
[i
].value
.data
,
6270 ea_list
[i
].value
.length
);
6274 printf("deleting EA's failed.\n");
6278 /* Try and delete a non existent EA. */
6279 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6280 if (!NT_STATUS_IS_OK(status
)) {
6281 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6286 talloc_destroy(mem_ctx
);
6287 if (!torture_close_connection(cli
)) {
6294 static bool run_dirtest1(int dummy
)
6297 static struct cli_state
*cli
;
6300 bool correct
= True
;
6302 printf("starting directory test\n");
6304 if (!torture_open_connection(&cli
, 0)) {
6308 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6310 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6311 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6312 cli_rmdir(cli
, "\\LISTDIR");
6313 cli_mkdir(cli
, "\\LISTDIR");
6315 /* Create 1000 files and 1000 directories. */
6316 for (i
=0;i
<1000;i
++) {
6318 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6319 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6320 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
,
6321 0, 0, &fnum
, NULL
))) {
6322 fprintf(stderr
,"Failed to open %s\n", fname
);
6325 cli_close(cli
, fnum
);
6327 for (i
=0;i
<1000;i
++) {
6329 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6330 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6331 fprintf(stderr
,"Failed to open %s\n", fname
);
6336 /* Now ensure that doing an old list sees both files and directories. */
6338 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6339 printf("num_seen = %d\n", num_seen
);
6340 /* We should see 100 files + 1000 directories + . and .. */
6341 if (num_seen
!= 2002)
6344 /* Ensure if we have the "must have" bits we only see the
6348 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6349 printf("num_seen = %d\n", num_seen
);
6350 if (num_seen
!= 1002)
6354 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6355 printf("num_seen = %d\n", num_seen
);
6356 if (num_seen
!= 1000)
6359 /* Delete everything. */
6360 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6361 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6362 cli_rmdir(cli
, "\\LISTDIR");
6365 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6366 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6367 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6370 if (!torture_close_connection(cli
)) {
6374 printf("finished dirtest1\n");
6379 static bool run_error_map_extract(int dummy
) {
6381 static struct cli_state
*c_dos
;
6382 static struct cli_state
*c_nt
;
6394 /* NT-Error connection */
6396 disable_spnego
= true;
6397 if (!(c_nt
= open_nbt_connection())) {
6398 disable_spnego
= false;
6401 disable_spnego
= false;
6403 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
6406 if (!NT_STATUS_IS_OK(status
)) {
6407 printf("%s rejected the NT-error negprot (%s)\n", host
,
6413 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6414 if (!NT_STATUS_IS_OK(status
)) {
6415 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6419 /* DOS-Error connection */
6421 disable_spnego
= true;
6422 force_dos_errors
= true;
6423 if (!(c_dos
= open_nbt_connection())) {
6424 disable_spnego
= false;
6425 force_dos_errors
= false;
6428 disable_spnego
= false;
6429 force_dos_errors
= false;
6431 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
6433 if (!NT_STATUS_IS_OK(status
)) {
6434 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6436 cli_shutdown(c_dos
);
6440 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6441 if (!NT_STATUS_IS_OK(status
)) {
6442 printf("%s rejected the DOS-error initial session setup (%s)\n",
6443 host
, nt_errstr(status
));
6447 c_nt
->map_dos_errors
= false;
6448 c_dos
->map_dos_errors
= false;
6450 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6451 fstr_sprintf(user
, "%X", error
);
6453 status
= cli_session_setup(c_nt
, user
,
6454 password
, strlen(password
),
6455 password
, strlen(password
),
6457 if (NT_STATUS_IS_OK(status
)) {
6458 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6461 /* Case #1: 32-bit NT errors */
6462 if (!NT_STATUS_IS_DOS(status
)) {
6465 printf("/** Dos error on NT connection! (%s) */\n",
6467 nt_status
= NT_STATUS(0xc0000000);
6470 status
= cli_session_setup(c_dos
, user
,
6471 password
, strlen(password
),
6472 password
, strlen(password
),
6474 if (NT_STATUS_IS_OK(status
)) {
6475 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6478 /* Case #1: 32-bit NT errors */
6479 if (NT_STATUS_IS_DOS(status
)) {
6480 printf("/** NT error on DOS connection! (%s) */\n",
6482 errnum
= errclass
= 0;
6484 errclass
= NT_STATUS_DOS_CLASS(status
);
6485 errnum
= NT_STATUS_DOS_CODE(status
);
6488 if (NT_STATUS_V(nt_status
) != error
) {
6489 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6490 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6491 get_nt_error_c_code(talloc_tos(), nt_status
));
6494 printf("\t{%s,\t%s,\t%s},\n",
6495 smb_dos_err_class(errclass
),
6496 smb_dos_err_name(errclass
, errnum
),
6497 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6502 static bool run_sesssetup_bench(int dummy
)
6504 static struct cli_state
*c
;
6505 const char *fname
= "\\file.dat";
6510 if (!torture_open_connection(&c
, 0)) {
6514 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6515 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6516 FILE_DELETE_ON_CLOSE
, 0, &fnum
, NULL
);
6517 if (!NT_STATUS_IS_OK(status
)) {
6518 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6522 for (i
=0; i
<torture_numops
; i
++) {
6523 status
= cli_session_setup(
6525 password
, strlen(password
),
6526 password
, strlen(password
),
6528 if (!NT_STATUS_IS_OK(status
)) {
6529 d_printf("(%s) cli_session_setup failed: %s\n",
6530 __location__
, nt_errstr(status
));
6534 d_printf("\r%d ", (int)cli_state_get_uid(c
));
6536 status
= cli_ulogoff(c
);
6537 if (!NT_STATUS_IS_OK(status
)) {
6538 d_printf("(%s) cli_ulogoff failed: %s\n",
6539 __location__
, nt_errstr(status
));
6547 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6548 uid_t uid
, gid_t gid
, const char *expected
)
6553 subst
= talloc_sub_specified(talloc_tos(), str
, user
, NULL
, domain
, uid
, gid
);
6555 if (strcmp(subst
, expected
) != 0) {
6556 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6557 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6566 static void chain1_open_completion(struct tevent_req
*req
)
6570 status
= cli_openx_recv(req
, &fnum
);
6573 d_printf("cli_openx_recv returned %s: %d\n",
6575 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6578 static void chain1_write_completion(struct tevent_req
*req
)
6582 status
= cli_write_andx_recv(req
, &written
);
6585 d_printf("cli_write_andx_recv returned %s: %d\n",
6587 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6590 static void chain1_close_completion(struct tevent_req
*req
)
6593 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6595 status
= cli_close_recv(req
);
6600 d_printf("cli_close returned %s\n", nt_errstr(status
));
6603 static bool run_chain1(int dummy
)
6605 struct cli_state
*cli1
;
6606 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
6607 struct tevent_req
*reqs
[3], *smbreqs
[3];
6609 const char *str
= "foobar";
6612 printf("starting chain1 test\n");
6613 if (!torture_open_connection(&cli1
, 0)) {
6617 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6619 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, "\\test",
6620 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6621 if (reqs
[0] == NULL
) return false;
6622 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6625 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6626 (const uint8_t *)str
, 0, strlen(str
)+1,
6627 smbreqs
, 1, &smbreqs
[1]);
6628 if (reqs
[1] == NULL
) return false;
6629 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6631 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6632 if (reqs
[2] == NULL
) return false;
6633 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6635 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
6636 if (!NT_STATUS_IS_OK(status
)) {
6641 tevent_loop_once(evt
);
6644 torture_close_connection(cli1
);
6648 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6651 status
= cli_session_setup_guest_recv(req
);
6652 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6655 static void chain2_tcon_completion(struct tevent_req
*req
)
6657 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6659 status
= cli_tcon_andx_recv(req
);
6660 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6664 static bool run_chain2(int dummy
)
6666 struct cli_state
*cli1
;
6667 struct tevent_context
*evt
= samba_tevent_context_init(NULL
);
6668 struct tevent_req
*reqs
[2], *smbreqs
[2];
6672 printf("starting chain2 test\n");
6673 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6674 port_to_use
, SMB_SIGNING_DEFAULT
, 0);
6675 if (!NT_STATUS_IS_OK(status
)) {
6679 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6681 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6683 if (reqs
[0] == NULL
) return false;
6684 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6686 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6687 "?????", NULL
, 0, &smbreqs
[1]);
6688 if (reqs
[1] == NULL
) return false;
6689 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6691 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
6692 if (!NT_STATUS_IS_OK(status
)) {
6697 tevent_loop_once(evt
);
6700 torture_close_connection(cli1
);
6705 struct torture_createdel_state
{
6706 struct tevent_context
*ev
;
6707 struct cli_state
*cli
;
6710 static void torture_createdel_created(struct tevent_req
*subreq
);
6711 static void torture_createdel_closed(struct tevent_req
*subreq
);
6713 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6714 struct tevent_context
*ev
,
6715 struct cli_state
*cli
,
6718 struct tevent_req
*req
, *subreq
;
6719 struct torture_createdel_state
*state
;
6721 req
= tevent_req_create(mem_ctx
, &state
,
6722 struct torture_createdel_state
);
6729 subreq
= cli_ntcreate_send(
6730 state
, ev
, cli
, name
, 0,
6731 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6732 FILE_ATTRIBUTE_NORMAL
,
6733 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6734 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6736 if (tevent_req_nomem(subreq
, req
)) {
6737 return tevent_req_post(req
, ev
);
6739 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6743 static void torture_createdel_created(struct tevent_req
*subreq
)
6745 struct tevent_req
*req
= tevent_req_callback_data(
6746 subreq
, struct tevent_req
);
6747 struct torture_createdel_state
*state
= tevent_req_data(
6748 req
, struct torture_createdel_state
);
6752 status
= cli_ntcreate_recv(subreq
, &fnum
, NULL
);
6753 TALLOC_FREE(subreq
);
6754 if (tevent_req_nterror(req
, status
)) {
6755 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6756 nt_errstr(status
)));
6760 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6761 if (tevent_req_nomem(subreq
, req
)) {
6764 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6767 static void torture_createdel_closed(struct tevent_req
*subreq
)
6769 struct tevent_req
*req
= tevent_req_callback_data(
6770 subreq
, struct tevent_req
);
6773 status
= cli_close_recv(subreq
);
6774 if (tevent_req_nterror(req
, status
)) {
6775 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6778 tevent_req_done(req
);
6781 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6783 return tevent_req_simple_recv_ntstatus(req
);
6786 struct torture_createdels_state
{
6787 struct tevent_context
*ev
;
6788 struct cli_state
*cli
;
6789 const char *base_name
;
6793 struct tevent_req
**reqs
;
6796 static void torture_createdels_done(struct tevent_req
*subreq
);
6798 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6799 struct tevent_context
*ev
,
6800 struct cli_state
*cli
,
6801 const char *base_name
,
6805 struct tevent_req
*req
;
6806 struct torture_createdels_state
*state
;
6809 req
= tevent_req_create(mem_ctx
, &state
,
6810 struct torture_createdels_state
);
6816 state
->base_name
= talloc_strdup(state
, base_name
);
6817 if (tevent_req_nomem(state
->base_name
, req
)) {
6818 return tevent_req_post(req
, ev
);
6820 state
->num_files
= MAX(num_parallel
, num_files
);
6822 state
->received
= 0;
6824 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6825 if (tevent_req_nomem(state
->reqs
, req
)) {
6826 return tevent_req_post(req
, ev
);
6829 for (i
=0; i
<num_parallel
; i
++) {
6832 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6834 if (tevent_req_nomem(name
, req
)) {
6835 return tevent_req_post(req
, ev
);
6837 state
->reqs
[i
] = torture_createdel_send(
6838 state
->reqs
, state
->ev
, state
->cli
, name
);
6839 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6840 return tevent_req_post(req
, ev
);
6842 name
= talloc_move(state
->reqs
[i
], &name
);
6843 tevent_req_set_callback(state
->reqs
[i
],
6844 torture_createdels_done
, req
);
6850 static void torture_createdels_done(struct tevent_req
*subreq
)
6852 struct tevent_req
*req
= tevent_req_callback_data(
6853 subreq
, struct tevent_req
);
6854 struct torture_createdels_state
*state
= tevent_req_data(
6855 req
, struct torture_createdels_state
);
6856 size_t num_parallel
= talloc_array_length(state
->reqs
);
6861 status
= torture_createdel_recv(subreq
);
6862 if (!NT_STATUS_IS_OK(status
)){
6863 DEBUG(10, ("torture_createdel_recv returned %s\n",
6864 nt_errstr(status
)));
6865 TALLOC_FREE(subreq
);
6866 tevent_req_nterror(req
, status
);
6870 for (i
=0; i
<num_parallel
; i
++) {
6871 if (subreq
== state
->reqs
[i
]) {
6875 if (i
== num_parallel
) {
6876 DEBUG(10, ("received something we did not send\n"));
6877 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6880 TALLOC_FREE(state
->reqs
[i
]);
6882 if (state
->sent
>= state
->num_files
) {
6883 tevent_req_done(req
);
6887 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6889 if (tevent_req_nomem(name
, req
)) {
6892 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6894 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6897 name
= talloc_move(state
->reqs
[i
], &name
);
6898 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6902 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6904 return tevent_req_simple_recv_ntstatus(req
);
6907 struct swallow_notify_state
{
6908 struct tevent_context
*ev
;
6909 struct cli_state
*cli
;
6911 uint32_t completion_filter
;
6913 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6917 static void swallow_notify_done(struct tevent_req
*subreq
);
6919 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6920 struct tevent_context
*ev
,
6921 struct cli_state
*cli
,
6923 uint32_t completion_filter
,
6925 bool (*fn
)(uint32_t action
,
6930 struct tevent_req
*req
, *subreq
;
6931 struct swallow_notify_state
*state
;
6933 req
= tevent_req_create(mem_ctx
, &state
,
6934 struct swallow_notify_state
);
6941 state
->completion_filter
= completion_filter
;
6942 state
->recursive
= recursive
;
6946 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6947 0xffff, state
->completion_filter
,
6949 if (tevent_req_nomem(subreq
, req
)) {
6950 return tevent_req_post(req
, ev
);
6952 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6956 static void swallow_notify_done(struct tevent_req
*subreq
)
6958 struct tevent_req
*req
= tevent_req_callback_data(
6959 subreq
, struct tevent_req
);
6960 struct swallow_notify_state
*state
= tevent_req_data(
6961 req
, struct swallow_notify_state
);
6963 uint32_t i
, num_changes
;
6964 struct notify_change
*changes
;
6966 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6967 TALLOC_FREE(subreq
);
6968 if (!NT_STATUS_IS_OK(status
)) {
6969 DEBUG(10, ("cli_notify_recv returned %s\n",
6970 nt_errstr(status
)));
6971 tevent_req_nterror(req
, status
);
6975 for (i
=0; i
<num_changes
; i
++) {
6976 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6978 TALLOC_FREE(changes
);
6980 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6981 0xffff, state
->completion_filter
,
6983 if (tevent_req_nomem(subreq
, req
)) {
6986 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6989 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6991 if (DEBUGLEVEL
> 5) {
6992 d_printf("%d %s\n", (int)action
, name
);
6997 static void notify_bench_done(struct tevent_req
*req
)
6999 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
7003 static bool run_notify_bench(int dummy
)
7005 const char *dname
= "\\notify-bench";
7006 struct tevent_context
*ev
;
7009 struct tevent_req
*req1
;
7010 struct tevent_req
*req2
= NULL
;
7011 int i
, num_unc_names
;
7012 int num_finished
= 0;
7014 printf("starting notify-bench test\n");
7016 if (use_multishare_conn
) {
7018 unc_list
= file_lines_load(multishare_conn_fname
,
7019 &num_unc_names
, 0, NULL
);
7020 if (!unc_list
|| num_unc_names
<= 0) {
7021 d_printf("Failed to load unc names list from '%s'\n",
7022 multishare_conn_fname
);
7025 TALLOC_FREE(unc_list
);
7030 ev
= samba_tevent_context_init(talloc_tos());
7032 d_printf("tevent_context_init failed\n");
7036 for (i
=0; i
<num_unc_names
; i
++) {
7037 struct cli_state
*cli
;
7040 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
7042 if (base_fname
== NULL
) {
7046 if (!torture_open_connection(&cli
, i
)) {
7050 status
= cli_ntcreate(cli
, dname
, 0,
7051 MAXIMUM_ALLOWED_ACCESS
,
7052 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
7054 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
7057 if (!NT_STATUS_IS_OK(status
)) {
7058 d_printf("Could not create %s: %s\n", dname
,
7063 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
7064 FILE_NOTIFY_CHANGE_FILE_NAME
|
7065 FILE_NOTIFY_CHANGE_DIR_NAME
|
7066 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
7067 FILE_NOTIFY_CHANGE_LAST_WRITE
,
7068 false, print_notifies
, NULL
);
7070 d_printf("Could not create notify request\n");
7074 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
7075 base_fname
, 10, torture_numops
);
7077 d_printf("Could not create createdels request\n");
7080 TALLOC_FREE(base_fname
);
7082 tevent_req_set_callback(req2
, notify_bench_done
,
7086 while (num_finished
< num_unc_names
) {
7088 ret
= tevent_loop_once(ev
);
7090 d_printf("tevent_loop_once failed\n");
7095 if (!tevent_req_poll(req2
, ev
)) {
7096 d_printf("tevent_req_poll failed\n");
7099 status
= torture_createdels_recv(req2
);
7100 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7105 static bool run_mangle1(int dummy
)
7107 struct cli_state
*cli
;
7108 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7112 time_t change_time
, access_time
, write_time
;
7116 printf("starting mangle1 test\n");
7117 if (!torture_open_connection(&cli
, 0)) {
7121 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7123 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7124 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7126 if (!NT_STATUS_IS_OK(status
)) {
7127 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7130 cli_close(cli
, fnum
);
7132 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7133 if (!NT_STATUS_IS_OK(status
)) {
7134 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7138 d_printf("alt_name: %s\n", alt_name
);
7140 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7141 if (!NT_STATUS_IS_OK(status
)) {
7142 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
7146 cli_close(cli
, fnum
);
7148 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7149 &write_time
, &size
, &mode
);
7150 if (!NT_STATUS_IS_OK(status
)) {
7151 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7159 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7161 size_t *to_pull
= (size_t *)priv
;
7162 size_t thistime
= *to_pull
;
7164 thistime
= MIN(thistime
, n
);
7165 if (thistime
== 0) {
7169 memset(buf
, 0, thistime
);
7170 *to_pull
-= thistime
;
7174 static bool run_windows_write(int dummy
)
7176 struct cli_state
*cli1
;
7180 const char *fname
= "\\writetest.txt";
7181 struct timeval start_time
;
7186 printf("starting windows_write test\n");
7187 if (!torture_open_connection(&cli1
, 0)) {
7191 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7192 if (!NT_STATUS_IS_OK(status
)) {
7193 printf("open failed (%s)\n", nt_errstr(status
));
7197 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7199 start_time
= timeval_current();
7201 for (i
=0; i
<torture_numops
; i
++) {
7203 off_t start
= i
* torture_blocksize
;
7204 size_t to_pull
= torture_blocksize
- 1;
7206 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7207 start
+ torture_blocksize
- 1, 1, NULL
);
7208 if (!NT_STATUS_IS_OK(status
)) {
7209 printf("cli_write failed: %s\n", nt_errstr(status
));
7213 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7214 null_source
, &to_pull
);
7215 if (!NT_STATUS_IS_OK(status
)) {
7216 printf("cli_push returned: %s\n", nt_errstr(status
));
7221 seconds
= timeval_elapsed(&start_time
);
7222 kbytes
= (double)torture_blocksize
* torture_numops
;
7225 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7226 (double)seconds
, (int)(kbytes
/seconds
));
7230 cli_close(cli1
, fnum
);
7231 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7232 torture_close_connection(cli1
);
7236 static size_t calc_expected_return(struct cli_state
*cli
, size_t len_requested
)
7238 size_t max_pdu
= 0x1FFFF;
7240 if (cli
->server_posix_capabilities
& CIFS_UNIX_LARGE_READ_CAP
) {
7244 if (smb1cli_conn_signing_is_active(cli
->conn
)) {
7248 if (smb1cli_conn_encryption_on(cli
->conn
)) {
7249 max_pdu
= CLI_BUFFER_SIZE
;
7252 if ((len_requested
& 0xFFFF0000) == 0xFFFF0000) {
7253 len_requested
&= 0xFFFF;
7256 return MIN(len_requested
,
7257 max_pdu
- (MIN_SMB_SIZE
+ VWV(12) + 1 /* padding byte */));
7260 static bool check_read_call(struct cli_state
*cli
,
7263 size_t len_requested
)
7266 struct tevent_req
*subreq
= NULL
;
7267 ssize_t len_read
= 0;
7268 size_t len_expected
= 0;
7269 struct tevent_context
*ev
= NULL
;
7271 ev
= samba_tevent_context_init(talloc_tos());
7276 subreq
= cli_read_andx_send(talloc_tos(),
7283 if (!tevent_req_poll_ntstatus(subreq
, ev
, &status
)) {
7287 status
= cli_read_andx_recv(subreq
, &len_read
, &buf
);
7288 if (!NT_STATUS_IS_OK(status
)) {
7289 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status
));
7293 TALLOC_FREE(subreq
);
7296 len_expected
= calc_expected_return(cli
, len_requested
);
7298 if (len_expected
> 0x10000 && len_read
== 0x10000) {
7299 /* Windows servers only return a max of 0x10000,
7300 doesn't matter if you set CAP_LARGE_READX in
7301 the client sessionsetupX call or not. */
7302 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
7303 (unsigned int)len_requested
);
7304 } else if (len_read
!= len_expected
) {
7305 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
7306 (unsigned int)len_requested
,
7307 (unsigned int)len_read
,
7308 (unsigned int)len_expected
);
7311 d_printf("Correct read reply.\n");
7317 /* Test large readX variants. */
7318 static bool large_readx_tests(struct cli_state
*cli
,
7322 /* A read of 0xFFFF0001 should *always* return 1 byte. */
7323 if (check_read_call(cli
, fnum
, buf
, 0xFFFF0001) == false) {
7326 /* A read of 0x10000 should return 0x10000 bytes. */
7327 if (check_read_call(cli
, fnum
, buf
, 0x10000) == false) {
7330 /* A read of 0x10000 should return 0x10001 bytes. */
7331 if (check_read_call(cli
, fnum
, buf
, 0x10001) == false) {
7334 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
7335 the requested number of bytes. */
7336 if (check_read_call(cli
, fnum
, buf
, 0x1FFFF - (MIN_SMB_SIZE
+ VWV(12))) == false) {
7339 /* A read of 1MB should return 1MB bytes (on Samba). */
7340 if (check_read_call(cli
, fnum
, buf
, 0x100000) == false) {
7344 if (check_read_call(cli
, fnum
, buf
, 0x20001) == false) {
7347 if (check_read_call(cli
, fnum
, buf
, 0x22000001) == false) {
7350 if (check_read_call(cli
, fnum
, buf
, 0xFFFE0001) == false) {
7356 static bool run_large_readx(int dummy
)
7358 uint8_t *buf
= NULL
;
7359 struct cli_state
*cli1
= NULL
;
7360 struct cli_state
*cli2
= NULL
;
7361 bool correct
= false;
7362 const char *fname
= "\\large_readx.dat";
7364 uint16_t fnum1
= UINT16_MAX
;
7365 uint32_t normal_caps
= 0;
7366 size_t file_size
= 20*1024*1024;
7367 TALLOC_CTX
*frame
= talloc_stackframe();
7371 enum smb_signing_setting signing_setting
;
7372 enum protocol_types protocol
;
7376 .signing_setting
= SMB_SIGNING_IF_REQUIRED
,
7377 .protocol
= PROTOCOL_NT1
,
7379 .name
= "NT1 - SIGNING_REQUIRED",
7380 .signing_setting
= SMB_SIGNING_REQUIRED
,
7381 .protocol
= PROTOCOL_NT1
,
7385 printf("starting large_readx test\n");
7387 if (!torture_open_connection(&cli1
, 0)) {
7391 normal_caps
= smb1cli_conn_capabilities(cli1
->conn
);
7393 if (!(normal_caps
& CAP_LARGE_READX
)) {
7394 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
7395 (unsigned int)normal_caps
);
7399 /* Create a file of size 4MB. */
7400 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
7401 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7402 0, 0, &fnum1
, NULL
);
7404 if (!NT_STATUS_IS_OK(status
)) {
7405 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7409 /* Write file_size bytes. */
7410 buf
= talloc_zero_array(frame
, uint8_t, file_size
);
7415 status
= cli_writeall(cli1
,
7422 if (!NT_STATUS_IS_OK(status
)) {
7423 d_printf("cli_writeall failed: %s\n", nt_errstr(status
));
7427 status
= cli_close(cli1
, fnum1
);
7428 if (!NT_STATUS_IS_OK(status
)) {
7429 d_printf("cli_close failed: %s\n", nt_errstr(status
));
7435 for (i
=0; i
< ARRAY_SIZE(runs
); i
++) {
7436 enum smb_signing_setting saved_signing_setting
= signing_state
;
7437 uint16_t fnum2
= -1;
7440 (runs
[i
].signing_setting
== SMB_SIGNING_REQUIRED
))
7442 d_printf("skip[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
7446 d_printf("run[%u] - %s\n", (unsigned)i
, runs
[i
].name
);
7448 signing_state
= runs
[i
].signing_setting
;
7449 cli2
= open_nbt_connection();
7450 signing_state
= saved_signing_setting
;
7455 status
= smbXcli_negprot(cli2
->conn
,
7459 if (!NT_STATUS_IS_OK(status
)) {
7463 status
= cli_session_setup(cli2
,
7470 if (!NT_STATUS_IS_OK(status
)) {
7474 status
= cli_tree_connect(cli2
,
7478 strlen(password
)+1);
7479 if (!NT_STATUS_IS_OK(status
)) {
7483 cli_set_timeout(cli2
, 120000); /* set a really long timeout (2 minutes) */
7485 normal_caps
= smb1cli_conn_capabilities(cli2
->conn
);
7487 if (!(normal_caps
& CAP_LARGE_READX
)) {
7488 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
7489 (unsigned int)normal_caps
);
7494 if (force_cli_encryption(cli2
, share
) == false) {
7497 } else if (SERVER_HAS_UNIX_CIFS(cli2
)) {
7498 uint16_t major
, minor
;
7499 uint32_t caplow
, caphigh
;
7501 status
= cli_unix_extensions_version(cli2
,
7504 if (!NT_STATUS_IS_OK(status
)) {
7509 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
,
7510 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
7511 0, 0, &fnum2
, NULL
);
7512 if (!NT_STATUS_IS_OK(status
)) {
7513 d_printf("Second open %s failed: %s\n", fname
, nt_errstr(status
));
7517 /* All reads must return less than file_size bytes. */
7518 if (!large_readx_tests(cli2
, fnum2
, buf
)) {
7522 status
= cli_close(cli2
, fnum2
);
7523 if (!NT_STATUS_IS_OK(status
)) {
7524 d_printf("cli_close failed: %s\n", nt_errstr(status
));
7529 if (!torture_close_connection(cli2
)) {
7536 printf("Success on large_readx test\n");
7541 if (!torture_close_connection(cli2
)) {
7547 if (fnum1
!= UINT16_MAX
) {
7548 status
= cli_close(cli1
, fnum1
);
7549 if (!NT_STATUS_IS_OK(status
)) {
7550 d_printf("cli_close failed: %s\n", nt_errstr(status
));
7555 status
= cli_unlink(cli1
, fname
,
7556 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7557 if (!NT_STATUS_IS_OK(status
)) {
7558 printf("unlink failed (%s)\n", nt_errstr(status
));
7561 if (!torture_close_connection(cli1
)) {
7568 printf("finished large_readx test\n");
7572 static bool run_cli_echo(int dummy
)
7574 struct cli_state
*cli
;
7577 printf("starting cli_echo test\n");
7578 if (!torture_open_connection(&cli
, 0)) {
7581 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7583 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7585 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7587 torture_close_connection(cli
);
7588 return NT_STATUS_IS_OK(status
);
7591 static bool run_uid_regression_test(int dummy
)
7593 static struct cli_state
*cli
;
7596 bool correct
= True
;
7599 printf("starting uid regression test\n");
7601 if (!torture_open_connection(&cli
, 0)) {
7605 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7607 /* Ok - now save then logoff our current user. */
7608 old_vuid
= cli_state_get_uid(cli
);
7610 status
= cli_ulogoff(cli
);
7611 if (!NT_STATUS_IS_OK(status
)) {
7612 d_printf("(%s) cli_ulogoff failed: %s\n",
7613 __location__
, nt_errstr(status
));
7618 cli_state_set_uid(cli
, old_vuid
);
7620 /* Try an operation. */
7621 status
= cli_mkdir(cli
, "\\uid_reg_test");
7622 if (NT_STATUS_IS_OK(status
)) {
7623 d_printf("(%s) cli_mkdir succeeded\n",
7628 /* Should be bad uid. */
7629 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
7630 NT_STATUS_USER_SESSION_DELETED
)) {
7636 old_cnum
= cli_state_get_tid(cli
);
7638 /* Now try a SMBtdis with the invald vuid set to zero. */
7639 cli_state_set_uid(cli
, 0);
7641 /* This should succeed. */
7642 status
= cli_tdis(cli
);
7644 if (NT_STATUS_IS_OK(status
)) {
7645 d_printf("First tdis with invalid vuid should succeed.\n");
7647 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7652 cli_state_set_uid(cli
, old_vuid
);
7653 cli_state_set_tid(cli
, old_cnum
);
7655 /* This should fail. */
7656 status
= cli_tdis(cli
);
7657 if (NT_STATUS_IS_OK(status
)) {
7658 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7662 /* Should be bad tid. */
7663 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
7664 NT_STATUS_NETWORK_NAME_DELETED
)) {
7670 cli_rmdir(cli
, "\\uid_reg_test");
7679 static const char *illegal_chars
= "*\\/?<>|\":";
7680 static char force_shortname_chars
[] = " +,.[];=\177";
7682 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7683 const char *mask
, void *state
)
7685 struct cli_state
*pcli
= (struct cli_state
*)state
;
7687 NTSTATUS status
= NT_STATUS_OK
;
7689 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7691 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7692 return NT_STATUS_OK
;
7694 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7695 status
= cli_rmdir(pcli
, fname
);
7696 if (!NT_STATUS_IS_OK(status
)) {
7697 printf("del_fn: failed to rmdir %s\n,", fname
);
7700 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7701 if (!NT_STATUS_IS_OK(status
)) {
7702 printf("del_fn: failed to unlink %s\n,", fname
);
7714 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7715 const char *name
, void *state
)
7717 struct sn_state
*s
= (struct sn_state
*)state
;
7721 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7722 i
, finfo
->name
, finfo
->short_name
);
7725 if (strchr(force_shortname_chars
, i
)) {
7726 if (!finfo
->short_name
) {
7727 /* Shortname not created when it should be. */
7728 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7729 __location__
, finfo
->name
, i
);
7732 } else if (finfo
->short_name
){
7733 /* Shortname created when it should not be. */
7734 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7735 __location__
, finfo
->short_name
, finfo
->name
);
7739 return NT_STATUS_OK
;
7742 static bool run_shortname_test(int dummy
)
7744 static struct cli_state
*cli
;
7745 bool correct
= True
;
7751 printf("starting shortname test\n");
7753 if (!torture_open_connection(&cli
, 0)) {
7757 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7759 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7760 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7761 cli_rmdir(cli
, "\\shortname");
7763 status
= cli_mkdir(cli
, "\\shortname");
7764 if (!NT_STATUS_IS_OK(status
)) {
7765 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7766 __location__
, nt_errstr(status
));
7771 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
7775 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
7782 for (i
= 32; i
< 128; i
++) {
7783 uint16_t fnum
= (uint16_t)-1;
7787 if (strchr(illegal_chars
, i
)) {
7792 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7793 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
7794 FILE_OVERWRITE_IF
, 0, 0, &fnum
, NULL
);
7795 if (!NT_STATUS_IS_OK(status
)) {
7796 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7797 __location__
, fname
, nt_errstr(status
));
7801 cli_close(cli
, fnum
);
7804 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7805 shortname_list_fn
, &s
);
7806 if (s
.matched
!= 1) {
7807 d_printf("(%s) failed to list %s: %s\n",
7808 __location__
, fname
, nt_errstr(status
));
7813 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7814 if (!NT_STATUS_IS_OK(status
)) {
7815 d_printf("(%s) failed to delete %s: %s\n",
7816 __location__
, fname
, nt_errstr(status
));
7829 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7830 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7831 cli_rmdir(cli
, "\\shortname");
7832 torture_close_connection(cli
);
7836 static void pagedsearch_cb(struct tevent_req
*req
)
7839 struct tldap_message
*msg
;
7842 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7843 if (rc
!= TLDAP_SUCCESS
) {
7844 d_printf("tldap_search_paged_recv failed: %s\n",
7845 tldap_err2string(rc
));
7848 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7852 if (!tldap_entry_dn(msg
, &dn
)) {
7853 d_printf("tldap_entry_dn failed\n");
7856 d_printf("%s\n", dn
);
7860 static bool run_tldap(int dummy
)
7862 struct tldap_context
*ld
;
7865 struct sockaddr_storage addr
;
7866 struct tevent_context
*ev
;
7867 struct tevent_req
*req
;
7871 if (!resolve_name(host
, &addr
, 0, false)) {
7872 d_printf("could not find host %s\n", host
);
7875 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7876 if (!NT_STATUS_IS_OK(status
)) {
7877 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7881 ld
= tldap_context_create(talloc_tos(), fd
);
7884 d_printf("tldap_context_create failed\n");
7888 rc
= tldap_fetch_rootdse(ld
);
7889 if (rc
!= TLDAP_SUCCESS
) {
7890 d_printf("tldap_fetch_rootdse failed: %s\n",
7891 tldap_errstr(talloc_tos(), ld
, rc
));
7895 basedn
= tldap_talloc_single_attribute(
7896 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7897 if (basedn
== NULL
) {
7898 d_printf("no defaultNamingContext\n");
7901 d_printf("defaultNamingContext: %s\n", basedn
);
7903 ev
= samba_tevent_context_init(talloc_tos());
7905 d_printf("tevent_context_init failed\n");
7909 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7910 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7912 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7914 d_printf("tldap_search_paged_send failed\n");
7917 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7919 tevent_req_poll(req
, ev
);
7923 /* test search filters against rootDSE */
7924 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7925 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7927 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7928 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7929 talloc_tos(), NULL
, NULL
);
7930 if (rc
!= TLDAP_SUCCESS
) {
7931 d_printf("tldap_search with complex filter failed: %s\n",
7932 tldap_errstr(talloc_tos(), ld
, rc
));
7940 /* Torture test to ensure no regression of :
7941 https://bugzilla.samba.org/show_bug.cgi?id=7084
7944 static bool run_dir_createtime(int dummy
)
7946 struct cli_state
*cli
;
7947 const char *dname
= "\\testdir";
7948 const char *fname
= "\\testdir\\testfile";
7950 struct timespec create_time
;
7951 struct timespec create_time1
;
7955 if (!torture_open_connection(&cli
, 0)) {
7959 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7960 cli_rmdir(cli
, dname
);
7962 status
= cli_mkdir(cli
, dname
);
7963 if (!NT_STATUS_IS_OK(status
)) {
7964 printf("mkdir failed: %s\n", nt_errstr(status
));
7968 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7970 if (!NT_STATUS_IS_OK(status
)) {
7971 printf("cli_qpathinfo2 returned %s\n",
7976 /* Sleep 3 seconds, then create a file. */
7979 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7981 if (!NT_STATUS_IS_OK(status
)) {
7982 printf("cli_openx failed: %s\n", nt_errstr(status
));
7986 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7988 if (!NT_STATUS_IS_OK(status
)) {
7989 printf("cli_qpathinfo2 (2) returned %s\n",
7994 if (timespec_compare(&create_time1
, &create_time
)) {
7995 printf("run_dir_createtime: create time was updated (error)\n");
7997 printf("run_dir_createtime: create time was not updated (correct)\n");
8003 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8004 cli_rmdir(cli
, dname
);
8005 if (!torture_close_connection(cli
)) {
8012 static bool run_streamerror(int dummy
)
8014 struct cli_state
*cli
;
8015 const char *dname
= "\\testdir";
8016 const char *streamname
=
8017 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
8019 time_t change_time
, access_time
, write_time
;
8021 uint16_t mode
, fnum
;
8024 if (!torture_open_connection(&cli
, 0)) {
8028 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
8029 cli_rmdir(cli
, dname
);
8031 status
= cli_mkdir(cli
, dname
);
8032 if (!NT_STATUS_IS_OK(status
)) {
8033 printf("mkdir failed: %s\n", nt_errstr(status
));
8037 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
8038 &write_time
, &size
, &mode
);
8039 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
8040 printf("pathinfo returned %s, expected "
8041 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8046 status
= cli_ntcreate(cli
, streamname
, 0x16,
8047 FILE_READ_DATA
|FILE_READ_EA
|
8048 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
8049 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
8050 FILE_OPEN
, 0, 0, &fnum
, NULL
);
8052 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
8053 printf("ntcreate returned %s, expected "
8054 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8060 cli_rmdir(cli
, dname
);
8064 static bool run_local_substitute(int dummy
)
8068 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
8069 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
8070 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
8071 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
8072 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
8073 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
8074 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
8075 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
8077 /* Different captialization rules in sub_basic... */
8079 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
8085 static bool run_local_base64(int dummy
)
8090 for (i
=1; i
<2000; i
++) {
8091 DATA_BLOB blob1
, blob2
;
8094 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
8096 generate_random_buffer(blob1
.data
, blob1
.length
);
8098 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
8100 d_fprintf(stderr
, "base64_encode_data_blob failed "
8101 "for %d bytes\n", i
);
8104 blob2
= base64_decode_data_blob(b64
);
8107 if (data_blob_cmp(&blob1
, &blob2
)) {
8108 d_fprintf(stderr
, "data_blob_cmp failed for %d "
8112 TALLOC_FREE(blob1
.data
);
8113 data_blob_free(&blob2
);
8118 static void parse_fn(time_t timeout
, DATA_BLOB blob
, void *private_data
)
8123 static bool run_local_gencache(int dummy
)
8129 struct memcache
*mem
;
8132 mem
= memcache_init(NULL
, 0);
8134 d_printf("%s: memcache_init failed\n", __location__
);
8137 memcache_set_global(mem
);
8139 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
8140 d_printf("%s: gencache_set() failed\n", __location__
);
8144 if (!gencache_get("foo", NULL
, NULL
, NULL
)) {
8145 d_printf("%s: gencache_get() failed\n", __location__
);
8149 for (i
=0; i
<1000000; i
++) {
8150 gencache_parse("foo", parse_fn
, NULL
);
8153 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
8154 d_printf("%s: gencache_get() failed\n", __location__
);
8159 if (!gencache_get("foo", talloc_tos(), &val
, &tm
)) {
8160 d_printf("%s: gencache_get() failed\n", __location__
);
8164 if (strcmp(val
, "bar") != 0) {
8165 d_printf("%s: gencache_get() returned %s, expected %s\n",
8166 __location__
, val
, "bar");
8173 if (!gencache_del("foo")) {
8174 d_printf("%s: gencache_del() failed\n", __location__
);
8177 if (gencache_del("foo")) {
8178 d_printf("%s: second gencache_del() succeeded\n",
8183 if (gencache_get("foo", talloc_tos(), &val
, &tm
)) {
8184 d_printf("%s: gencache_get() on deleted entry "
8185 "succeeded\n", __location__
);
8189 blob
= data_blob_string_const_null("bar");
8190 tm
= time(NULL
) + 60;
8192 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
8193 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
8197 if (!gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
8198 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
8202 if (strcmp((const char *)blob
.data
, "bar") != 0) {
8203 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
8204 __location__
, (const char *)blob
.data
, "bar");
8205 data_blob_free(&blob
);
8209 data_blob_free(&blob
);
8211 if (!gencache_del("foo")) {
8212 d_printf("%s: gencache_del() failed\n", __location__
);
8215 if (gencache_del("foo")) {
8216 d_printf("%s: second gencache_del() succeeded\n",
8221 if (gencache_get_data_blob("foo", talloc_tos(), &blob
, NULL
, NULL
)) {
8222 d_printf("%s: gencache_get_data_blob() on deleted entry "
8223 "succeeded\n", __location__
);
8228 blob
.data
= (uint8_t *)&v
;
8229 blob
.length
= sizeof(v
);
8231 if (!gencache_set_data_blob("blob", &blob
, tm
)) {
8232 d_printf("%s: gencache_set_data_blob() failed\n",
8236 if (gencache_get("blob", talloc_tos(), &val
, &tm
)) {
8237 d_printf("%s: gencache_get succeeded\n", __location__
);
8244 static bool rbt_testval(struct db_context
*db
, const char *key
,
8247 struct db_record
*rec
;
8248 TDB_DATA data
= string_tdb_data(value
);
8253 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
8255 d_fprintf(stderr
, "fetch_locked failed\n");
8258 status
= dbwrap_record_store(rec
, data
, 0);
8259 if (!NT_STATUS_IS_OK(status
)) {
8260 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
8265 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
8267 d_fprintf(stderr
, "second fetch_locked failed\n");
8271 dbvalue
= dbwrap_record_get_value(rec
);
8272 if ((dbvalue
.dsize
!= data
.dsize
)
8273 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
8274 d_fprintf(stderr
, "Got wrong data back\n");
8284 static bool run_local_rbtree(int dummy
)
8286 struct db_context
*db
;
8290 db
= db_open_rbt(NULL
);
8293 d_fprintf(stderr
, "db_open_rbt failed\n");
8297 for (i
=0; i
<1000; i
++) {
8300 if (asprintf(&key
, "key%ld", random()) == -1) {
8303 if (asprintf(&value
, "value%ld", random()) == -1) {
8308 if (!rbt_testval(db
, key
, value
)) {
8315 if (asprintf(&value
, "value%ld", random()) == -1) {
8320 if (!rbt_testval(db
, key
, value
)) {
8339 local test for character set functions
8341 This is a very simple test for the functionality in convert_string_error()
8343 static bool run_local_convert_string(int dummy
)
8345 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
8346 const char *test_strings
[2] = { "March", "M\303\244rz" };
8350 for (i
=0; i
<2; i
++) {
8351 const char *str
= test_strings
[i
];
8352 int len
= strlen(str
);
8353 size_t converted_size
;
8356 memset(dst
, 'X', sizeof(dst
));
8358 /* first try with real source length */
8359 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
8364 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
8368 if (converted_size
!= len
) {
8369 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
8370 str
, len
, (int)converted_size
);
8374 if (strncmp(str
, dst
, converted_size
) != 0) {
8375 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
8379 if (strlen(str
) != converted_size
) {
8380 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
8381 (int)strlen(str
), (int)converted_size
);
8385 if (dst
[converted_size
] != 'X') {
8386 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
8390 /* now with srclen==-1, this causes the nul to be
8392 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
8397 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
8401 if (converted_size
!= len
+1) {
8402 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
8403 str
, len
, (int)converted_size
);
8407 if (strncmp(str
, dst
, converted_size
) != 0) {
8408 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
8412 if (len
+1 != converted_size
) {
8413 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
8414 len
+1, (int)converted_size
);
8418 if (dst
[converted_size
] != 'X') {
8419 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
8426 TALLOC_FREE(tmp_ctx
);
8429 TALLOC_FREE(tmp_ctx
);
8434 struct talloc_dict_test
{
8438 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
8440 int *count
= (int *)priv
;
8445 static bool run_local_talloc_dict(int dummy
)
8447 struct talloc_dict
*dict
;
8448 struct talloc_dict_test
*t
;
8449 int key
, count
, res
;
8452 dict
= talloc_dict_init(talloc_tos());
8457 t
= talloc(talloc_tos(), struct talloc_dict_test
);
8464 ok
= talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), &t
);
8470 res
= talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
);
8488 static bool run_local_string_to_sid(int dummy
) {
8491 if (string_to_sid(&sid
, "S--1-5-32-545")) {
8492 printf("allowing S--1-5-32-545\n");
8495 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
8496 printf("allowing S-1-5-32-+545\n");
8499 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")) {
8500 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8503 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
8504 printf("allowing S-1-5-32-545-abc\n");
8507 if (string_to_sid(&sid
, "S-300-5-32-545")) {
8508 printf("allowing S-300-5-32-545\n");
8511 if (string_to_sid(&sid
, "S-1-0xfffffffffffffe-32-545")) {
8512 printf("allowing S-1-0xfffffffffffffe-32-545\n");
8515 if (string_to_sid(&sid
, "S-1-0xffffffffffff-5294967297-545")) {
8516 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
8519 if (!string_to_sid(&sid
, "S-1-0xfffffffffffe-32-545")) {
8520 printf("could not parse S-1-0xfffffffffffe-32-545\n");
8523 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
8524 printf("could not parse S-1-5-32-545\n");
8527 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
8528 printf("mis-parsed S-1-5-32-545 as %s\n",
8529 sid_string_tos(&sid
));
8535 static bool sid_to_string_test(const char *expected
) {
8540 if (!string_to_sid(&sid
, expected
)) {
8541 printf("could not parse %s\n", expected
);
8545 str
= dom_sid_string(NULL
, &sid
);
8546 if (strcmp(str
, expected
)) {
8547 printf("Comparison failed (%s != %s)\n", str
, expected
);
8554 static bool run_local_sid_to_string(int dummy
) {
8555 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
8557 if (!sid_to_string_test("S-1-545"))
8559 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
8564 static bool run_local_binary_to_sid(int dummy
) {
8565 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
8566 static const uint8_t good_binary_sid
[] = {
8567 0x1, /* revision number */
8569 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8570 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8571 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8572 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8573 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8574 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8575 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8576 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8577 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8578 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8579 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8580 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8581 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8582 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8583 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8584 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8587 static const uint8_t long_binary_sid
[] = {
8588 0x1, /* revision number */
8590 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8591 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8592 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8593 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8594 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8595 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8596 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8597 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8598 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8599 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8600 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8601 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8602 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8603 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8604 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8605 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8606 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8607 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8608 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8611 static const uint8_t long_binary_sid2
[] = {
8612 0x1, /* revision number */
8614 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8615 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8616 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8617 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8618 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8619 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8620 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8621 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8622 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8623 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8624 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8625 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8626 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8627 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8628 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8629 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8630 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8631 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8632 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8633 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8634 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8635 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8636 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8637 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8638 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8639 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8640 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8641 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8642 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8643 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8644 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8645 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8646 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8649 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8652 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8655 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8661 /* Split a path name into filename and stream name components. Canonicalise
8662 * such that an implicit $DATA token is always explicit.
8664 * The "specification" of this function can be found in the
8665 * run_local_stream_name() function in torture.c, I've tried those
8666 * combinations against a W2k3 server.
8669 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8670 char **pbase
, char **pstream
)
8673 char *stream
= NULL
;
8674 char *sname
; /* stream name */
8675 const char *stype
; /* stream type */
8677 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8679 sname
= strchr_m(fname
, ':');
8681 if (lp_posix_pathnames() || (sname
== NULL
)) {
8682 if (pbase
!= NULL
) {
8683 base
= talloc_strdup(mem_ctx
, fname
);
8684 NT_STATUS_HAVE_NO_MEMORY(base
);
8689 if (pbase
!= NULL
) {
8690 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8691 NT_STATUS_HAVE_NO_MEMORY(base
);
8696 stype
= strchr_m(sname
, ':');
8698 if (stype
== NULL
) {
8699 sname
= talloc_strdup(mem_ctx
, sname
);
8703 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8705 * If there is an explicit stream type, so far we only
8706 * allow $DATA. Is there anything else allowed? -- vl
8708 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8710 return NT_STATUS_OBJECT_NAME_INVALID
;
8712 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8716 if (sname
== NULL
) {
8718 return NT_STATUS_NO_MEMORY
;
8721 if (sname
[0] == '\0') {
8723 * no stream name, so no stream
8728 if (pstream
!= NULL
) {
8729 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8730 if (stream
== NULL
) {
8733 return NT_STATUS_NO_MEMORY
;
8736 * upper-case the type field
8738 (void)strupper_m(strchr_m(stream
, ':')+1);
8742 if (pbase
!= NULL
) {
8745 if (pstream
!= NULL
) {
8748 return NT_STATUS_OK
;
8751 static bool test_stream_name(const char *fname
, const char *expected_base
,
8752 const char *expected_stream
,
8753 NTSTATUS expected_status
)
8757 char *stream
= NULL
;
8759 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8760 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8764 if (!NT_STATUS_IS_OK(status
)) {
8768 if (base
== NULL
) goto error
;
8770 if (strcmp(expected_base
, base
) != 0) goto error
;
8772 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8773 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8775 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8779 TALLOC_FREE(stream
);
8783 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8784 fname
, expected_base
? expected_base
: "<NULL>",
8785 expected_stream
? expected_stream
: "<NULL>",
8786 nt_errstr(expected_status
));
8787 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8788 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8791 TALLOC_FREE(stream
);
8795 static bool run_local_stream_name(int dummy
)
8799 ret
&= test_stream_name(
8800 "bla", "bla", NULL
, NT_STATUS_OK
);
8801 ret
&= test_stream_name(
8802 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8803 ret
&= test_stream_name(
8804 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8805 ret
&= test_stream_name(
8806 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8807 ret
&= test_stream_name(
8808 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8809 ret
&= test_stream_name(
8810 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8811 ret
&= test_stream_name(
8812 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8813 ret
&= test_stream_name(
8814 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8819 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8821 if (a
.length
!= b
.length
) {
8822 printf("a.length=%d != b.length=%d\n",
8823 (int)a
.length
, (int)b
.length
);
8826 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8827 printf("a.data and b.data differ\n");
8833 static bool run_local_memcache(int dummy
)
8835 struct memcache
*cache
;
8837 DATA_BLOB d1
, d2
, d3
;
8838 DATA_BLOB v1
, v2
, v3
;
8840 TALLOC_CTX
*mem_ctx
;
8842 size_t size1
, size2
;
8845 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
8847 if (cache
== NULL
) {
8848 printf("memcache_init failed\n");
8852 d1
= data_blob_const("d1", 2);
8853 d2
= data_blob_const("d2", 2);
8854 d3
= data_blob_const("d3", 2);
8856 k1
= data_blob_const("d1", 2);
8857 k2
= data_blob_const("d2", 2);
8859 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8860 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8862 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8863 printf("could not find k1\n");
8866 if (!data_blob_equal(d1
, v1
)) {
8870 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8871 printf("could not find k2\n");
8874 if (!data_blob_equal(d2
, v2
)) {
8878 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8880 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8881 printf("could not find replaced k1\n");
8884 if (!data_blob_equal(d3
, v3
)) {
8888 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8890 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8891 printf("Did find k2, should have been purged\n");
8897 cache
= memcache_init(NULL
, 0);
8899 mem_ctx
= talloc_init("foo");
8901 str1
= talloc_strdup(mem_ctx
, "string1");
8902 str2
= talloc_strdup(mem_ctx
, "string2");
8904 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8905 data_blob_string_const("torture"), &str1
);
8906 size1
= talloc_total_size(cache
);
8908 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8909 data_blob_string_const("torture"), &str2
);
8910 size2
= talloc_total_size(cache
);
8912 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8914 if (size2
> size1
) {
8915 printf("memcache leaks memory!\n");
8925 static void wbclient_done(struct tevent_req
*req
)
8928 struct winbindd_response
*wb_resp
;
8929 int *i
= (int *)tevent_req_callback_data_void(req
);
8931 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8934 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8937 static bool run_wbclient_multi_ping(int dummy
)
8939 struct tevent_context
*ev
;
8940 struct wb_context
**wb_ctx
;
8941 struct winbindd_request wb_req
;
8942 bool result
= false;
8945 BlockSignals(True
, SIGPIPE
);
8947 ev
= tevent_context_init(talloc_tos());
8952 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
8953 if (wb_ctx
== NULL
) {
8957 ZERO_STRUCT(wb_req
);
8958 wb_req
.cmd
= WINBINDD_PING
;
8960 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
8962 for (i
=0; i
<torture_nprocs
; i
++) {
8963 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8964 if (wb_ctx
[i
] == NULL
) {
8967 for (j
=0; j
<torture_numops
; j
++) {
8968 struct tevent_req
*req
;
8969 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8970 (j
% 2) == 0, &wb_req
);
8974 tevent_req_set_callback(req
, wbclient_done
, &i
);
8980 while (i
< torture_nprocs
* torture_numops
) {
8981 tevent_loop_once(ev
);
8990 static void getaddrinfo_finished(struct tevent_req
*req
)
8992 char *name
= (char *)tevent_req_callback_data_void(req
);
8993 struct addrinfo
*ainfo
;
8996 res
= getaddrinfo_recv(req
, &ainfo
);
8998 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
9001 d_printf("gai(%s) succeeded\n", name
);
9002 freeaddrinfo(ainfo
);
9005 static bool run_getaddrinfo_send(int dummy
)
9007 TALLOC_CTX
*frame
= talloc_stackframe();
9008 struct fncall_context
*ctx
;
9009 struct tevent_context
*ev
;
9010 bool result
= false;
9011 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
9012 "www.slashdot.org", "heise.de" };
9013 struct tevent_req
*reqs
[4];
9016 ev
= samba_tevent_context_init(frame
);
9021 ctx
= fncall_context_init(frame
, 4);
9023 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
9024 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
9026 if (reqs
[i
] == NULL
) {
9029 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
9030 discard_const_p(void, names
[i
]));
9033 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
9034 tevent_loop_once(ev
);
9043 static bool dbtrans_inc(struct db_context
*db
)
9045 struct db_record
*rec
;
9051 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
9053 printf(__location__
"fetch_lock failed\n");
9057 value
= dbwrap_record_get_value(rec
);
9059 if (value
.dsize
!= sizeof(uint32_t)) {
9060 printf(__location__
"value.dsize = %d\n",
9065 memcpy(&val
, value
.dptr
, sizeof(val
));
9068 status
= dbwrap_record_store(
9069 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
9070 if (!NT_STATUS_IS_OK(status
)) {
9071 printf(__location__
"store failed: %s\n",
9082 static bool run_local_dbtrans(int dummy
)
9084 struct db_context
*db
;
9085 struct db_record
*rec
;
9091 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
9092 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
,
9095 printf("Could not open transtest.db\n");
9099 res
= dbwrap_transaction_start(db
);
9101 printf(__location__
"transaction_start failed\n");
9105 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
9107 printf(__location__
"fetch_lock failed\n");
9111 value
= dbwrap_record_get_value(rec
);
9113 if (value
.dptr
== NULL
) {
9115 status
= dbwrap_record_store(
9116 rec
, make_tdb_data((uint8_t *)&initial
,
9119 if (!NT_STATUS_IS_OK(status
)) {
9120 printf(__location__
"store returned %s\n",
9128 res
= dbwrap_transaction_commit(db
);
9130 printf(__location__
"transaction_commit failed\n");
9138 res
= dbwrap_transaction_start(db
);
9140 printf(__location__
"transaction_start failed\n");
9144 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val
);
9145 if (!NT_STATUS_IS_OK(status
)) {
9146 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
9151 for (i
=0; i
<10; i
++) {
9152 if (!dbtrans_inc(db
)) {
9157 status
= dbwrap_fetch_uint32_bystring(db
, "transtest", &val2
);
9158 if (!NT_STATUS_IS_OK(status
)) {
9159 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
9164 if (val2
!= val
+ 10) {
9165 printf(__location__
"val=%d, val2=%d\n",
9166 (int)val
, (int)val2
);
9170 printf("val2=%d\r", val2
);
9172 res
= dbwrap_transaction_commit(db
);
9174 printf(__location__
"transaction_commit failed\n");
9184 * Just a dummy test to be run under a debugger. There's no real way
9185 * to inspect the tevent_select specific function from outside of
9189 static bool run_local_tevent_select(int dummy
)
9191 struct tevent_context
*ev
;
9192 struct tevent_fd
*fd1
, *fd2
;
9193 bool result
= false;
9195 ev
= tevent_context_init_byname(NULL
, "select");
9197 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
9201 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
9203 d_fprintf(stderr
, "tevent_add_fd failed\n");
9206 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
9208 d_fprintf(stderr
, "tevent_add_fd failed\n");
9213 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
9215 d_fprintf(stderr
, "tevent_add_fd failed\n");
9225 static bool run_local_hex_encode_buf(int dummy
)
9231 for (i
=0; i
<sizeof(src
); i
++) {
9234 hex_encode_buf(buf
, src
, sizeof(src
));
9235 if (strcmp(buf
, "0001020304050607") != 0) {
9238 hex_encode_buf(buf
, NULL
, 0);
9239 if (buf
[0] != '\0') {
9245 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
9267 "1001:1111:1111:1000:0:1111:1111:1111",
9276 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
9290 "1001:1111:1111:1000:0:1111:1111:1111"
9293 static bool run_local_remove_duplicate_addrs2(int dummy
)
9295 struct ip_service test_vector
[28];
9298 /* Construct the sockaddr_storage test vector. */
9299 for (i
= 0; i
< 28; i
++) {
9300 struct addrinfo hints
;
9301 struct addrinfo
*res
= NULL
;
9304 memset(&hints
, '\0', sizeof(hints
));
9305 hints
.ai_flags
= AI_NUMERICHOST
;
9306 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
9311 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
9312 remove_duplicate_addrs2_test_strings_vector
[i
]);
9315 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
9316 memcpy(&test_vector
[i
].ss
,
9322 count
= remove_duplicate_addrs2(test_vector
, i
);
9325 fprintf(stderr
, "count wrong (%d) should be 14\n",
9330 for (i
= 0; i
< count
; i
++) {
9331 char addr
[INET6_ADDRSTRLEN
];
9333 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
9335 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
9336 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
9339 remove_duplicate_addrs2_test_strings_result
[i
]);
9344 printf("run_local_remove_duplicate_addrs2: success\n");
9348 static bool run_local_tdb_opener(int dummy
)
9354 t
= tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST
,
9355 O_RDWR
|O_CREAT
, 0755);
9357 perror("tdb_open failed");
9368 static bool run_local_tdb_writer(int dummy
)
9374 t
= tdb_open("test.tdb", 1000, 0, O_RDWR
|O_CREAT
, 0755);
9376 perror("tdb_open failed");
9380 val
.dptr
= (uint8_t *)&v
;
9381 val
.dsize
= sizeof(v
);
9387 ret
= tdb_store(t
, val
, val
, 0);
9389 printf("%s\n", tdb_errorstr(t
));
9394 data
= tdb_fetch(t
, val
);
9395 if (data
.dptr
!= NULL
) {
9396 SAFE_FREE(data
.dptr
);
9402 static double create_procs(bool (*fn
)(int), bool *result
)
9405 volatile pid_t
*child_status
;
9406 volatile bool *child_status_out
;
9409 struct timeval start
;
9413 child_status
= (volatile pid_t
*)anonymous_shared_allocate(sizeof(pid_t
)*torture_nprocs
);
9414 if (!child_status
) {
9415 printf("Failed to setup shared memory\n");
9419 child_status_out
= (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs
);
9420 if (!child_status_out
) {
9421 printf("Failed to setup result status shared memory\n");
9425 for (i
= 0; i
< torture_nprocs
; i
++) {
9426 child_status
[i
] = 0;
9427 child_status_out
[i
] = True
;
9430 start
= timeval_current();
9432 for (i
=0;i
<torture_nprocs
;i
++) {
9435 pid_t mypid
= getpid();
9436 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
9438 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
9441 if (torture_open_connection(¤t_cli
, i
)) break;
9443 printf("pid %d failed to start\n", (int)getpid());
9449 child_status
[i
] = getpid();
9451 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
9453 child_status_out
[i
] = fn(i
);
9460 for (i
=0;i
<torture_nprocs
;i
++) {
9461 if (child_status
[i
]) synccount
++;
9463 if (synccount
== torture_nprocs
) break;
9465 } while (timeval_elapsed(&start
) < 30);
9467 if (synccount
!= torture_nprocs
) {
9468 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
9470 return timeval_elapsed(&start
);
9473 /* start the client load */
9474 start
= timeval_current();
9476 for (i
=0;i
<torture_nprocs
;i
++) {
9477 child_status
[i
] = 0;
9480 printf("%d clients started\n", torture_nprocs
);
9482 for (i
=0;i
<torture_nprocs
;i
++) {
9483 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
9488 for (i
=0;i
<torture_nprocs
;i
++) {
9489 if (!child_status_out
[i
]) {
9493 return timeval_elapsed(&start
);
9496 #define FLAG_MULTIPROC 1
9503 {"FDPASS", run_fdpasstest
, 0},
9504 {"LOCK1", run_locktest1
, 0},
9505 {"LOCK2", run_locktest2
, 0},
9506 {"LOCK3", run_locktest3
, 0},
9507 {"LOCK4", run_locktest4
, 0},
9508 {"LOCK5", run_locktest5
, 0},
9509 {"LOCK6", run_locktest6
, 0},
9510 {"LOCK7", run_locktest7
, 0},
9511 {"LOCK8", run_locktest8
, 0},
9512 {"LOCK9", run_locktest9
, 0},
9513 {"UNLINK", run_unlinktest
, 0},
9514 {"BROWSE", run_browsetest
, 0},
9515 {"ATTR", run_attrtest
, 0},
9516 {"TRANS2", run_trans2test
, 0},
9517 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
9518 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
9519 {"RANDOMIPC", run_randomipc
, 0},
9520 {"NEGNOWAIT", run_negprot_nowait
, 0},
9521 {"NBENCH", run_nbench
, 0},
9522 {"NBENCH2", run_nbench2
, 0},
9523 {"OPLOCK1", run_oplock1
, 0},
9524 {"OPLOCK2", run_oplock2
, 0},
9525 {"OPLOCK4", run_oplock4
, 0},
9526 {"DIR", run_dirtest
, 0},
9527 {"DIR1", run_dirtest1
, 0},
9528 {"DIR-CREATETIME", run_dir_createtime
, 0},
9529 {"DENY1", torture_denytest1
, 0},
9530 {"DENY2", torture_denytest2
, 0},
9531 {"TCON", run_tcon_test
, 0},
9532 {"TCONDEV", run_tcon_devtype_test
, 0},
9533 {"RW1", run_readwritetest
, 0},
9534 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
9535 {"RW3", run_readwritelarge
, 0},
9536 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
9537 {"OPEN", run_opentest
, 0},
9538 {"POSIX", run_simple_posix_open_test
, 0},
9539 {"POSIX-APPEND", run_posix_append
, 0},
9540 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
9541 {"ASYNC-ECHO", run_async_echo
, 0},
9542 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
9543 { "SHORTNAME-TEST", run_shortname_test
, 0},
9544 { "ADDRCHANGE", run_addrchange
, 0},
9546 {"OPENATTR", run_openattrtest
, 0},
9548 {"XCOPY", run_xcopy
, 0},
9549 {"RENAME", run_rename
, 0},
9550 {"DELETE", run_deletetest
, 0},
9551 {"DELETE-LN", run_deletetest_ln
, 0},
9552 {"PROPERTIES", run_properties
, 0},
9553 {"MANGLE", torture_mangle
, 0},
9554 {"MANGLE1", run_mangle1
, 0},
9555 {"W2K", run_w2ktest
, 0},
9556 {"TRANS2SCAN", torture_trans2_scan
, 0},
9557 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
9558 {"UTABLE", torture_utable
, 0},
9559 {"CASETABLE", torture_casetable
, 0},
9560 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
9561 {"PIPE_NUMBER", run_pipe_number
, 0},
9562 {"TCON2", run_tcon2_test
, 0},
9563 {"IOCTL", torture_ioctl_test
, 0},
9564 {"CHKPATH", torture_chkpath_test
, 0},
9565 {"FDSESS", run_fdsesstest
, 0},
9566 { "EATEST", run_eatest
, 0},
9567 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
9568 { "CHAIN1", run_chain1
, 0},
9569 { "CHAIN2", run_chain2
, 0},
9570 { "CHAIN3", run_chain3
, 0},
9571 { "WINDOWS-WRITE", run_windows_write
, 0},
9572 { "LARGE_READX", run_large_readx
, 0},
9573 { "NTTRANS-CREATE", run_nttrans_create
, 0},
9574 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
9575 { "CLI_ECHO", run_cli_echo
, 0},
9576 { "GETADDRINFO", run_getaddrinfo_send
, 0},
9577 { "TLDAP", run_tldap
},
9578 { "STREAMERROR", run_streamerror
},
9579 { "NOTIFY-BENCH", run_notify_bench
},
9580 { "NOTIFY-BENCH2", run_notify_bench2
},
9581 { "NOTIFY-BENCH3", run_notify_bench3
},
9582 { "BAD-NBT-SESSION", run_bad_nbt_session
},
9583 { "SMB-ANY-CONNECT", run_smb_any_connect
},
9584 { "NOTIFY-ONLINE", run_notify_online
},
9585 { "SMB2-BASIC", run_smb2_basic
},
9586 { "SMB2-NEGPROT", run_smb2_negprot
},
9587 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
9588 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
9589 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
9590 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
9591 { "CLEANUP1", run_cleanup1
},
9592 { "CLEANUP2", run_cleanup2
},
9593 { "CLEANUP3", run_cleanup3
},
9594 { "CLEANUP4", run_cleanup4
},
9595 { "OPLOCK-CANCEL", run_oplock_cancel
},
9596 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
9597 { "LOCAL-GENCACHE", run_local_gencache
, 0},
9598 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
9599 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
9600 { "LOCAL-MESSAGING-READ1", run_messaging_read1
, 0 },
9601 { "LOCAL-MESSAGING-READ2", run_messaging_read2
, 0 },
9602 { "LOCAL-MESSAGING-READ3", run_messaging_read3
, 0 },
9603 { "LOCAL-MESSAGING-READ4", run_messaging_read4
, 0 },
9604 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1
, 0 },
9605 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2
, 0 },
9606 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a
, 0 },
9607 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b
, 0 },
9608 { "LOCAL-BASE64", run_local_base64
, 0},
9609 { "LOCAL-RBTREE", run_local_rbtree
, 0},
9610 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
9611 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
9612 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping
, 0},
9613 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
9614 { "LOCAL-sid_to_string", run_local_sid_to_string
, 0},
9615 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
9616 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
9617 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
9618 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
9619 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
9620 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
9621 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
9622 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
9623 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
9624 { "local-tdb-opener", run_local_tdb_opener
, 0 },
9625 { "local-tdb-writer", run_local_tdb_writer
, 0 },
9626 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb
, 0 },
9627 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool
, 0 },
9628 { "qpathinfo-bufsize", run_qpathinfo_bufsize
, 0 },
9632 * dummy function to satisfy linker dependency
9634 struct tevent_context
*winbind_event_context(void);
9635 struct tevent_context
*winbind_event_context(void)
9640 /****************************************************************************
9641 run a specified test or "ALL"
9642 ****************************************************************************/
9643 static bool run_test(const char *name
)
9650 if (strequal(name
,"ALL")) {
9651 for (i
=0;torture_ops
[i
].name
;i
++) {
9652 run_test(torture_ops
[i
].name
);
9657 for (i
=0;torture_ops
[i
].name
;i
++) {
9658 fstr_sprintf(randomfname
, "\\XX%x",
9659 (unsigned)random());
9661 if (strequal(name
, torture_ops
[i
].name
)) {
9663 printf("Running %s\n", name
);
9664 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
9665 t
= create_procs(torture_ops
[i
].fn
, &result
);
9668 printf("TEST %s FAILED!\n", name
);
9671 struct timeval start
;
9672 start
= timeval_current();
9673 if (!torture_ops
[i
].fn(0)) {
9675 printf("TEST %s FAILED!\n", name
);
9677 t
= timeval_elapsed(&start
);
9679 printf("%s took %g secs\n\n", name
, t
);
9684 printf("Did not find a test named %s\n", name
);
9692 static void usage(void)
9696 printf("WARNING samba4 test suite is much more complete nowadays.\n");
9697 printf("Please use samba4 torture.\n\n");
9699 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9701 printf("\t-d debuglevel\n");
9702 printf("\t-U user%%pass\n");
9703 printf("\t-k use kerberos\n");
9704 printf("\t-N numprocs\n");
9705 printf("\t-n my_netbios_name\n");
9706 printf("\t-W workgroup\n");
9707 printf("\t-o num_operations\n");
9708 printf("\t-O socket_options\n");
9709 printf("\t-m maximum protocol\n");
9710 printf("\t-L use oplocks\n");
9711 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
9712 printf("\t-A showall\n");
9713 printf("\t-p port\n");
9714 printf("\t-s seed\n");
9715 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
9716 printf("\t-f filename filename to test\n");
9717 printf("\t-e encrypt\n");
9720 printf("tests are:");
9721 for (i
=0;torture_ops
[i
].name
;i
++) {
9722 printf(" %s", torture_ops
[i
].name
);
9726 printf("default test is ALL\n");
9731 /****************************************************************************
9733 ****************************************************************************/
9734 int main(int argc
,char *argv
[])
9740 bool correct
= True
;
9741 TALLOC_CTX
*frame
= talloc_stackframe();
9742 int seed
= time(NULL
);
9744 #ifdef HAVE_SETBUFFER
9745 setbuffer(stdout
, NULL
, 0);
9748 setup_logging("smbtorture", DEBUG_STDOUT
);
9753 if (is_default_dyn_CONFIGFILE()) {
9754 if(getenv("SMB_CONF_PATH")) {
9755 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9758 lp_load_global(get_dyn_CONFIGFILE());
9765 for(p
= argv
[1]; *p
; p
++)
9769 if (strncmp(argv
[1], "//", 2)) {
9773 fstrcpy(host
, &argv
[1][2]);
9774 p
= strchr_m(&host
[2],'/');
9779 fstrcpy(share
, p
+1);
9781 fstrcpy(myname
, get_myname(talloc_tos()));
9783 fprintf(stderr
, "Failed to get my hostname.\n");
9787 if (*username
== 0 && getenv("LOGNAME")) {
9788 fstrcpy(username
,getenv("LOGNAME"));
9794 fstrcpy(workgroup
, lp_workgroup());
9796 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9800 port_to_use
= atoi(optarg
);
9803 seed
= atoi(optarg
);
9806 fstrcpy(workgroup
,optarg
);
9809 lp_set_cmdline("client max protocol", optarg
);
9812 torture_nprocs
= atoi(optarg
);
9815 torture_numops
= atoi(optarg
);
9818 lp_set_cmdline("log level", optarg
);
9827 local_path
= optarg
;
9830 torture_showall
= True
;
9833 fstrcpy(myname
, optarg
);
9836 client_txt
= optarg
;
9843 use_kerberos
= True
;
9845 d_printf("No kerberos support compiled in\n");
9851 fstrcpy(username
,optarg
);
9852 p
= strchr_m(username
,'%');
9855 fstrcpy(password
, p
+1);
9860 fstrcpy(multishare_conn_fname
, optarg
);
9861 use_multishare_conn
= True
;
9864 torture_blocksize
= atoi(optarg
);
9867 test_filename
= SMB_STRDUP(optarg
);
9870 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
9875 d_printf("using seed %d\n", seed
);
9879 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9882 char pwd
[256] = {0};
9885 rc
= samba_getpass("Password:", pwd
, sizeof(pwd
), false, false);
9887 fstrcpy(password
, pwd
);
9892 printf("host=%s share=%s user=%s myname=%s\n",
9893 host
, share
, username
, myname
);
9895 if (argc
== optind
) {
9896 correct
= run_test("ALL");
9898 for (i
=optind
;i
<argc
;i
++) {
9899 if (!run_test(argv
[i
])) {