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"
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"
48 fstring host
, workgroup
, share
, password
, username
, myname
;
49 static int max_protocol
= PROTOCOL_NT1
;
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 int signing_state
= SMB_SIGNING_DEFAULT
;
71 bool torture_showall
= False
;
73 static double create_procs(bool (*fn
)(int), bool *result
);
76 /* return a pointer to a anonymous shared memory segment of size "size"
77 which will persist across fork() but will disappear when all processes
80 The memory is not zeroed
82 This function uses system5 shared memory. It takes advantage of a property
83 that the memory is not destroyed if it is attached when the id is removed
85 void *shm_setup(int size
)
91 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
93 printf("can't get shared memory\n");
96 shm_unlink("private");
97 if (ftruncate(shmid
, size
) == -1) {
98 printf("can't set shared memory size\n");
101 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
102 if (ret
== MAP_FAILED
) {
103 printf("can't map shared memory\n");
107 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
109 printf("can't get shared memory\n");
112 ret
= (void *)shmat(shmid
, 0, 0);
113 if (!ret
|| ret
== (void *)-1) {
114 printf("can't attach to shared memory\n");
117 /* the following releases the ipc, but note that this process
118 and all its children will still have access to the memory, its
119 just that the shmid is no longer valid for other shm calls. This
120 means we don't leave behind lots of shm segments after we exit
122 See Stevens "advanced programming in unix env" for details
124 shmctl(shmid
, IPC_RMID
, 0);
130 /********************************************************************
131 Ensure a connection is encrypted.
132 ********************************************************************/
134 static bool force_cli_encryption(struct cli_state
*c
,
135 const char *sharename
)
138 uint32 caplow
, caphigh
;
141 if (!SERVER_HAS_UNIX_CIFS(c
)) {
142 d_printf("Encryption required and "
143 "server that doesn't support "
144 "UNIX extensions - failing connect\n");
148 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
150 if (!NT_STATUS_IS_OK(status
)) {
151 d_printf("Encryption required and "
152 "can't get UNIX CIFS extensions "
153 "version from server: %s\n", nt_errstr(status
));
157 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
158 d_printf("Encryption required and "
159 "share %s doesn't support "
160 "encryption.\n", sharename
);
164 if (c
->use_kerberos
) {
165 status
= cli_gss_smb_encryption_start(c
);
167 status
= cli_raw_ntlm_smb_encryption_start(c
,
173 if (!NT_STATUS_IS_OK(status
)) {
174 d_printf("Encryption required and "
175 "setup failed with error %s.\n",
184 static struct cli_state
*open_nbt_connection(void)
190 if (disable_spnego
) {
191 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
195 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
198 if (use_level_II_oplocks
) {
199 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
203 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
206 if (force_dos_errors
) {
207 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
210 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
211 signing_state
, flags
, &c
);
212 if (!NT_STATUS_IS_OK(status
)) {
213 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
217 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
222 /****************************************************************************
223 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
224 ****************************************************************************/
226 static bool cli_bad_session_request(int fd
,
227 struct nmb_name
*calling
, struct nmb_name
*called
)
236 uint8_t message_type
;
238 struct event_context
*ev
;
239 struct tevent_req
*req
;
241 frame
= talloc_stackframe();
243 iov
[0].iov_base
= len_buf
;
244 iov
[0].iov_len
= sizeof(len_buf
);
246 /* put in the destination name */
248 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
250 if (iov
[1].iov_base
== NULL
) {
253 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
254 talloc_get_size(iov
[1].iov_base
));
258 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
260 if (iov
[2].iov_base
== NULL
) {
263 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
264 talloc_get_size(iov
[2].iov_base
));
266 /* Deliberately corrupt the name len (first byte) */
267 *((uint8_t *)iov
[2].iov_base
) = 100;
269 /* send a session request (RFC 1002) */
270 /* setup the packet length
271 * Remove four bytes from the length count, since the length
272 * field in the NBT Session Service header counts the number
273 * of bytes which follow. The cli_send_smb() function knows
274 * about this and accounts for those four bytes.
278 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
279 SCVAL(len_buf
,0,0x81);
281 len
= write_data_iov(fd
, iov
, 3);
286 ev
= event_context_init(frame
);
290 req
= read_smb_send(frame
, ev
, fd
);
294 if (!tevent_req_poll(req
, ev
)) {
297 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
304 message_type
= CVAL(inbuf
, 0);
305 if (message_type
!= 0x83) {
306 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
311 if (smb_len(inbuf
) != 1) {
312 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
313 (int)smb_len(inbuf
));
317 error
= CVAL(inbuf
, 4);
319 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
330 /* Insert a NULL at the first separator of the given path and return a pointer
331 * to the remainder of the string.
334 terminate_path_at_separator(char * path
)
342 if ((p
= strchr_m(path
, '/'))) {
347 if ((p
= strchr_m(path
, '\\'))) {
357 parse a //server/share type UNC name
359 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
360 char **hostname
, char **sharename
)
364 *hostname
= *sharename
= NULL
;
366 if (strncmp(unc_name
, "\\\\", 2) &&
367 strncmp(unc_name
, "//", 2)) {
371 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
372 p
= terminate_path_at_separator(*hostname
);
375 *sharename
= talloc_strdup(mem_ctx
, p
);
376 terminate_path_at_separator(*sharename
);
379 if (*hostname
&& *sharename
) {
383 TALLOC_FREE(*hostname
);
384 TALLOC_FREE(*sharename
);
388 static bool torture_open_connection_share(struct cli_state
**c
,
389 const char *hostname
,
390 const char *sharename
)
396 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
398 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
399 if (use_level_II_oplocks
)
400 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
402 status
= cli_full_connection(c
, myname
,
403 hostname
, NULL
, port_to_use
,
406 password
, flags
, signing_state
);
407 if (!NT_STATUS_IS_OK(status
)) {
408 printf("failed to open share connection: //%s/%s port:%d - %s\n",
409 hostname
, sharename
, port_to_use
, nt_errstr(status
));
413 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
416 return force_cli_encryption(*c
,
422 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
424 char **unc_list
= NULL
;
425 int num_unc_names
= 0;
428 if (use_multishare_conn
==True
) {
430 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
431 if (!unc_list
|| num_unc_names
<= 0) {
432 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
436 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
438 printf("Failed to parse UNC name %s\n",
439 unc_list
[conn_index
% num_unc_names
]);
440 TALLOC_FREE(unc_list
);
444 result
= torture_open_connection_share(c
, h
, s
);
446 /* h, s were copied earlier */
447 TALLOC_FREE(unc_list
);
451 return torture_open_connection_share(c
, host
, share
);
454 bool torture_init_connection(struct cli_state
**pcli
)
456 struct cli_state
*cli
;
458 cli
= open_nbt_connection();
467 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
469 uint16_t old_vuid
= cli_state_get_uid(cli
);
470 fstring old_user_name
;
471 size_t passlen
= strlen(password
);
475 fstrcpy(old_user_name
, cli
->user_name
);
476 cli_state_set_uid(cli
, 0);
477 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
481 *new_vuid
= cli_state_get_uid(cli
);
482 cli_state_set_uid(cli
, old_vuid
);
483 status
= cli_set_username(cli
, old_user_name
);
484 if (!NT_STATUS_IS_OK(status
)) {
491 bool torture_close_connection(struct cli_state
*c
)
496 status
= cli_tdis(c
);
497 if (!NT_STATUS_IS_OK(status
)) {
498 printf("tdis failed (%s)\n", nt_errstr(status
));
508 /* check if the server produced the expected dos or nt error code */
509 static bool check_both_error(int line
, NTSTATUS status
,
510 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
512 if (NT_STATUS_IS_DOS(status
)) {
516 /* Check DOS error */
517 cclass
= NT_STATUS_DOS_CLASS(status
);
518 num
= NT_STATUS_DOS_CODE(status
);
520 if (eclass
!= cclass
|| ecode
!= num
) {
521 printf("unexpected error code class=%d code=%d\n",
522 (int)cclass
, (int)num
);
523 printf(" expected %d/%d %s (line=%d)\n",
524 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
529 if (!NT_STATUS_EQUAL(nterr
, status
)) {
530 printf("unexpected error code %s\n",
532 printf(" expected %s (line=%d)\n",
533 nt_errstr(nterr
), line
);
542 /* check if the server produced the expected error code */
543 static bool check_error(int line
, NTSTATUS status
,
544 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
546 if (NT_STATUS_IS_DOS(status
)) {
550 /* Check DOS error */
552 cclass
= NT_STATUS_DOS_CLASS(status
);
553 num
= NT_STATUS_DOS_CODE(status
);
555 if (eclass
!= cclass
|| ecode
!= num
) {
556 printf("unexpected error code class=%d code=%d\n",
557 (int)cclass
, (int)num
);
558 printf(" expected %d/%d %s (line=%d)\n",
559 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
567 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
568 printf("unexpected error code %s\n",
570 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
580 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
584 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
586 while (!NT_STATUS_IS_OK(status
)) {
587 if (!check_both_error(__LINE__
, status
, ERRDOS
,
588 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
592 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
599 static bool rw_torture(struct cli_state
*c
)
601 const char *lockfname
= "\\torture.lck";
605 pid_t pid2
, pid
= getpid();
612 memset(buf
, '\0', sizeof(buf
));
614 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
616 if (!NT_STATUS_IS_OK(status
)) {
617 status
= cli_openx(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
619 if (!NT_STATUS_IS_OK(status
)) {
620 printf("open of %s failed (%s)\n",
621 lockfname
, nt_errstr(status
));
625 for (i
=0;i
<torture_numops
;i
++) {
626 unsigned n
= (unsigned)sys_random()%10;
629 printf("%d\r", i
); fflush(stdout
);
631 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
633 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
637 status
= cli_openx(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
639 if (!NT_STATUS_IS_OK(status
)) {
640 printf("open failed (%s)\n", nt_errstr(status
));
645 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
647 if (!NT_STATUS_IS_OK(status
)) {
648 printf("write failed (%s)\n", nt_errstr(status
));
653 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
654 sizeof(pid
)+(j
*sizeof(buf
)),
656 if (!NT_STATUS_IS_OK(status
)) {
657 printf("write failed (%s)\n",
665 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
667 if (!NT_STATUS_IS_OK(status
)) {
668 printf("read failed (%s)\n", nt_errstr(status
));
670 } else if (nread
!= sizeof(pid
)) {
671 printf("read/write compare failed: "
672 "recv %ld req %ld\n", (unsigned long)nread
,
673 (unsigned long)sizeof(pid
));
678 printf("data corruption!\n");
682 status
= cli_close(c
, fnum
);
683 if (!NT_STATUS_IS_OK(status
)) {
684 printf("close failed (%s)\n", nt_errstr(status
));
688 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
689 if (!NT_STATUS_IS_OK(status
)) {
690 printf("unlink failed (%s)\n", nt_errstr(status
));
694 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
695 if (!NT_STATUS_IS_OK(status
)) {
696 printf("unlock failed (%s)\n", nt_errstr(status
));
702 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
709 static bool run_torture(int dummy
)
711 struct cli_state
*cli
;
716 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
718 ret
= rw_torture(cli
);
720 if (!torture_close_connection(cli
)) {
727 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
729 uint16_t fnum
= (uint16_t)-1;
734 unsigned countprev
= 0;
737 NTSTATUS status
= NT_STATUS_OK
;
740 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
742 SIVAL(buf
, i
, sys_random());
749 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
750 if (!NT_STATUS_IS_OK(status
)) {
751 printf("unlink failed (%s) (normal, this file should "
752 "not exist)\n", nt_errstr(status
));
755 status
= cli_openx(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
757 if (!NT_STATUS_IS_OK(status
)) {
758 printf("first open read/write of %s failed (%s)\n",
759 lockfname
, nt_errstr(status
));
765 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
767 status
= cli_openx(c
, lockfname
, O_RDONLY
,
769 if (!NT_STATUS_IS_OK(status
)) {
774 if (!NT_STATUS_IS_OK(status
)) {
775 printf("second open read-only of %s failed (%s)\n",
776 lockfname
, nt_errstr(status
));
782 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
784 if (count
>= countprev
) {
785 printf("%d %8d\r", i
, count
);
788 countprev
+= (sizeof(buf
) / 20);
793 sent
= ((unsigned)sys_random()%(20))+ 1;
794 if (sent
> sizeof(buf
) - count
)
796 sent
= sizeof(buf
) - count
;
799 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
801 if (!NT_STATUS_IS_OK(status
)) {
802 printf("write failed (%s)\n",
809 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
810 sizeof(buf
)-count
, &sent
);
811 if(!NT_STATUS_IS_OK(status
)) {
812 printf("read failed offset:%d size:%ld (%s)\n",
813 count
, (unsigned long)sizeof(buf
)-count
,
817 } else if (sent
> 0) {
818 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
820 printf("read/write compare failed\n");
821 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
830 status
= cli_close(c
, fnum
);
831 if (!NT_STATUS_IS_OK(status
)) {
832 printf("close failed (%s)\n", nt_errstr(status
));
839 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
841 const char *lockfname
= "\\torture2.lck";
851 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
852 if (!NT_STATUS_IS_OK(status
)) {
853 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
856 status
= cli_openx(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
858 if (!NT_STATUS_IS_OK(status
)) {
859 printf("first open read/write of %s failed (%s)\n",
860 lockfname
, nt_errstr(status
));
864 status
= cli_openx(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
865 if (!NT_STATUS_IS_OK(status
)) {
866 printf("second open read-only of %s failed (%s)\n",
867 lockfname
, nt_errstr(status
));
868 cli_close(c1
, fnum1
);
872 for (i
= 0; i
< torture_numops
; i
++)
874 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
876 printf("%d\r", i
); fflush(stdout
);
879 generate_random_buffer((unsigned char *)buf
, buf_size
);
881 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
883 if (!NT_STATUS_IS_OK(status
)) {
884 printf("write failed (%s)\n", nt_errstr(status
));
889 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
890 if(!NT_STATUS_IS_OK(status
)) {
891 printf("read failed (%s)\n", nt_errstr(status
));
894 } else if (bytes_read
!= buf_size
) {
895 printf("read failed\n");
896 printf("read %ld, expected %ld\n",
897 (unsigned long)bytes_read
,
898 (unsigned long)buf_size
);
903 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
905 printf("read/write compare failed\n");
911 status
= cli_close(c2
, fnum2
);
912 if (!NT_STATUS_IS_OK(status
)) {
913 printf("close failed (%s)\n", nt_errstr(status
));
917 status
= cli_close(c1
, fnum1
);
918 if (!NT_STATUS_IS_OK(status
)) {
919 printf("close failed (%s)\n", nt_errstr(status
));
923 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
924 if (!NT_STATUS_IS_OK(status
)) {
925 printf("unlink failed (%s)\n", nt_errstr(status
));
932 static bool run_readwritetest(int dummy
)
934 struct cli_state
*cli1
, *cli2
;
935 bool test1
, test2
= False
;
937 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
940 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
941 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
943 printf("starting readwritetest\n");
945 test1
= rw_torture2(cli1
, cli2
);
946 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
949 test2
= rw_torture2(cli1
, cli1
);
950 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
953 if (!torture_close_connection(cli1
)) {
957 if (!torture_close_connection(cli2
)) {
961 return (test1
&& test2
);
964 static bool run_readwritemulti(int dummy
)
966 struct cli_state
*cli
;
971 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
973 printf("run_readwritemulti: fname %s\n", randomfname
);
974 test
= rw_torture3(cli
, randomfname
);
976 if (!torture_close_connection(cli
)) {
983 static bool run_readwritelarge_internal(void)
985 static struct cli_state
*cli1
;
987 const char *lockfname
= "\\large.dat";
993 if (!torture_open_connection(&cli1
, 0)) {
996 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
997 memset(buf
,'\0',sizeof(buf
));
999 printf("starting readwritelarge_internal\n");
1001 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1003 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1005 if (!NT_STATUS_IS_OK(status
)) {
1006 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1010 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
1012 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1014 if (!NT_STATUS_IS_OK(status
)) {
1015 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1019 if (fsize
== sizeof(buf
))
1020 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1021 (unsigned long)fsize
);
1023 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1024 (unsigned long)fsize
);
1028 status
= cli_close(cli1
, fnum1
);
1029 if (!NT_STATUS_IS_OK(status
)) {
1030 printf("close failed (%s)\n", nt_errstr(status
));
1034 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1035 if (!NT_STATUS_IS_OK(status
)) {
1036 printf("unlink failed (%s)\n", nt_errstr(status
));
1040 status
= cli_openx(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1042 if (!NT_STATUS_IS_OK(status
)) {
1043 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1047 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
1049 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1051 if (!NT_STATUS_IS_OK(status
)) {
1052 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1056 if (fsize
== sizeof(buf
))
1057 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1058 (unsigned long)fsize
);
1060 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1061 (unsigned long)fsize
);
1066 /* ToDo - set allocation. JRA */
1067 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1068 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1071 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1073 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1077 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1080 status
= cli_close(cli1
, fnum1
);
1081 if (!NT_STATUS_IS_OK(status
)) {
1082 printf("close failed (%s)\n", nt_errstr(status
));
1086 if (!torture_close_connection(cli1
)) {
1092 static bool run_readwritelarge(int dummy
)
1094 return run_readwritelarge_internal();
1097 static bool run_readwritelarge_signtest(int dummy
)
1100 signing_state
= SMB_SIGNING_REQUIRED
;
1101 ret
= run_readwritelarge_internal();
1102 signing_state
= SMB_SIGNING_DEFAULT
;
1109 #define ival(s) strtol(s, NULL, 0)
1111 /* run a test that simulates an approximate netbench client load */
1112 static bool run_netbench(int client
)
1114 struct cli_state
*cli
;
1119 const char *params
[20];
1120 bool correct
= True
;
1126 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1130 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1132 f
= fopen(client_txt
, "r");
1139 while (fgets(line
, sizeof(line
)-1, f
)) {
1143 line
[strlen(line
)-1] = 0;
1145 /* printf("[%d] %s\n", line_count, line); */
1147 all_string_sub(line
,"client1", cname
, sizeof(line
));
1149 /* parse the command parameters */
1150 params
[0] = strtok_r(line
, " ", &saveptr
);
1152 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1156 if (i
< 2) continue;
1158 if (!strncmp(params
[0],"SMB", 3)) {
1159 printf("ERROR: You are using a dbench 1 load file\n");
1163 if (!strcmp(params
[0],"NTCreateX")) {
1164 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1166 } else if (!strcmp(params
[0],"Close")) {
1167 nb_close(ival(params
[1]));
1168 } else if (!strcmp(params
[0],"Rename")) {
1169 nb_rename(params
[1], params
[2]);
1170 } else if (!strcmp(params
[0],"Unlink")) {
1171 nb_unlink(params
[1]);
1172 } else if (!strcmp(params
[0],"Deltree")) {
1173 nb_deltree(params
[1]);
1174 } else if (!strcmp(params
[0],"Rmdir")) {
1175 nb_rmdir(params
[1]);
1176 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1177 nb_qpathinfo(params
[1]);
1178 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1179 nb_qfileinfo(ival(params
[1]));
1180 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1181 nb_qfsinfo(ival(params
[1]));
1182 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1183 nb_findfirst(params
[1]);
1184 } else if (!strcmp(params
[0],"WriteX")) {
1185 nb_writex(ival(params
[1]),
1186 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1187 } else if (!strcmp(params
[0],"ReadX")) {
1188 nb_readx(ival(params
[1]),
1189 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1190 } else if (!strcmp(params
[0],"Flush")) {
1191 nb_flush(ival(params
[1]));
1193 printf("Unknown operation %s\n", params
[0]);
1201 if (!torture_close_connection(cli
)) {
1209 /* run a test that simulates an approximate netbench client load */
1210 static bool run_nbench(int dummy
)
1213 bool correct
= True
;
1215 nbio_shmem(torture_nprocs
);
1219 signal(SIGALRM
, nb_alarm
);
1221 t
= create_procs(run_netbench
, &correct
);
1224 printf("\nThroughput %g MB/sec\n",
1225 1.0e-6 * nbio_total() / t
);
1231 This test checks for two things:
1233 1) correct support for retaining locks over a close (ie. the server
1234 must not use posix semantics)
1235 2) support for lock timeouts
1237 static bool run_locktest1(int dummy
)
1239 struct cli_state
*cli1
, *cli2
;
1240 const char *fname
= "\\lockt1.lck";
1241 uint16_t fnum1
, fnum2
, fnum3
;
1243 unsigned lock_timeout
;
1246 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1249 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1250 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1252 printf("starting locktest1\n");
1254 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1256 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1258 if (!NT_STATUS_IS_OK(status
)) {
1259 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1263 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1264 if (!NT_STATUS_IS_OK(status
)) {
1265 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1269 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1270 if (!NT_STATUS_IS_OK(status
)) {
1271 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1275 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1276 if (!NT_STATUS_IS_OK(status
)) {
1277 printf("lock1 failed (%s)\n", nt_errstr(status
));
1281 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1282 if (NT_STATUS_IS_OK(status
)) {
1283 printf("lock2 succeeded! This is a locking bug\n");
1286 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1287 NT_STATUS_LOCK_NOT_GRANTED
)) {
1292 lock_timeout
= (1 + (random() % 20));
1293 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1295 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1296 if (NT_STATUS_IS_OK(status
)) {
1297 printf("lock3 succeeded! This is a locking bug\n");
1300 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1301 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1307 if (ABS(t2
- t1
) < lock_timeout
-1) {
1308 printf("error: This server appears not to support timed lock requests\n");
1311 printf("server slept for %u seconds for a %u second timeout\n",
1312 (unsigned int)(t2
-t1
), lock_timeout
);
1314 status
= cli_close(cli1
, fnum2
);
1315 if (!NT_STATUS_IS_OK(status
)) {
1316 printf("close1 failed (%s)\n", nt_errstr(status
));
1320 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1321 if (NT_STATUS_IS_OK(status
)) {
1322 printf("lock4 succeeded! This is a locking bug\n");
1325 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1326 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1331 status
= cli_close(cli1
, fnum1
);
1332 if (!NT_STATUS_IS_OK(status
)) {
1333 printf("close2 failed (%s)\n", nt_errstr(status
));
1337 status
= cli_close(cli2
, fnum3
);
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 printf("close3 failed (%s)\n", nt_errstr(status
));
1343 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1344 if (!NT_STATUS_IS_OK(status
)) {
1345 printf("unlink failed (%s)\n", nt_errstr(status
));
1350 if (!torture_close_connection(cli1
)) {
1354 if (!torture_close_connection(cli2
)) {
1358 printf("Passed locktest1\n");
1363 this checks to see if a secondary tconx can use open files from an
1366 static bool run_tcon_test(int dummy
)
1368 static struct cli_state
*cli
;
1369 const char *fname
= "\\tcontest.tmp";
1371 uint16 cnum1
, cnum2
, cnum3
;
1372 uint16 vuid1
, vuid2
;
1377 memset(buf
, '\0', sizeof(buf
));
1379 if (!torture_open_connection(&cli
, 0)) {
1382 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1384 printf("starting tcontest\n");
1386 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1388 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1389 if (!NT_STATUS_IS_OK(status
)) {
1390 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1394 cnum1
= cli_state_get_tid(cli
);
1395 vuid1
= cli_state_get_uid(cli
);
1397 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1398 if (!NT_STATUS_IS_OK(status
)) {
1399 printf("initial write failed (%s)", nt_errstr(status
));
1403 status
= cli_tree_connect(cli
, share
, "?????",
1404 password
, strlen(password
)+1);
1405 if (!NT_STATUS_IS_OK(status
)) {
1406 printf("%s refused 2nd tree connect (%s)\n", host
,
1412 cnum2
= cli_state_get_tid(cli
);
1413 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1414 vuid2
= cli_state_get_uid(cli
) + 1;
1416 /* try a write with the wrong tid */
1417 cli_state_set_tid(cli
, cnum2
);
1419 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1420 if (NT_STATUS_IS_OK(status
)) {
1421 printf("* server allows write with wrong TID\n");
1424 printf("server fails write with wrong TID : %s\n",
1429 /* try a write with an invalid tid */
1430 cli_state_set_tid(cli
, cnum3
);
1432 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1433 if (NT_STATUS_IS_OK(status
)) {
1434 printf("* server allows write with invalid TID\n");
1437 printf("server fails write with invalid TID : %s\n",
1441 /* try a write with an invalid vuid */
1442 cli_state_set_uid(cli
, vuid2
);
1443 cli_state_set_tid(cli
, cnum1
);
1445 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1446 if (NT_STATUS_IS_OK(status
)) {
1447 printf("* server allows write with invalid VUID\n");
1450 printf("server fails write with invalid VUID : %s\n",
1454 cli_state_set_tid(cli
, cnum1
);
1455 cli_state_set_uid(cli
, vuid1
);
1457 status
= cli_close(cli
, fnum1
);
1458 if (!NT_STATUS_IS_OK(status
)) {
1459 printf("close failed (%s)\n", nt_errstr(status
));
1463 cli_state_set_tid(cli
, cnum2
);
1465 status
= cli_tdis(cli
);
1466 if (!NT_STATUS_IS_OK(status
)) {
1467 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1471 cli_state_set_tid(cli
, cnum1
);
1473 if (!torture_close_connection(cli
)) {
1482 checks for old style tcon support
1484 static bool run_tcon2_test(int dummy
)
1486 static struct cli_state
*cli
;
1487 uint16 cnum
, max_xmit
;
1491 if (!torture_open_connection(&cli
, 0)) {
1494 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1496 printf("starting tcon2 test\n");
1498 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1502 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1506 if (!NT_STATUS_IS_OK(status
)) {
1507 printf("tcon2 failed : %s\n", nt_errstr(status
));
1509 printf("tcon OK : max_xmit=%d cnum=%d\n",
1510 (int)max_xmit
, (int)cnum
);
1513 if (!torture_close_connection(cli
)) {
1517 printf("Passed tcon2 test\n");
1521 static bool tcon_devtest(struct cli_state
*cli
,
1522 const char *myshare
, const char *devtype
,
1523 const char *return_devtype
,
1524 NTSTATUS expected_error
)
1529 status
= cli_tree_connect(cli
, myshare
, devtype
,
1530 password
, strlen(password
)+1);
1532 if (NT_STATUS_IS_OK(expected_error
)) {
1533 if (NT_STATUS_IS_OK(status
)) {
1534 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1537 printf("tconX to share %s with type %s "
1538 "succeeded but returned the wrong "
1539 "device type (got [%s] but should have got [%s])\n",
1540 myshare
, devtype
, cli
->dev
, return_devtype
);
1544 printf("tconX to share %s with type %s "
1545 "should have succeeded but failed\n",
1551 if (NT_STATUS_IS_OK(status
)) {
1552 printf("tconx to share %s with type %s "
1553 "should have failed but succeeded\n",
1557 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1560 printf("Returned unexpected error\n");
1569 checks for correct tconX support
1571 static bool run_tcon_devtype_test(int dummy
)
1573 static struct cli_state
*cli1
= NULL
;
1578 status
= cli_full_connection(&cli1
, myname
,
1579 host
, NULL
, port_to_use
,
1581 username
, workgroup
,
1582 password
, flags
, signing_state
);
1584 if (!NT_STATUS_IS_OK(status
)) {
1585 printf("could not open connection\n");
1589 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1592 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1595 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1598 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1601 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1604 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1607 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1610 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1613 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1616 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1622 printf("Passed tcondevtest\n");
1629 This test checks that
1631 1) the server supports multiple locking contexts on the one SMB
1632 connection, distinguished by PID.
1634 2) the server correctly fails overlapping locks made by the same PID (this
1635 goes against POSIX behaviour, which is why it is tricky to implement)
1637 3) the server denies unlock requests by an incorrect client PID
1639 static bool run_locktest2(int dummy
)
1641 static struct cli_state
*cli
;
1642 const char *fname
= "\\lockt2.lck";
1643 uint16_t fnum1
, fnum2
, fnum3
;
1644 bool correct
= True
;
1647 if (!torture_open_connection(&cli
, 0)) {
1651 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
1653 printf("starting locktest2\n");
1655 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1659 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1660 if (!NT_STATUS_IS_OK(status
)) {
1661 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1665 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1666 if (!NT_STATUS_IS_OK(status
)) {
1667 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1673 status
= cli_openx(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1674 if (!NT_STATUS_IS_OK(status
)) {
1675 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1681 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1682 if (!NT_STATUS_IS_OK(status
)) {
1683 printf("lock1 failed (%s)\n", nt_errstr(status
));
1687 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1688 if (NT_STATUS_IS_OK(status
)) {
1689 printf("WRITE lock1 succeeded! This is a locking bug\n");
1692 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1693 NT_STATUS_LOCK_NOT_GRANTED
)) {
1698 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1699 if (NT_STATUS_IS_OK(status
)) {
1700 printf("WRITE lock2 succeeded! This is a locking bug\n");
1703 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1704 NT_STATUS_LOCK_NOT_GRANTED
)) {
1709 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1710 if (NT_STATUS_IS_OK(status
)) {
1711 printf("READ lock2 succeeded! This is a locking bug\n");
1714 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1715 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1720 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1721 if (!NT_STATUS_IS_OK(status
)) {
1722 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1725 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1726 printf("unlock at 100 succeeded! This is a locking bug\n");
1730 status
= cli_unlock(cli
, fnum1
, 0, 4);
1731 if (NT_STATUS_IS_OK(status
)) {
1732 printf("unlock1 succeeded! This is a locking bug\n");
1735 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1736 NT_STATUS_RANGE_NOT_LOCKED
)) {
1741 status
= cli_unlock(cli
, fnum1
, 0, 8);
1742 if (NT_STATUS_IS_OK(status
)) {
1743 printf("unlock2 succeeded! This is a locking bug\n");
1746 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1747 NT_STATUS_RANGE_NOT_LOCKED
)) {
1752 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1753 if (NT_STATUS_IS_OK(status
)) {
1754 printf("lock3 succeeded! This is a locking bug\n");
1757 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1758 NT_STATUS_LOCK_NOT_GRANTED
)) {
1765 status
= cli_close(cli
, fnum1
);
1766 if (!NT_STATUS_IS_OK(status
)) {
1767 printf("close1 failed (%s)\n", nt_errstr(status
));
1771 status
= cli_close(cli
, fnum2
);
1772 if (!NT_STATUS_IS_OK(status
)) {
1773 printf("close2 failed (%s)\n", nt_errstr(status
));
1777 status
= cli_close(cli
, fnum3
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1779 printf("close3 failed (%s)\n", nt_errstr(status
));
1783 if (!torture_close_connection(cli
)) {
1787 printf("locktest2 finished\n");
1794 This test checks that
1796 1) the server supports the full offset range in lock requests
1798 static bool run_locktest3(int dummy
)
1800 static struct cli_state
*cli1
, *cli2
;
1801 const char *fname
= "\\lockt3.lck";
1802 uint16_t fnum1
, fnum2
;
1805 bool correct
= True
;
1808 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1810 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1813 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1814 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1816 printf("starting locktest3\n");
1818 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1820 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1822 if (!NT_STATUS_IS_OK(status
)) {
1823 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1827 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1828 if (!NT_STATUS_IS_OK(status
)) {
1829 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1833 for (offset
=i
=0;i
<torture_numops
;i
++) {
1836 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1837 if (!NT_STATUS_IS_OK(status
)) {
1838 printf("lock1 %d failed (%s)\n",
1844 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1845 if (!NT_STATUS_IS_OK(status
)) {
1846 printf("lock2 %d failed (%s)\n",
1853 for (offset
=i
=0;i
<torture_numops
;i
++) {
1856 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1857 if (NT_STATUS_IS_OK(status
)) {
1858 printf("error: lock1 %d succeeded!\n", i
);
1862 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1863 if (NT_STATUS_IS_OK(status
)) {
1864 printf("error: lock2 %d succeeded!\n", i
);
1868 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1869 if (NT_STATUS_IS_OK(status
)) {
1870 printf("error: lock3 %d succeeded!\n", i
);
1874 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1875 if (NT_STATUS_IS_OK(status
)) {
1876 printf("error: lock4 %d succeeded!\n", i
);
1881 for (offset
=i
=0;i
<torture_numops
;i
++) {
1884 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1885 if (!NT_STATUS_IS_OK(status
)) {
1886 printf("unlock1 %d failed (%s)\n",
1892 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1893 if (!NT_STATUS_IS_OK(status
)) {
1894 printf("unlock2 %d failed (%s)\n",
1901 status
= cli_close(cli1
, fnum1
);
1902 if (!NT_STATUS_IS_OK(status
)) {
1903 printf("close1 failed (%s)\n", nt_errstr(status
));
1907 status
= cli_close(cli2
, fnum2
);
1908 if (!NT_STATUS_IS_OK(status
)) {
1909 printf("close2 failed (%s)\n", nt_errstr(status
));
1913 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1914 if (!NT_STATUS_IS_OK(status
)) {
1915 printf("unlink failed (%s)\n", nt_errstr(status
));
1919 if (!torture_close_connection(cli1
)) {
1923 if (!torture_close_connection(cli2
)) {
1927 printf("finished locktest3\n");
1932 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1933 char *buf
, off_t offset
, size_t size
,
1934 size_t *nread
, size_t expect
)
1939 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1941 if(!NT_STATUS_IS_OK(status
)) {
1943 } else if (l_nread
!= expect
) {
1954 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1955 printf("** "); correct = False; \
1959 looks at overlapping locks
1961 static bool run_locktest4(int dummy
)
1963 static struct cli_state
*cli1
, *cli2
;
1964 const char *fname
= "\\lockt4.lck";
1965 uint16_t fnum1
, fnum2
, f
;
1968 bool correct
= True
;
1971 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1975 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
1976 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
1978 printf("starting locktest4\n");
1980 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1982 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1983 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1985 memset(buf
, 0, sizeof(buf
));
1987 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1989 if (!NT_STATUS_IS_OK(status
)) {
1990 printf("Failed to create file: %s\n", nt_errstr(status
));
1995 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1996 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1997 EXPECTED(ret
, False
);
1998 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
2000 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
2001 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
2002 EXPECTED(ret
, True
);
2003 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
2005 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
2006 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
2007 EXPECTED(ret
, False
);
2008 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
2010 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
2011 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
2012 EXPECTED(ret
, True
);
2013 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
2015 ret
= (cli_setpid(cli1
, 1),
2016 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
2017 (cli_setpid(cli1
, 2),
2018 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
2019 EXPECTED(ret
, False
);
2020 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
2022 ret
= (cli_setpid(cli1
, 1),
2023 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
2024 (cli_setpid(cli1
, 2),
2025 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
2026 EXPECTED(ret
, True
);
2027 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
2029 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
2030 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
2031 EXPECTED(ret
, True
);
2032 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
2034 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
2035 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
2036 EXPECTED(ret
, False
);
2037 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
2039 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
2040 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
2041 EXPECTED(ret
, False
);
2042 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
2044 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
2045 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
2046 EXPECTED(ret
, True
);
2047 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2049 ret
= (cli_setpid(cli1
, 1),
2050 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2051 (cli_setpid(cli1
, 2),
2052 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2053 EXPECTED(ret
, False
);
2054 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2056 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2057 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2058 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2059 EXPECTED(ret
, False
);
2060 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2063 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2064 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2065 EXPECTED(ret
, False
);
2066 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2068 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2069 ret
= NT_STATUS_IS_OK(status
);
2071 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2073 ret
= NT_STATUS_IS_OK(status
);
2075 EXPECTED(ret
, False
);
2076 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2079 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2082 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2083 EXPECTED(ret
, True
);
2084 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2087 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2088 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2089 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2090 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2091 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2093 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2094 EXPECTED(ret
, True
);
2095 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2097 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2098 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2099 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2101 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2102 EXPECTED(ret
, True
);
2103 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2105 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2106 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2107 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2109 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2110 EXPECTED(ret
, True
);
2111 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2113 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2114 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2115 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2116 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2118 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2119 EXPECTED(ret
, True
);
2120 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2122 cli_close(cli1
, fnum1
);
2123 cli_close(cli2
, fnum2
);
2124 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2125 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2126 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2127 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2128 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2129 NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2130 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2132 cli_close(cli1
, fnum1
);
2133 EXPECTED(ret
, True
);
2134 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2137 cli_close(cli1
, fnum1
);
2138 cli_close(cli2
, fnum2
);
2139 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2140 torture_close_connection(cli1
);
2141 torture_close_connection(cli2
);
2143 printf("finished locktest4\n");
2148 looks at lock upgrade/downgrade.
2150 static bool run_locktest5(int dummy
)
2152 static struct cli_state
*cli1
, *cli2
;
2153 const char *fname
= "\\lockt5.lck";
2154 uint16_t fnum1
, fnum2
, fnum3
;
2157 bool correct
= True
;
2160 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2164 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2165 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2167 printf("starting locktest5\n");
2169 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2171 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2172 cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2173 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2175 memset(buf
, 0, sizeof(buf
));
2177 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2179 if (!NT_STATUS_IS_OK(status
)) {
2180 printf("Failed to create file: %s\n", nt_errstr(status
));
2185 /* Check for NT bug... */
2186 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2187 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2188 cli_close(cli1
, fnum1
);
2189 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2190 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2191 ret
= NT_STATUS_IS_OK(status
);
2192 EXPECTED(ret
, True
);
2193 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2194 cli_close(cli1
, fnum1
);
2195 cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2196 cli_unlock(cli1
, fnum3
, 0, 1);
2198 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2199 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2200 EXPECTED(ret
, True
);
2201 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2203 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2204 ret
= NT_STATUS_IS_OK(status
);
2205 EXPECTED(ret
, False
);
2207 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2209 /* Unlock the process 2 lock. */
2210 cli_unlock(cli2
, fnum2
, 0, 4);
2212 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2213 ret
= NT_STATUS_IS_OK(status
);
2214 EXPECTED(ret
, False
);
2216 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2218 /* Unlock the process 1 fnum3 lock. */
2219 cli_unlock(cli1
, fnum3
, 0, 4);
2221 /* Stack 2 more locks here. */
2222 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2223 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2225 EXPECTED(ret
, True
);
2226 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2228 /* Unlock the first process lock, then check this was the WRITE lock that was
2231 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2232 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2234 EXPECTED(ret
, True
);
2235 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2237 /* Unlock the process 2 lock. */
2238 cli_unlock(cli2
, fnum2
, 0, 4);
2240 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2242 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2243 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2244 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2246 EXPECTED(ret
, True
);
2247 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2249 /* Ensure the next unlock fails. */
2250 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2251 EXPECTED(ret
, False
);
2252 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2254 /* Ensure connection 2 can get a write lock. */
2255 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2256 ret
= NT_STATUS_IS_OK(status
);
2257 EXPECTED(ret
, True
);
2259 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2263 cli_close(cli1
, fnum1
);
2264 cli_close(cli2
, fnum2
);
2265 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2266 if (!torture_close_connection(cli1
)) {
2269 if (!torture_close_connection(cli2
)) {
2273 printf("finished locktest5\n");
2279 tries the unusual lockingX locktype bits
2281 static bool run_locktest6(int dummy
)
2283 static struct cli_state
*cli
;
2284 const char *fname
[1] = { "\\lock6.txt" };
2289 if (!torture_open_connection(&cli
, 0)) {
2293 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2295 printf("starting locktest6\n");
2298 printf("Testing %s\n", fname
[i
]);
2300 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2302 cli_openx(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2303 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2304 cli_close(cli
, fnum
);
2305 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2307 cli_openx(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2308 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2309 cli_close(cli
, fnum
);
2310 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2312 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2315 torture_close_connection(cli
);
2317 printf("finished locktest6\n");
2321 static bool run_locktest7(int dummy
)
2323 struct cli_state
*cli1
;
2324 const char *fname
= "\\lockt7.lck";
2327 bool correct
= False
;
2331 if (!torture_open_connection(&cli1
, 0)) {
2335 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2337 printf("starting locktest7\n");
2339 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2341 cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2343 memset(buf
, 0, sizeof(buf
));
2345 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2347 if (!NT_STATUS_IS_OK(status
)) {
2348 printf("Failed to create file: %s\n", nt_errstr(status
));
2352 cli_setpid(cli1
, 1);
2354 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2355 if (!NT_STATUS_IS_OK(status
)) {
2356 printf("Unable to apply read lock on range 130:4, "
2357 "error was %s\n", nt_errstr(status
));
2360 printf("pid1 successfully locked range 130:4 for READ\n");
2363 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2364 if (!NT_STATUS_IS_OK(status
)) {
2365 printf("pid1 unable to read the range 130:4, error was %s\n",
2368 } else if (nread
!= 4) {
2369 printf("pid1 unable to read the range 130:4, "
2370 "recv %ld req %d\n", (unsigned long)nread
, 4);
2373 printf("pid1 successfully read the range 130:4\n");
2376 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2377 if (!NT_STATUS_IS_OK(status
)) {
2378 printf("pid1 unable to write to the range 130:4, error was "
2379 "%s\n", nt_errstr(status
));
2380 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2381 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2385 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2389 cli_setpid(cli1
, 2);
2391 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2392 if (!NT_STATUS_IS_OK(status
)) {
2393 printf("pid2 unable to read the range 130:4, error was %s\n",
2396 } else if (nread
!= 4) {
2397 printf("pid2 unable to read the range 130:4, "
2398 "recv %ld req %d\n", (unsigned long)nread
, 4);
2401 printf("pid2 successfully read the range 130:4\n");
2404 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2405 if (!NT_STATUS_IS_OK(status
)) {
2406 printf("pid2 unable to write to the range 130:4, error was "
2407 "%s\n", nt_errstr(status
));
2408 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2409 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2413 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2417 cli_setpid(cli1
, 1);
2418 cli_unlock(cli1
, fnum1
, 130, 4);
2420 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2421 if (!NT_STATUS_IS_OK(status
)) {
2422 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2425 printf("pid1 successfully locked range 130:4 for WRITE\n");
2428 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2429 if (!NT_STATUS_IS_OK(status
)) {
2430 printf("pid1 unable to read the range 130:4, error was %s\n",
2433 } else if (nread
!= 4) {
2434 printf("pid1 unable to read the range 130:4, "
2435 "recv %ld req %d\n", (unsigned long)nread
, 4);
2438 printf("pid1 successfully read the range 130:4\n");
2441 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2442 if (!NT_STATUS_IS_OK(status
)) {
2443 printf("pid1 unable to write to the range 130:4, error was "
2444 "%s\n", nt_errstr(status
));
2447 printf("pid1 successfully wrote to the range 130:4\n");
2450 cli_setpid(cli1
, 2);
2452 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2453 if (!NT_STATUS_IS_OK(status
)) {
2454 printf("pid2 unable to read the range 130:4, error was "
2455 "%s\n", nt_errstr(status
));
2456 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2457 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2461 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2462 (unsigned long)nread
);
2466 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2467 if (!NT_STATUS_IS_OK(status
)) {
2468 printf("pid2 unable to write to the range 130:4, error was "
2469 "%s\n", nt_errstr(status
));
2470 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2471 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2475 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2479 cli_unlock(cli1
, fnum1
, 130, 0);
2483 cli_close(cli1
, fnum1
);
2484 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2485 torture_close_connection(cli1
);
2487 printf("finished locktest7\n");
2492 * This demonstrates a problem with our use of GPFS share modes: A file
2493 * descriptor sitting in the pending close queue holding a GPFS share mode
2494 * blocks opening a file another time. Happens with Word 2007 temp files.
2495 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2496 * open is denied with NT_STATUS_SHARING_VIOLATION.
2499 static bool run_locktest8(int dummy
)
2501 struct cli_state
*cli1
;
2502 const char *fname
= "\\lockt8.lck";
2503 uint16_t fnum1
, fnum2
;
2505 bool correct
= False
;
2508 if (!torture_open_connection(&cli1
, 0)) {
2512 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2514 printf("starting locktest8\n");
2516 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2518 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2520 if (!NT_STATUS_IS_OK(status
)) {
2521 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2525 memset(buf
, 0, sizeof(buf
));
2527 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2528 if (!NT_STATUS_IS_OK(status
)) {
2529 d_fprintf(stderr
, "cli_openx second time returned %s\n",
2534 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2535 if (!NT_STATUS_IS_OK(status
)) {
2536 printf("Unable to apply read lock on range 1:1, error was "
2537 "%s\n", nt_errstr(status
));
2541 status
= cli_close(cli1
, fnum1
);
2542 if (!NT_STATUS_IS_OK(status
)) {
2543 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2547 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2548 if (!NT_STATUS_IS_OK(status
)) {
2549 d_fprintf(stderr
, "cli_openx third time returned %s\n",
2557 cli_close(cli1
, fnum1
);
2558 cli_close(cli1
, fnum2
);
2559 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2560 torture_close_connection(cli1
);
2562 printf("finished locktest8\n");
2567 * This test is designed to be run in conjunction with
2568 * external NFS or POSIX locks taken in the filesystem.
2569 * It checks that the smbd server will block until the
2570 * lock is released and then acquire it. JRA.
2573 static bool got_alarm
;
2574 static struct cli_state
*alarm_cli
;
2576 static void alarm_handler(int dummy
)
2581 static void alarm_handler_parent(int dummy
)
2583 smbXcli_conn_disconnect(alarm_cli
->conn
, NT_STATUS_OK
);
2586 static void do_local_lock(int read_fd
, int write_fd
)
2591 const char *local_pathname
= NULL
;
2594 local_pathname
= talloc_asprintf(talloc_tos(),
2595 "%s/lockt9.lck", local_path
);
2596 if (!local_pathname
) {
2597 printf("child: alloc fail\n");
2601 unlink(local_pathname
);
2602 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2604 printf("child: open of %s failed %s.\n",
2605 local_pathname
, strerror(errno
));
2609 /* Now take a fcntl lock. */
2610 lock
.l_type
= F_WRLCK
;
2611 lock
.l_whence
= SEEK_SET
;
2614 lock
.l_pid
= getpid();
2616 ret
= fcntl(fd
,F_SETLK
,&lock
);
2618 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2619 local_pathname
, strerror(errno
));
2622 printf("child: got lock 0:4 on file %s.\n",
2627 CatchSignal(SIGALRM
, alarm_handler
);
2629 /* Signal the parent. */
2630 if (write(write_fd
, &c
, 1) != 1) {
2631 printf("child: start signal fail %s.\n",
2638 /* Wait for the parent to be ready. */
2639 if (read(read_fd
, &c
, 1) != 1) {
2640 printf("child: reply signal fail %s.\n",
2648 printf("child: released lock 0:4 on file %s.\n",
2654 static bool run_locktest9(int dummy
)
2656 struct cli_state
*cli1
;
2657 const char *fname
= "\\lockt9.lck";
2659 bool correct
= False
;
2660 int pipe_in
[2], pipe_out
[2];
2664 struct timeval start
;
2668 printf("starting locktest9\n");
2670 if (local_path
== NULL
) {
2671 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2675 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2680 if (child_pid
== -1) {
2684 if (child_pid
== 0) {
2686 do_local_lock(pipe_out
[0], pipe_in
[1]);
2696 ret
= read(pipe_in
[0], &c
, 1);
2698 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2703 if (!torture_open_connection(&cli1
, 0)) {
2707 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2709 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
,
2711 if (!NT_STATUS_IS_OK(status
)) {
2712 d_fprintf(stderr
, "cli_openx returned %s\n", nt_errstr(status
));
2716 /* Ensure the child has the lock. */
2717 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2718 if (NT_STATUS_IS_OK(status
)) {
2719 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2722 d_printf("Child has the lock.\n");
2725 /* Tell the child to wait 5 seconds then exit. */
2726 ret
= write(pipe_out
[1], &c
, 1);
2728 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2733 /* Wait 20 seconds for the lock. */
2735 CatchSignal(SIGALRM
, alarm_handler_parent
);
2738 start
= timeval_current();
2740 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2741 if (!NT_STATUS_IS_OK(status
)) {
2742 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2743 "%s\n", nt_errstr(status
));
2748 seconds
= timeval_elapsed(&start
);
2750 printf("Parent got the lock after %.2f seconds.\n",
2753 status
= cli_close(cli1
, fnum
);
2754 if (!NT_STATUS_IS_OK(status
)) {
2755 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2762 cli_close(cli1
, fnum
);
2763 torture_close_connection(cli1
);
2767 printf("finished locktest9\n");
2772 test whether fnums and tids open on one VC are available on another (a major
2775 static bool run_fdpasstest(int dummy
)
2777 struct cli_state
*cli1
, *cli2
;
2778 const char *fname
= "\\fdpass.tst";
2783 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2786 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
2787 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
2789 printf("starting fdpasstest\n");
2791 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2793 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2795 if (!NT_STATUS_IS_OK(status
)) {
2796 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2800 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2802 if (!NT_STATUS_IS_OK(status
)) {
2803 printf("write failed (%s)\n", nt_errstr(status
));
2807 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2808 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2809 cli_setpid(cli2
, cli_getpid(cli1
));
2811 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2812 printf("read succeeded! nasty security hole [%s]\n", buf
);
2816 cli_close(cli1
, fnum1
);
2817 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2819 torture_close_connection(cli1
);
2820 torture_close_connection(cli2
);
2822 printf("finished fdpasstest\n");
2826 static bool run_fdsesstest(int dummy
)
2828 struct cli_state
*cli
;
2833 const char *fname
= "\\fdsess.tst";
2834 const char *fname1
= "\\fdsess1.tst";
2841 if (!torture_open_connection(&cli
, 0))
2843 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2845 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2848 saved_cnum
= cli_state_get_tid(cli
);
2849 if (!NT_STATUS_IS_OK(cli_tree_connect(cli
, share
, "?????", "", 1)))
2851 new_cnum
= cli_state_get_tid(cli
);
2852 cli_state_set_tid(cli
, saved_cnum
);
2854 printf("starting fdsesstest\n");
2856 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2857 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2859 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2860 if (!NT_STATUS_IS_OK(status
)) {
2861 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2865 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2867 if (!NT_STATUS_IS_OK(status
)) {
2868 printf("write failed (%s)\n", nt_errstr(status
));
2872 saved_vuid
= cli_state_get_uid(cli
);
2873 cli_state_set_uid(cli
, new_vuid
);
2875 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2876 printf("read succeeded with different vuid! "
2877 "nasty security hole [%s]\n", buf
);
2880 /* Try to open a file with different vuid, samba cnum. */
2881 if (NT_STATUS_IS_OK(cli_openx(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2882 printf("create with different vuid, same cnum succeeded.\n");
2883 cli_close(cli
, fnum2
);
2884 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2886 printf("create with different vuid, same cnum failed.\n");
2887 printf("This will cause problems with service clients.\n");
2891 cli_state_set_uid(cli
, saved_vuid
);
2893 /* Try with same vuid, different cnum. */
2894 cli_state_set_tid(cli
, new_cnum
);
2896 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2897 printf("read succeeded with different cnum![%s]\n", buf
);
2901 cli_state_set_tid(cli
, saved_cnum
);
2902 cli_close(cli
, fnum1
);
2903 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2905 torture_close_connection(cli
);
2907 printf("finished fdsesstest\n");
2912 This test checks that
2914 1) the server does not allow an unlink on a file that is open
2916 static bool run_unlinktest(int dummy
)
2918 struct cli_state
*cli
;
2919 const char *fname
= "\\unlink.tst";
2921 bool correct
= True
;
2924 if (!torture_open_connection(&cli
, 0)) {
2928 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2930 printf("starting unlink test\n");
2932 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2936 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2937 if (!NT_STATUS_IS_OK(status
)) {
2938 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2942 status
= cli_unlink(cli
, fname
,
2943 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2944 if (NT_STATUS_IS_OK(status
)) {
2945 printf("error: server allowed unlink on an open file\n");
2948 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2949 NT_STATUS_SHARING_VIOLATION
);
2952 cli_close(cli
, fnum
);
2953 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2955 if (!torture_close_connection(cli
)) {
2959 printf("unlink test finished\n");
2966 test how many open files this server supports on the one socket
2968 static bool run_maxfidtest(int dummy
)
2970 struct cli_state
*cli
;
2972 uint16_t fnums
[0x11000];
2975 bool correct
= True
;
2981 printf("failed to connect\n");
2985 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
2987 for (i
=0; i
<0x11000; i
++) {
2988 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2989 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2991 if (!NT_STATUS_IS_OK(status
)) {
2992 printf("open of %s failed (%s)\n",
2993 fname
, nt_errstr(status
));
2994 printf("maximum fnum is %d\n", i
);
3002 printf("cleaning up\n");
3004 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
3005 cli_close(cli
, fnums
[i
]);
3007 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3008 if (!NT_STATUS_IS_OK(status
)) {
3009 printf("unlink of %s failed (%s)\n",
3010 fname
, nt_errstr(status
));
3017 printf("maxfid test finished\n");
3018 if (!torture_close_connection(cli
)) {
3024 /* generate a random buffer */
3025 static void rand_buf(char *buf
, int len
)
3028 *buf
= (char)sys_random();
3033 /* send smb negprot commands, not reading the response */
3034 static bool run_negprot_nowait(int dummy
)
3036 struct tevent_context
*ev
;
3038 struct cli_state
*cli
;
3039 bool correct
= True
;
3041 printf("starting negprot nowait test\n");
3043 ev
= tevent_context_init(talloc_tos());
3048 if (!(cli
= open_nbt_connection())) {
3053 for (i
=0;i
<50000;i
++) {
3054 struct tevent_req
*req
;
3056 req
= smbXcli_negprot_send(ev
, ev
, cli
->conn
, cli
->timeout
,
3057 PROTOCOL_CORE
, PROTOCOL_NT1
);
3062 if (!tevent_req_poll(req
, ev
)) {
3063 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3071 if (torture_close_connection(cli
)) {
3075 printf("finished negprot nowait test\n");
3080 /* send smb negprot commands, not reading the response */
3081 static bool run_bad_nbt_session(int dummy
)
3083 struct nmb_name called
, calling
;
3084 struct sockaddr_storage ss
;
3089 printf("starting bad nbt session test\n");
3091 make_nmb_name(&calling
, myname
, 0x0);
3092 make_nmb_name(&called
, host
, 0x20);
3094 if (!resolve_name(host
, &ss
, 0x20, true)) {
3095 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3099 status
= open_socket_out(&ss
, NBT_SMB_PORT
, 10000, &fd
);
3100 if (!NT_STATUS_IS_OK(status
)) {
3101 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3106 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3109 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3114 printf("finished bad nbt session test\n");
3118 /* send random IPC commands */
3119 static bool run_randomipc(int dummy
)
3121 char *rparam
= NULL
;
3123 unsigned int rdrcnt
,rprcnt
;
3125 int api
, param_len
, i
;
3126 struct cli_state
*cli
;
3127 bool correct
= True
;
3130 printf("starting random ipc test\n");
3132 if (!torture_open_connection(&cli
, 0)) {
3136 for (i
=0;i
<count
;i
++) {
3137 api
= sys_random() % 500;
3138 param_len
= (sys_random() % 64);
3140 rand_buf(param
, param_len
);
3145 param
, param_len
, 8,
3146 NULL
, 0, BUFFER_SIZE
,
3150 printf("%d/%d\r", i
,count
);
3153 printf("%d/%d\n", i
, count
);
3155 if (!torture_close_connection(cli
)) {
3159 printf("finished random ipc test\n");
3166 static void browse_callback(const char *sname
, uint32 stype
,
3167 const char *comment
, void *state
)
3169 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3175 This test checks the browse list code
3178 static bool run_browsetest(int dummy
)
3180 static struct cli_state
*cli
;
3181 bool correct
= True
;
3183 printf("starting browse test\n");
3185 if (!torture_open_connection(&cli
, 0)) {
3189 printf("domain list:\n");
3190 cli_NetServerEnum(cli
, cli
->server_domain
,
3191 SV_TYPE_DOMAIN_ENUM
,
3192 browse_callback
, NULL
);
3194 printf("machine list:\n");
3195 cli_NetServerEnum(cli
, cli
->server_domain
,
3197 browse_callback
, NULL
);
3199 if (!torture_close_connection(cli
)) {
3203 printf("browse test finished\n");
3211 This checks how the getatr calls works
3213 static bool run_attrtest(int dummy
)
3215 struct cli_state
*cli
;
3218 const char *fname
= "\\attrib123456789.tst";
3219 bool correct
= True
;
3222 printf("starting attrib test\n");
3224 if (!torture_open_connection(&cli
, 0)) {
3228 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3229 cli_openx(cli
, fname
,
3230 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3231 cli_close(cli
, fnum
);
3233 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3234 if (!NT_STATUS_IS_OK(status
)) {
3235 printf("getatr failed (%s)\n", nt_errstr(status
));
3239 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3240 printf("ERROR: SMBgetatr bug. time is %s",
3246 t2
= t
-60*60*24; /* 1 day ago */
3248 status
= cli_setatr(cli
, fname
, 0, t2
);
3249 if (!NT_STATUS_IS_OK(status
)) {
3250 printf("setatr failed (%s)\n", nt_errstr(status
));
3254 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3255 if (!NT_STATUS_IS_OK(status
)) {
3256 printf("getatr failed (%s)\n", nt_errstr(status
));
3261 printf("ERROR: getatr/setatr bug. times are\n%s",
3263 printf("%s", ctime(&t2
));
3267 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3269 if (!torture_close_connection(cli
)) {
3273 printf("attrib test finished\n");
3280 This checks a couple of trans2 calls
3282 static bool run_trans2test(int dummy
)
3284 struct cli_state
*cli
;
3287 time_t c_time
, a_time
, m_time
;
3288 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3289 const char *fname
= "\\trans2.tst";
3290 const char *dname
= "\\trans2";
3291 const char *fname2
= "\\trans2\\trans2.tst";
3293 bool correct
= True
;
3297 printf("starting trans2 test\n");
3299 if (!torture_open_connection(&cli
, 0)) {
3303 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3304 if (!NT_STATUS_IS_OK(status
)) {
3305 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3310 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3311 cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3312 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3313 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3314 if (!NT_STATUS_IS_OK(status
)) {
3315 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3319 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3320 if (!NT_STATUS_IS_OK(status
)) {
3321 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3325 if (strcmp(pname
, fname
)) {
3326 printf("qfilename gave different name? [%s] [%s]\n",
3331 cli_close(cli
, fnum
);
3335 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3336 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3338 if (!NT_STATUS_IS_OK(status
)) {
3339 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3342 cli_close(cli
, fnum
);
3344 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3346 if (!NT_STATUS_IS_OK(status
)) {
3347 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3350 time_t t
= time(NULL
);
3352 if (c_time
!= m_time
) {
3353 printf("create time=%s", ctime(&c_time
));
3354 printf("modify time=%s", ctime(&m_time
));
3355 printf("This system appears to have sticky create times\n");
3357 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3358 printf("access time=%s", ctime(&a_time
));
3359 printf("This system appears to set a midnight access time\n");
3363 if (abs(m_time
- t
) > 60*60*24*7) {
3364 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3370 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3371 cli_openx(cli
, fname
,
3372 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3373 cli_close(cli
, fnum
);
3374 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3375 &m_time_ts
, &size
, NULL
, NULL
);
3376 if (!NT_STATUS_IS_OK(status
)) {
3377 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3380 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3381 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3382 printf("This system appears to set a initial 0 write time\n");
3387 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3390 /* check if the server updates the directory modification time
3391 when creating a new file */
3392 status
= cli_mkdir(cli
, dname
);
3393 if (!NT_STATUS_IS_OK(status
)) {
3394 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3398 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3399 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3400 if (!NT_STATUS_IS_OK(status
)) {
3401 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3405 cli_openx(cli
, fname2
,
3406 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3407 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3408 cli_close(cli
, fnum
);
3409 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3410 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3411 if (!NT_STATUS_IS_OK(status
)) {
3412 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3415 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3417 printf("This system does not update directory modification times\n");
3421 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3422 cli_rmdir(cli
, dname
);
3424 if (!torture_close_connection(cli
)) {
3428 printf("trans2 test finished\n");
3434 This checks new W2K calls.
3437 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3439 uint8_t *buf
= NULL
;
3443 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3444 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3445 if (!NT_STATUS_IS_OK(status
)) {
3446 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3449 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3450 dump_data(0, (uint8
*)buf
, len
);
3457 static bool run_w2ktest(int dummy
)
3459 struct cli_state
*cli
;
3461 const char *fname
= "\\w2ktest\\w2k.tst";
3463 bool correct
= True
;
3465 printf("starting w2k test\n");
3467 if (!torture_open_connection(&cli
, 0)) {
3471 cli_openx(cli
, fname
,
3472 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3474 for (level
= 1004; level
< 1040; level
++) {
3475 new_trans(cli
, fnum
, level
);
3478 cli_close(cli
, fnum
);
3480 if (!torture_close_connection(cli
)) {
3484 printf("w2k test finished\n");
3491 this is a harness for some oplock tests
3493 static bool run_oplock1(int dummy
)
3495 struct cli_state
*cli1
;
3496 const char *fname
= "\\lockt1.lck";
3498 bool correct
= True
;
3501 printf("starting oplock test 1\n");
3503 if (!torture_open_connection(&cli1
, 0)) {
3507 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3509 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3511 cli1
->use_oplocks
= True
;
3513 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3515 if (!NT_STATUS_IS_OK(status
)) {
3516 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3520 cli1
->use_oplocks
= False
;
3522 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3523 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3525 status
= cli_close(cli1
, fnum1
);
3526 if (!NT_STATUS_IS_OK(status
)) {
3527 printf("close2 failed (%s)\n", nt_errstr(status
));
3531 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3532 if (!NT_STATUS_IS_OK(status
)) {
3533 printf("unlink failed (%s)\n", nt_errstr(status
));
3537 if (!torture_close_connection(cli1
)) {
3541 printf("finished oplock test 1\n");
3546 static bool run_oplock2(int dummy
)
3548 struct cli_state
*cli1
, *cli2
;
3549 const char *fname
= "\\lockt2.lck";
3550 uint16_t fnum1
, fnum2
;
3551 int saved_use_oplocks
= use_oplocks
;
3553 bool correct
= True
;
3554 volatile bool *shared_correct
;
3558 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3559 *shared_correct
= True
;
3561 use_level_II_oplocks
= True
;
3564 printf("starting oplock test 2\n");
3566 if (!torture_open_connection(&cli1
, 0)) {
3567 use_level_II_oplocks
= False
;
3568 use_oplocks
= saved_use_oplocks
;
3572 if (!torture_open_connection(&cli2
, 1)) {
3573 use_level_II_oplocks
= False
;
3574 use_oplocks
= saved_use_oplocks
;
3578 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3580 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3581 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3583 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3585 if (!NT_STATUS_IS_OK(status
)) {
3586 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3590 /* Don't need the globals any more. */
3591 use_level_II_oplocks
= False
;
3592 use_oplocks
= saved_use_oplocks
;
3596 status
= cli_openx(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3597 if (!NT_STATUS_IS_OK(status
)) {
3598 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3599 *shared_correct
= False
;
3605 status
= cli_close(cli2
, fnum2
);
3606 if (!NT_STATUS_IS_OK(status
)) {
3607 printf("close2 failed (%s)\n", nt_errstr(status
));
3608 *shared_correct
= False
;
3616 /* Ensure cli1 processes the break. Empty file should always return 0
3618 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3619 if (!NT_STATUS_IS_OK(status
)) {
3620 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3622 } else if (nread
!= 0) {
3623 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3624 (unsigned long)nread
, 0);
3628 /* Should now be at level II. */
3629 /* Test if sending a write locks causes a break to none. */
3630 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3631 if (!NT_STATUS_IS_OK(status
)) {
3632 printf("lock failed (%s)\n", nt_errstr(status
));
3636 cli_unlock(cli1
, fnum1
, 0, 4);
3640 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3641 if (!NT_STATUS_IS_OK(status
)) {
3642 printf("lock failed (%s)\n", nt_errstr(status
));
3646 cli_unlock(cli1
, fnum1
, 0, 4);
3650 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3652 status
= cli_close(cli1
, fnum1
);
3653 if (!NT_STATUS_IS_OK(status
)) {
3654 printf("close1 failed (%s)\n", nt_errstr(status
));
3660 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3661 if (!NT_STATUS_IS_OK(status
)) {
3662 printf("unlink failed (%s)\n", nt_errstr(status
));
3666 if (!torture_close_connection(cli1
)) {
3670 if (!*shared_correct
) {
3674 printf("finished oplock test 2\n");
3679 struct oplock4_state
{
3680 struct tevent_context
*ev
;
3681 struct cli_state
*cli
;
3686 static void oplock4_got_break(struct tevent_req
*req
);
3687 static void oplock4_got_open(struct tevent_req
*req
);
3689 static bool run_oplock4(int dummy
)
3691 struct tevent_context
*ev
;
3692 struct cli_state
*cli1
, *cli2
;
3693 struct tevent_req
*oplock_req
, *open_req
;
3694 const char *fname
= "\\lockt4.lck";
3695 const char *fname_ln
= "\\lockt4_ln.lck";
3696 uint16_t fnum1
, fnum2
;
3697 int saved_use_oplocks
= use_oplocks
;
3699 bool correct
= true;
3703 struct oplock4_state
*state
;
3705 printf("starting oplock test 4\n");
3707 if (!torture_open_connection(&cli1
, 0)) {
3708 use_level_II_oplocks
= false;
3709 use_oplocks
= saved_use_oplocks
;
3713 if (!torture_open_connection(&cli2
, 1)) {
3714 use_level_II_oplocks
= false;
3715 use_oplocks
= saved_use_oplocks
;
3719 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3720 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3722 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3723 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
3725 /* Create the file. */
3726 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3728 if (!NT_STATUS_IS_OK(status
)) {
3729 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3733 status
= cli_close(cli1
, fnum1
);
3734 if (!NT_STATUS_IS_OK(status
)) {
3735 printf("close1 failed (%s)\n", nt_errstr(status
));
3739 /* Now create a hardlink. */
3740 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3741 if (!NT_STATUS_IS_OK(status
)) {
3742 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3746 /* Prove that opening hardlinks cause deny modes to conflict. */
3747 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3748 if (!NT_STATUS_IS_OK(status
)) {
3749 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3753 status
= cli_openx(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3754 if (NT_STATUS_IS_OK(status
)) {
3755 printf("open of %s succeeded - should fail with sharing violation.\n",
3760 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3761 printf("open of %s should fail with sharing violation. Got %s\n",
3762 fname_ln
, nt_errstr(status
));
3766 status
= cli_close(cli1
, fnum1
);
3767 if (!NT_STATUS_IS_OK(status
)) {
3768 printf("close1 failed (%s)\n", nt_errstr(status
));
3772 cli1
->use_oplocks
= true;
3773 cli2
->use_oplocks
= true;
3775 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3776 if (!NT_STATUS_IS_OK(status
)) {
3777 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3781 ev
= tevent_context_init(talloc_tos());
3783 printf("tevent_context_init failed\n");
3787 state
= talloc(ev
, struct oplock4_state
);
3788 if (state
== NULL
) {
3789 printf("talloc failed\n");
3794 state
->got_break
= &got_break
;
3795 state
->fnum2
= &fnum2
;
3797 oplock_req
= cli_smb_oplock_break_waiter_send(
3798 talloc_tos(), ev
, cli1
);
3799 if (oplock_req
== NULL
) {
3800 printf("cli_smb_oplock_break_waiter_send failed\n");
3803 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3805 open_req
= cli_openx_send(
3806 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3807 if (open_req
== NULL
) {
3808 printf("cli_openx_send failed\n");
3811 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3816 while (!got_break
|| fnum2
== 0xffff) {
3818 ret
= tevent_loop_once(ev
);
3820 printf("tevent_loop_once failed: %s\n",
3826 status
= cli_close(cli2
, fnum2
);
3827 if (!NT_STATUS_IS_OK(status
)) {
3828 printf("close2 failed (%s)\n", nt_errstr(status
));
3832 status
= cli_close(cli1
, fnum1
);
3833 if (!NT_STATUS_IS_OK(status
)) {
3834 printf("close1 failed (%s)\n", nt_errstr(status
));
3838 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3839 if (!NT_STATUS_IS_OK(status
)) {
3840 printf("unlink failed (%s)\n", nt_errstr(status
));
3844 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3845 if (!NT_STATUS_IS_OK(status
)) {
3846 printf("unlink failed (%s)\n", nt_errstr(status
));
3850 if (!torture_close_connection(cli1
)) {
3858 printf("finished oplock test 4\n");
3863 static void oplock4_got_break(struct tevent_req
*req
)
3865 struct oplock4_state
*state
= tevent_req_callback_data(
3866 req
, struct oplock4_state
);
3871 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3873 if (!NT_STATUS_IS_OK(status
)) {
3874 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3878 *state
->got_break
= true;
3880 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3883 printf("cli_oplock_ack_send failed\n");
3888 static void oplock4_got_open(struct tevent_req
*req
)
3890 struct oplock4_state
*state
= tevent_req_callback_data(
3891 req
, struct oplock4_state
);
3894 status
= cli_openx_recv(req
, state
->fnum2
);
3895 if (!NT_STATUS_IS_OK(status
)) {
3896 printf("cli_openx_recv returned %s\n", nt_errstr(status
));
3897 *state
->fnum2
= 0xffff;
3902 Test delete on close semantics.
3904 static bool run_deletetest(int dummy
)
3906 struct cli_state
*cli1
= NULL
;
3907 struct cli_state
*cli2
= NULL
;
3908 const char *fname
= "\\delete.file";
3909 uint16_t fnum1
= (uint16_t)-1;
3910 uint16_t fnum2
= (uint16_t)-1;
3911 bool correct
= True
;
3914 printf("starting delete test\n");
3916 if (!torture_open_connection(&cli1
, 0)) {
3920 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
3922 /* Test 1 - this should delete the file on close. */
3924 cli_setatr(cli1
, fname
, 0, 0);
3925 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3927 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3928 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3929 FILE_DELETE_ON_CLOSE
, 0, &fnum1
);
3930 if (!NT_STATUS_IS_OK(status
)) {
3931 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3936 status
= cli_close(cli1
, fnum1
);
3937 if (!NT_STATUS_IS_OK(status
)) {
3938 printf("[1] close failed (%s)\n", nt_errstr(status
));
3943 if (NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3944 printf("[1] open of %s succeeded (should fail)\n", fname
);
3949 printf("first delete on close test succeeded.\n");
3951 /* Test 2 - this should delete the file on close. */
3953 cli_setatr(cli1
, fname
, 0, 0);
3954 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3956 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3957 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3958 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3959 if (!NT_STATUS_IS_OK(status
)) {
3960 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3965 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3966 if (!NT_STATUS_IS_OK(status
)) {
3967 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3972 status
= cli_close(cli1
, fnum1
);
3973 if (!NT_STATUS_IS_OK(status
)) {
3974 printf("[2] close failed (%s)\n", nt_errstr(status
));
3979 if (NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3980 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3981 status
= cli_close(cli1
, fnum1
);
3982 if (!NT_STATUS_IS_OK(status
)) {
3983 printf("[2] close failed (%s)\n", nt_errstr(status
));
3987 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3989 printf("second delete on close test succeeded.\n");
3992 cli_setatr(cli1
, fname
, 0, 0);
3993 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3995 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3996 FILE_ATTRIBUTE_NORMAL
,
3997 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3998 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3999 if (!NT_STATUS_IS_OK(status
)) {
4000 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4005 /* This should fail with a sharing violation - open for delete is only compatible
4006 with SHARE_DELETE. */
4008 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4009 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
4010 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4015 /* This should succeed. */
4016 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4017 FILE_ATTRIBUTE_NORMAL
,
4018 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4019 FILE_OPEN
, 0, 0, &fnum2
);
4020 if (!NT_STATUS_IS_OK(status
)) {
4021 printf("[3] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4026 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4027 if (!NT_STATUS_IS_OK(status
)) {
4028 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4033 status
= cli_close(cli1
, fnum1
);
4034 if (!NT_STATUS_IS_OK(status
)) {
4035 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
4040 status
= cli_close(cli1
, fnum2
);
4041 if (!NT_STATUS_IS_OK(status
)) {
4042 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
4047 /* This should fail - file should no longer be there. */
4049 if (NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4050 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4051 status
= cli_close(cli1
, fnum1
);
4052 if (!NT_STATUS_IS_OK(status
)) {
4053 printf("[3] close failed (%s)\n", nt_errstr(status
));
4055 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4059 printf("third delete on close test succeeded.\n");
4062 cli_setatr(cli1
, fname
, 0, 0);
4063 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4065 status
= cli_ntcreate(cli1
, fname
, 0,
4066 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4067 FILE_ATTRIBUTE_NORMAL
,
4068 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4069 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4070 if (!NT_STATUS_IS_OK(status
)) {
4071 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4076 /* This should succeed. */
4077 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4078 FILE_ATTRIBUTE_NORMAL
,
4079 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4080 FILE_OPEN
, 0, 0, &fnum2
);
4081 if (!NT_STATUS_IS_OK(status
)) {
4082 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4087 status
= cli_close(cli1
, fnum2
);
4088 if (!NT_STATUS_IS_OK(status
)) {
4089 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4094 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4095 if (!NT_STATUS_IS_OK(status
)) {
4096 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4101 /* This should fail - no more opens once delete on close set. */
4102 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4103 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4104 FILE_OPEN
, 0, 0, &fnum2
))) {
4105 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4109 printf("fourth delete on close test succeeded.\n");
4111 status
= cli_close(cli1
, fnum1
);
4112 if (!NT_STATUS_IS_OK(status
)) {
4113 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4119 cli_setatr(cli1
, fname
, 0, 0);
4120 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4122 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4123 if (!NT_STATUS_IS_OK(status
)) {
4124 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4129 /* This should fail - only allowed on NT opens with DELETE access. */
4131 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4132 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4137 status
= cli_close(cli1
, fnum1
);
4138 if (!NT_STATUS_IS_OK(status
)) {
4139 printf("[5] close - 2 failed (%s)\n", nt_errstr(status
));
4144 printf("fifth delete on close test succeeded.\n");
4147 cli_setatr(cli1
, fname
, 0, 0);
4148 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4150 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4151 FILE_ATTRIBUTE_NORMAL
,
4152 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4153 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4154 if (!NT_STATUS_IS_OK(status
)) {
4155 printf("[6] open of %s failed (%s)\n", fname
,
4161 /* This should fail - only allowed on NT opens with DELETE access. */
4163 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4164 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4169 status
= cli_close(cli1
, fnum1
);
4170 if (!NT_STATUS_IS_OK(status
)) {
4171 printf("[6] close - 2 failed (%s)\n", nt_errstr(status
));
4176 printf("sixth delete on close test succeeded.\n");
4179 cli_setatr(cli1
, fname
, 0, 0);
4180 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4182 status
= cli_ntcreate(cli1
, fname
, 0,
4183 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4184 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4186 if (!NT_STATUS_IS_OK(status
)) {
4187 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4192 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4193 printf("[7] setting delete_on_close on file failed !\n");
4198 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
4199 printf("[7] unsetting delete_on_close on file failed !\n");
4204 status
= cli_close(cli1
, fnum1
);
4205 if (!NT_STATUS_IS_OK(status
)) {
4206 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4211 /* This next open should succeed - we reset the flag. */
4212 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4213 if (!NT_STATUS_IS_OK(status
)) {
4214 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4219 status
= cli_close(cli1
, fnum1
);
4220 if (!NT_STATUS_IS_OK(status
)) {
4221 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4226 printf("seventh delete on close test succeeded.\n");
4229 cli_setatr(cli1
, fname
, 0, 0);
4230 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4232 if (!torture_open_connection(&cli2
, 1)) {
4233 printf("[8] failed to open second connection.\n");
4238 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4240 status
= cli_ntcreate(cli1
, fname
, 0,
4241 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4242 FILE_ATTRIBUTE_NORMAL
,
4243 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4244 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4245 if (!NT_STATUS_IS_OK(status
)) {
4246 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4251 status
= cli_ntcreate(cli2
, fname
, 0,
4252 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4253 FILE_ATTRIBUTE_NORMAL
,
4254 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4255 FILE_OPEN
, 0, 0, &fnum2
);
4256 if (!NT_STATUS_IS_OK(status
)) {
4257 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4262 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4263 printf("[8] setting delete_on_close on file failed !\n");
4268 status
= cli_close(cli1
, fnum1
);
4269 if (!NT_STATUS_IS_OK(status
)) {
4270 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4275 status
= cli_close(cli2
, fnum2
);
4276 if (!NT_STATUS_IS_OK(status
)) {
4277 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4282 /* This should fail.. */
4283 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4284 if (NT_STATUS_IS_OK(status
)) {
4285 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4289 printf("eighth delete on close test succeeded.\n");
4291 /* This should fail - we need to set DELETE_ACCESS. */
4292 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
4293 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
4294 printf("[9] open of %s succeeded should have failed!\n", fname
);
4299 printf("ninth delete on close test succeeded.\n");
4301 status
= cli_ntcreate(cli1
, fname
, 0,
4302 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4303 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4304 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4306 if (!NT_STATUS_IS_OK(status
)) {
4307 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4312 /* This should delete the file. */
4313 status
= cli_close(cli1
, fnum1
);
4314 if (!NT_STATUS_IS_OK(status
)) {
4315 printf("[10] close failed (%s)\n", nt_errstr(status
));
4320 /* This should fail.. */
4321 if (NT_STATUS_IS_OK(cli_openx(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4322 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4326 printf("tenth delete on close test succeeded.\n");
4328 cli_setatr(cli1
, fname
, 0, 0);
4329 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4331 /* What error do we get when attempting to open a read-only file with
4334 /* Create a readonly file. */
4335 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4336 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4337 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4338 if (!NT_STATUS_IS_OK(status
)) {
4339 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4344 status
= cli_close(cli1
, fnum1
);
4345 if (!NT_STATUS_IS_OK(status
)) {
4346 printf("[11] close failed (%s)\n", nt_errstr(status
));
4351 /* Now try open for delete access. */
4352 status
= cli_ntcreate(cli1
, fname
, 0,
4353 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4355 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4356 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4357 if (NT_STATUS_IS_OK(status
)) {
4358 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
4359 cli_close(cli1
, fnum1
);
4363 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4364 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(status
));
4368 printf("eleventh delete on close test succeeded.\n");
4372 printf("finished delete test\n");
4375 /* FIXME: This will crash if we aborted before cli2 got
4376 * intialized, because these functions don't handle
4377 * uninitialized connections. */
4379 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4380 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4381 cli_setatr(cli1
, fname
, 0, 0);
4382 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4384 if (cli1
&& !torture_close_connection(cli1
)) {
4387 if (cli2
&& !torture_close_connection(cli2
)) {
4393 static bool run_deletetest_ln(int dummy
)
4395 struct cli_state
*cli
;
4396 const char *fname
= "\\delete1";
4397 const char *fname_ln
= "\\delete1_ln";
4401 bool correct
= true;
4404 printf("starting deletetest-ln\n");
4406 if (!torture_open_connection(&cli
, 0)) {
4410 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4411 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4413 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4415 /* Create the file. */
4416 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4417 if (!NT_STATUS_IS_OK(status
)) {
4418 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4422 status
= cli_close(cli
, fnum
);
4423 if (!NT_STATUS_IS_OK(status
)) {
4424 printf("close1 failed (%s)\n", nt_errstr(status
));
4428 /* Now create a hardlink. */
4429 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4430 if (!NT_STATUS_IS_OK(status
)) {
4431 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4435 /* Open the original file. */
4436 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4437 FILE_ATTRIBUTE_NORMAL
,
4438 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4439 FILE_OPEN_IF
, 0, 0, &fnum
);
4440 if (!NT_STATUS_IS_OK(status
)) {
4441 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4445 /* Unlink the hard link path. */
4446 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4447 FILE_ATTRIBUTE_NORMAL
,
4448 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4449 FILE_OPEN_IF
, 0, 0, &fnum1
);
4450 if (!NT_STATUS_IS_OK(status
)) {
4451 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4454 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4455 if (!NT_STATUS_IS_OK(status
)) {
4456 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4457 __location__
, fname_ln
, nt_errstr(status
));
4461 status
= cli_close(cli
, fnum1
);
4462 if (!NT_STATUS_IS_OK(status
)) {
4463 printf("close %s failed (%s)\n",
4464 fname_ln
, nt_errstr(status
));
4468 status
= cli_close(cli
, fnum
);
4469 if (!NT_STATUS_IS_OK(status
)) {
4470 printf("close %s failed (%s)\n",
4471 fname
, nt_errstr(status
));
4475 /* Ensure the original file is still there. */
4476 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4477 if (!NT_STATUS_IS_OK(status
)) {
4478 printf("%s getatr on file %s failed (%s)\n",
4485 /* Ensure the link path is gone. */
4486 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4487 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4488 printf("%s, getatr for file %s returned wrong error code %s "
4489 "- should have been deleted\n",
4491 fname_ln
, nt_errstr(status
));
4495 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4496 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4498 if (!torture_close_connection(cli
)) {
4502 printf("finished deletetest-ln\n");
4508 print out server properties
4510 static bool run_properties(int dummy
)
4512 struct cli_state
*cli
;
4513 bool correct
= True
;
4515 printf("starting properties test\n");
4519 if (!torture_open_connection(&cli
, 0)) {
4523 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
4525 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli
->conn
));
4527 if (!torture_close_connection(cli
)) {
4536 /* FIRST_DESIRED_ACCESS 0xf019f */
4537 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4538 FILE_READ_EA| /* 0xf */ \
4539 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4540 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4541 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4542 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4543 /* SECOND_DESIRED_ACCESS 0xe0080 */
4544 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4545 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4546 WRITE_OWNER_ACCESS /* 0xe0000 */
4549 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4550 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4552 WRITE_OWNER_ACCESS /* */
4556 Test ntcreate calls made by xcopy
4558 static bool run_xcopy(int dummy
)
4560 static struct cli_state
*cli1
;
4561 const char *fname
= "\\test.txt";
4562 bool correct
= True
;
4563 uint16_t fnum1
, fnum2
;
4566 printf("starting xcopy test\n");
4568 if (!torture_open_connection(&cli1
, 0)) {
4572 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4573 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4574 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
);
4575 if (!NT_STATUS_IS_OK(status
)) {
4576 printf("First open failed - %s\n", nt_errstr(status
));
4580 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4581 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4582 FILE_OPEN
, 0x200000, 0, &fnum2
);
4583 if (!NT_STATUS_IS_OK(status
)) {
4584 printf("second open failed - %s\n", nt_errstr(status
));
4588 if (!torture_close_connection(cli1
)) {
4596 Test rename on files open with share delete and no share delete.
4598 static bool run_rename(int dummy
)
4600 static struct cli_state
*cli1
;
4601 const char *fname
= "\\test.txt";
4602 const char *fname1
= "\\test1.txt";
4603 bool correct
= True
;
4608 printf("starting rename test\n");
4610 if (!torture_open_connection(&cli1
, 0)) {
4614 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4615 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4617 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4618 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4619 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4620 if (!NT_STATUS_IS_OK(status
)) {
4621 printf("First open failed - %s\n", nt_errstr(status
));
4625 status
= cli_rename(cli1
, fname
, fname1
);
4626 if (!NT_STATUS_IS_OK(status
)) {
4627 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4629 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4633 status
= cli_close(cli1
, fnum1
);
4634 if (!NT_STATUS_IS_OK(status
)) {
4635 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4639 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4640 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4641 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4643 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4645 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4647 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4648 if (!NT_STATUS_IS_OK(status
)) {
4649 printf("Second open failed - %s\n", nt_errstr(status
));
4653 status
= cli_rename(cli1
, fname
, fname1
);
4654 if (!NT_STATUS_IS_OK(status
)) {
4655 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4658 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4661 status
= cli_close(cli1
, fnum1
);
4662 if (!NT_STATUS_IS_OK(status
)) {
4663 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4667 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4668 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4670 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4671 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4672 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4673 if (!NT_STATUS_IS_OK(status
)) {
4674 printf("Third open failed - %s\n", nt_errstr(status
));
4683 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4684 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4685 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4688 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4689 printf("[8] setting delete_on_close on file failed !\n");
4693 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4694 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4700 status
= cli_rename(cli1
, fname
, fname1
);
4701 if (!NT_STATUS_IS_OK(status
)) {
4702 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4705 printf("Third rename succeeded (SHARE_NONE)\n");
4708 status
= cli_close(cli1
, fnum1
);
4709 if (!NT_STATUS_IS_OK(status
)) {
4710 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4714 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4715 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4719 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4720 FILE_ATTRIBUTE_NORMAL
,
4721 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4722 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4723 if (!NT_STATUS_IS_OK(status
)) {
4724 printf("Fourth open failed - %s\n", nt_errstr(status
));
4728 status
= cli_rename(cli1
, fname
, fname1
);
4729 if (!NT_STATUS_IS_OK(status
)) {
4730 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4732 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4736 status
= cli_close(cli1
, fnum1
);
4737 if (!NT_STATUS_IS_OK(status
)) {
4738 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4742 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4743 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4747 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4748 FILE_ATTRIBUTE_NORMAL
,
4749 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4750 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4751 if (!NT_STATUS_IS_OK(status
)) {
4752 printf("Fifth open failed - %s\n", nt_errstr(status
));
4756 status
= cli_rename(cli1
, fname
, fname1
);
4757 if (!NT_STATUS_IS_OK(status
)) {
4758 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4761 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4765 * Now check if the first name still exists ...
4768 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4769 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4770 printf("Opening original file after rename of open file fails: %s\n",
4774 printf("Opening original file after rename of open file works ...\n");
4775 (void)cli_close(cli1, fnum2);
4779 status
= cli_close(cli1
, fnum1
);
4780 if (!NT_STATUS_IS_OK(status
)) {
4781 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4785 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4786 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4787 if (!NT_STATUS_IS_OK(status
)) {
4788 printf("getatr on file %s failed - %s ! \n",
4789 fname1
, nt_errstr(status
));
4792 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4793 printf("Renamed file %s has wrong attr 0x%x "
4794 "(should be 0x%x)\n",
4797 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4800 printf("Renamed file %s has archive bit set\n", fname1
);
4804 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4805 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4807 if (!torture_close_connection(cli1
)) {
4814 static bool run_pipe_number(int dummy
)
4816 struct cli_state
*cli1
;
4817 const char *pipe_name
= "\\SPOOLSS";
4822 printf("starting pipenumber test\n");
4823 if (!torture_open_connection(&cli1
, 0)) {
4827 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4829 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4830 FILE_ATTRIBUTE_NORMAL
,
4831 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4832 FILE_OPEN_IF
, 0, 0, &fnum
);
4833 if (!NT_STATUS_IS_OK(status
)) {
4834 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4838 printf("\r%6d", num_pipes
);
4841 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4842 torture_close_connection(cli1
);
4847 Test open mode returns on read-only files.
4849 static bool run_opentest(int dummy
)
4851 static struct cli_state
*cli1
;
4852 static struct cli_state
*cli2
;
4853 const char *fname
= "\\readonly.file";
4854 uint16_t fnum1
, fnum2
;
4857 bool correct
= True
;
4861 printf("starting open test\n");
4863 if (!torture_open_connection(&cli1
, 0)) {
4867 cli_setatr(cli1
, fname
, 0, 0);
4868 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4870 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
4872 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4873 if (!NT_STATUS_IS_OK(status
)) {
4874 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4878 status
= cli_close(cli1
, fnum1
);
4879 if (!NT_STATUS_IS_OK(status
)) {
4880 printf("close2 failed (%s)\n", nt_errstr(status
));
4884 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4885 if (!NT_STATUS_IS_OK(status
)) {
4886 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4890 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4891 if (!NT_STATUS_IS_OK(status
)) {
4892 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4896 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4897 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4899 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
4900 NT_STATUS_ACCESS_DENIED
)) {
4901 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4904 printf("finished open test 1\n");
4906 cli_close(cli1
, fnum1
);
4908 /* Now try not readonly and ensure ERRbadshare is returned. */
4910 cli_setatr(cli1
, fname
, 0, 0);
4912 status
= cli_openx(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4913 if (!NT_STATUS_IS_OK(status
)) {
4914 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4918 /* This will fail - but the error should be ERRshare. */
4919 status
= cli_openx(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4921 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
4922 NT_STATUS_SHARING_VIOLATION
)) {
4923 printf("correct error code ERRDOS/ERRbadshare returned\n");
4926 status
= cli_close(cli1
, fnum1
);
4927 if (!NT_STATUS_IS_OK(status
)) {
4928 printf("close2 failed (%s)\n", nt_errstr(status
));
4932 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4934 printf("finished open test 2\n");
4936 /* Test truncate open disposition on file opened for read. */
4937 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4938 if (!NT_STATUS_IS_OK(status
)) {
4939 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
4943 /* write 20 bytes. */
4945 memset(buf
, '\0', 20);
4947 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4948 if (!NT_STATUS_IS_OK(status
)) {
4949 printf("write failed (%s)\n", nt_errstr(status
));
4953 status
= cli_close(cli1
, fnum1
);
4954 if (!NT_STATUS_IS_OK(status
)) {
4955 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
4959 /* Ensure size == 20. */
4960 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4961 if (!NT_STATUS_IS_OK(status
)) {
4962 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4967 printf("(3) file size != 20\n");
4971 /* Now test if we can truncate a file opened for readonly. */
4972 status
= cli_openx(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
4973 if (!NT_STATUS_IS_OK(status
)) {
4974 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
4978 status
= cli_close(cli1
, fnum1
);
4979 if (!NT_STATUS_IS_OK(status
)) {
4980 printf("close2 failed (%s)\n", nt_errstr(status
));
4984 /* Ensure size == 0. */
4985 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4986 if (!NT_STATUS_IS_OK(status
)) {
4987 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4992 printf("(3) file size != 0\n");
4995 printf("finished open test 3\n");
4997 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4999 printf("Do ctemp tests\n");
5000 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
5001 if (!NT_STATUS_IS_OK(status
)) {
5002 printf("ctemp failed (%s)\n", nt_errstr(status
));
5006 printf("ctemp gave path %s\n", tmp_path
);
5007 status
= cli_close(cli1
, fnum1
);
5008 if (!NT_STATUS_IS_OK(status
)) {
5009 printf("close of temp failed (%s)\n", nt_errstr(status
));
5012 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5013 if (!NT_STATUS_IS_OK(status
)) {
5014 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5017 /* Test the non-io opens... */
5019 if (!torture_open_connection(&cli2
, 1)) {
5023 cli_setatr(cli2
, fname
, 0, 0);
5024 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5026 smbXcli_conn_set_sockopt(cli2
->conn
, sockops
);
5028 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5029 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5030 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5031 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5032 if (!NT_STATUS_IS_OK(status
)) {
5033 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5037 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5038 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5039 FILE_OPEN_IF
, 0, 0, &fnum2
);
5040 if (!NT_STATUS_IS_OK(status
)) {
5041 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5045 status
= cli_close(cli1
, fnum1
);
5046 if (!NT_STATUS_IS_OK(status
)) {
5047 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5051 status
= cli_close(cli2
, fnum2
);
5052 if (!NT_STATUS_IS_OK(status
)) {
5053 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5057 printf("non-io open test #1 passed.\n");
5059 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5061 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5063 status
= cli_ntcreate(cli1
, fname
, 0,
5064 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5065 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5066 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5067 if (!NT_STATUS_IS_OK(status
)) {
5068 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5072 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5073 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5074 FILE_OPEN_IF
, 0, 0, &fnum2
);
5075 if (!NT_STATUS_IS_OK(status
)) {
5076 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5080 status
= cli_close(cli1
, fnum1
);
5081 if (!NT_STATUS_IS_OK(status
)) {
5082 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5086 status
= cli_close(cli2
, fnum2
);
5087 if (!NT_STATUS_IS_OK(status
)) {
5088 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5092 printf("non-io open test #2 passed.\n");
5094 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5096 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5098 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5099 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5100 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5101 if (!NT_STATUS_IS_OK(status
)) {
5102 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5106 status
= cli_ntcreate(cli2
, fname
, 0,
5107 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5108 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5109 FILE_OPEN_IF
, 0, 0, &fnum2
);
5110 if (!NT_STATUS_IS_OK(status
)) {
5111 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5115 status
= cli_close(cli1
, fnum1
);
5116 if (!NT_STATUS_IS_OK(status
)) {
5117 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5121 status
= cli_close(cli2
, fnum2
);
5122 if (!NT_STATUS_IS_OK(status
)) {
5123 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5127 printf("non-io open test #3 passed.\n");
5129 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5131 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5133 status
= cli_ntcreate(cli1
, fname
, 0,
5134 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5135 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5136 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5137 if (!NT_STATUS_IS_OK(status
)) {
5138 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5142 status
= cli_ntcreate(cli2
, fname
, 0,
5143 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5144 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5145 FILE_OPEN_IF
, 0, 0, &fnum2
);
5146 if (NT_STATUS_IS_OK(status
)) {
5147 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5151 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5153 status
= cli_close(cli1
, fnum1
);
5154 if (!NT_STATUS_IS_OK(status
)) {
5155 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5159 printf("non-io open test #4 passed.\n");
5161 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5163 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5165 status
= cli_ntcreate(cli1
, fname
, 0,
5166 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5167 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5168 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5169 if (!NT_STATUS_IS_OK(status
)) {
5170 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5174 status
= cli_ntcreate(cli2
, fname
, 0,
5175 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5176 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5177 FILE_OPEN_IF
, 0, 0, &fnum2
);
5178 if (!NT_STATUS_IS_OK(status
)) {
5179 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5183 status
= cli_close(cli1
, fnum1
);
5184 if (!NT_STATUS_IS_OK(status
)) {
5185 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5189 status
= cli_close(cli2
, fnum2
);
5190 if (!NT_STATUS_IS_OK(status
)) {
5191 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5195 printf("non-io open test #5 passed.\n");
5197 printf("TEST #6 testing 1 non-io open, one io open\n");
5199 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5201 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5202 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5203 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5204 if (!NT_STATUS_IS_OK(status
)) {
5205 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5209 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5210 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5211 FILE_OPEN_IF
, 0, 0, &fnum2
);
5212 if (!NT_STATUS_IS_OK(status
)) {
5213 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5217 status
= cli_close(cli1
, fnum1
);
5218 if (!NT_STATUS_IS_OK(status
)) {
5219 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5223 status
= cli_close(cli2
, fnum2
);
5224 if (!NT_STATUS_IS_OK(status
)) {
5225 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5229 printf("non-io open test #6 passed.\n");
5231 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5233 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5235 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5236 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5237 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5238 if (!NT_STATUS_IS_OK(status
)) {
5239 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5243 status
= cli_ntcreate(cli2
, fname
, 0,
5244 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5245 FILE_ATTRIBUTE_NORMAL
,
5246 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5247 FILE_OPEN_IF
, 0, 0, &fnum2
);
5248 if (NT_STATUS_IS_OK(status
)) {
5249 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5253 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5255 status
= cli_close(cli1
, fnum1
);
5256 if (!NT_STATUS_IS_OK(status
)) {
5257 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5261 printf("non-io open test #7 passed.\n");
5263 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5265 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5266 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5267 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5268 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5269 if (!NT_STATUS_IS_OK(status
)) {
5270 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5275 /* Write to ensure we have to update the file time. */
5276 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5278 if (!NT_STATUS_IS_OK(status
)) {
5279 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5284 status
= cli_close(cli1
, fnum1
);
5285 if (!NT_STATUS_IS_OK(status
)) {
5286 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5292 if (!torture_close_connection(cli1
)) {
5295 if (!torture_close_connection(cli2
)) {
5302 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5304 uint16 major
, minor
;
5305 uint32 caplow
, caphigh
;
5308 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5309 printf("Server doesn't support UNIX CIFS extensions.\n");
5310 return NT_STATUS_NOT_SUPPORTED
;
5313 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5315 if (!NT_STATUS_IS_OK(status
)) {
5316 printf("Server didn't return UNIX CIFS extensions: %s\n",
5321 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5323 if (!NT_STATUS_IS_OK(status
)) {
5324 printf("Server doesn't support setting UNIX CIFS extensions: "
5325 "%s.\n", nt_errstr(status
));
5329 return NT_STATUS_OK
;
5333 Test POSIX open /mkdir calls.
5335 static bool run_simple_posix_open_test(int dummy
)
5337 static struct cli_state
*cli1
;
5338 const char *fname
= "posix:file";
5339 const char *hname
= "posix:hlink";
5340 const char *sname
= "posix:symlink";
5341 const char *dname
= "posix:dir";
5344 uint16_t fnum1
= (uint16_t)-1;
5345 SMB_STRUCT_STAT sbuf
;
5346 bool correct
= false;
5350 printf("Starting simple POSIX open test\n");
5352 if (!torture_open_connection(&cli1
, 0)) {
5356 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5358 status
= torture_setup_unix_extensions(cli1
);
5359 if (!NT_STATUS_IS_OK(status
)) {
5363 cli_setatr(cli1
, fname
, 0, 0);
5364 cli_posix_unlink(cli1
, fname
);
5365 cli_setatr(cli1
, dname
, 0, 0);
5366 cli_posix_rmdir(cli1
, dname
);
5367 cli_setatr(cli1
, hname
, 0, 0);
5368 cli_posix_unlink(cli1
, hname
);
5369 cli_setatr(cli1
, sname
, 0, 0);
5370 cli_posix_unlink(cli1
, sname
);
5372 /* Create a directory. */
5373 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5374 if (!NT_STATUS_IS_OK(status
)) {
5375 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5379 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5381 if (!NT_STATUS_IS_OK(status
)) {
5382 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5386 /* Test ftruncate - set file size. */
5387 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5388 if (!NT_STATUS_IS_OK(status
)) {
5389 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5393 /* Ensure st_size == 1000 */
5394 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5395 if (!NT_STATUS_IS_OK(status
)) {
5396 printf("stat failed (%s)\n", nt_errstr(status
));
5400 if (sbuf
.st_ex_size
!= 1000) {
5401 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5405 /* Ensure st_mode == 0600 */
5406 if ((sbuf
.st_ex_mode
& 07777) != 0600) {
5407 printf("posix_open - bad permissions 0%o != 0600\n",
5408 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5412 /* Test ftruncate - set file size back to zero. */
5413 status
= cli_ftruncate(cli1
, fnum1
, 0);
5414 if (!NT_STATUS_IS_OK(status
)) {
5415 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5419 status
= cli_close(cli1
, fnum1
);
5420 if (!NT_STATUS_IS_OK(status
)) {
5421 printf("close failed (%s)\n", nt_errstr(status
));
5425 /* Now open the file again for read only. */
5426 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5427 if (!NT_STATUS_IS_OK(status
)) {
5428 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5432 /* Now unlink while open. */
5433 status
= cli_posix_unlink(cli1
, fname
);
5434 if (!NT_STATUS_IS_OK(status
)) {
5435 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5439 status
= cli_close(cli1
, fnum1
);
5440 if (!NT_STATUS_IS_OK(status
)) {
5441 printf("close(2) failed (%s)\n", nt_errstr(status
));
5445 /* Ensure the file has gone. */
5446 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5447 if (NT_STATUS_IS_OK(status
)) {
5448 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5452 /* Create again to test open with O_TRUNC. */
5453 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5454 if (!NT_STATUS_IS_OK(status
)) {
5455 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5459 /* Test ftruncate - set file size. */
5460 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5461 if (!NT_STATUS_IS_OK(status
)) {
5462 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5466 /* Ensure st_size == 1000 */
5467 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5468 if (!NT_STATUS_IS_OK(status
)) {
5469 printf("stat failed (%s)\n", nt_errstr(status
));
5473 if (sbuf
.st_ex_size
!= 1000) {
5474 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5478 status
= cli_close(cli1
, fnum1
);
5479 if (!NT_STATUS_IS_OK(status
)) {
5480 printf("close(2) failed (%s)\n", nt_errstr(status
));
5484 /* Re-open with O_TRUNC. */
5485 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5486 if (!NT_STATUS_IS_OK(status
)) {
5487 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5491 /* Ensure st_size == 0 */
5492 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5493 if (!NT_STATUS_IS_OK(status
)) {
5494 printf("stat failed (%s)\n", nt_errstr(status
));
5498 if (sbuf
.st_ex_size
!= 0) {
5499 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5503 status
= cli_close(cli1
, fnum1
);
5504 if (!NT_STATUS_IS_OK(status
)) {
5505 printf("close failed (%s)\n", nt_errstr(status
));
5509 status
= cli_posix_unlink(cli1
, fname
);
5510 if (!NT_STATUS_IS_OK(status
)) {
5511 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5515 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5516 if (!NT_STATUS_IS_OK(status
)) {
5517 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5518 dname
, nt_errstr(status
));
5522 cli_close(cli1
, fnum1
);
5524 /* What happens when we try and POSIX open a directory for write ? */
5525 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5526 if (NT_STATUS_IS_OK(status
)) {
5527 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5530 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5531 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5536 /* Create the file. */
5537 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5539 if (!NT_STATUS_IS_OK(status
)) {
5540 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5544 /* Write some data into it. */
5545 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5547 if (!NT_STATUS_IS_OK(status
)) {
5548 printf("cli_write failed: %s\n", nt_errstr(status
));
5552 cli_close(cli1
, fnum1
);
5554 /* Now create a hardlink. */
5555 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5556 if (!NT_STATUS_IS_OK(status
)) {
5557 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5561 /* Now create a symlink. */
5562 status
= cli_posix_symlink(cli1
, fname
, sname
);
5563 if (!NT_STATUS_IS_OK(status
)) {
5564 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5568 /* Open the hardlink for read. */
5569 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5570 if (!NT_STATUS_IS_OK(status
)) {
5571 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5575 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5576 if (!NT_STATUS_IS_OK(status
)) {
5577 printf("POSIX read of %s failed (%s)\n", hname
,
5580 } else if (nread
!= 10) {
5581 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5582 hname
, (unsigned long)nread
, 10);
5586 if (memcmp(buf
, "TEST DATA\n", 10)) {
5587 printf("invalid data read from hardlink\n");
5591 /* Do a POSIX lock/unlock. */
5592 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5593 if (!NT_STATUS_IS_OK(status
)) {
5594 printf("POSIX lock failed %s\n", nt_errstr(status
));
5598 /* Punch a hole in the locked area. */
5599 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5600 if (!NT_STATUS_IS_OK(status
)) {
5601 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5605 cli_close(cli1
, fnum1
);
5607 /* Open the symlink for read - this should fail. A POSIX
5608 client should not be doing opens on a symlink. */
5609 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5610 if (NT_STATUS_IS_OK(status
)) {
5611 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5614 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5615 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5616 printf("POSIX open of %s should have failed "
5617 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5618 "failed with %s instead.\n",
5619 sname
, nt_errstr(status
));
5624 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5625 if (!NT_STATUS_IS_OK(status
)) {
5626 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5630 if (strcmp(namebuf
, fname
) != 0) {
5631 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5632 sname
, fname
, namebuf
);
5636 status
= cli_posix_rmdir(cli1
, dname
);
5637 if (!NT_STATUS_IS_OK(status
)) {
5638 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5642 /* Check directory opens with a specific permission. */
5643 status
= cli_posix_mkdir(cli1
, dname
, 0700);
5644 if (!NT_STATUS_IS_OK(status
)) {
5645 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5649 /* Ensure st_mode == 0700 */
5650 status
= cli_posix_stat(cli1
, dname
, &sbuf
);
5651 if (!NT_STATUS_IS_OK(status
)) {
5652 printf("stat failed (%s)\n", nt_errstr(status
));
5656 if ((sbuf
.st_ex_mode
& 07777) != 0700) {
5657 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5658 (unsigned int)(sbuf
.st_ex_mode
& 07777));
5662 printf("Simple POSIX open test passed\n");
5667 if (fnum1
!= (uint16_t)-1) {
5668 cli_close(cli1
, fnum1
);
5669 fnum1
= (uint16_t)-1;
5672 cli_setatr(cli1
, sname
, 0, 0);
5673 cli_posix_unlink(cli1
, sname
);
5674 cli_setatr(cli1
, hname
, 0, 0);
5675 cli_posix_unlink(cli1
, hname
);
5676 cli_setatr(cli1
, fname
, 0, 0);
5677 cli_posix_unlink(cli1
, fname
);
5678 cli_setatr(cli1
, dname
, 0, 0);
5679 cli_posix_rmdir(cli1
, dname
);
5681 if (!torture_close_connection(cli1
)) {
5689 static uint32 open_attrs_table
[] = {
5690 FILE_ATTRIBUTE_NORMAL
,
5691 FILE_ATTRIBUTE_ARCHIVE
,
5692 FILE_ATTRIBUTE_READONLY
,
5693 FILE_ATTRIBUTE_HIDDEN
,
5694 FILE_ATTRIBUTE_SYSTEM
,
5696 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5697 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5698 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5699 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5700 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5701 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5703 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5704 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5705 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5706 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5709 struct trunc_open_results
{
5716 static struct trunc_open_results attr_results
[] = {
5717 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5718 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5719 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5720 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5721 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5722 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5723 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5724 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5725 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5726 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5727 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5728 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5729 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5730 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5731 { 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
},
5732 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5733 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5734 { 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
},
5735 { 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
},
5736 { 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
},
5737 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5738 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5739 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5740 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5741 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5742 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5745 static bool run_openattrtest(int dummy
)
5747 static struct cli_state
*cli1
;
5748 const char *fname
= "\\openattr.file";
5750 bool correct
= True
;
5752 unsigned int i
, j
, k
, l
;
5755 printf("starting open attr test\n");
5757 if (!torture_open_connection(&cli1
, 0)) {
5761 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5763 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5764 cli_setatr(cli1
, fname
, 0, 0);
5765 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5767 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5768 open_attrs_table
[i
], FILE_SHARE_NONE
,
5769 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5770 if (!NT_STATUS_IS_OK(status
)) {
5771 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5775 status
= cli_close(cli1
, fnum1
);
5776 if (!NT_STATUS_IS_OK(status
)) {
5777 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5781 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5782 status
= cli_ntcreate(cli1
, fname
, 0,
5783 FILE_READ_DATA
|FILE_WRITE_DATA
,
5784 open_attrs_table
[j
],
5785 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5787 if (!NT_STATUS_IS_OK(status
)) {
5788 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5789 if (attr_results
[l
].num
== k
) {
5790 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5791 k
, open_attrs_table
[i
],
5792 open_attrs_table
[j
],
5793 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5798 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5799 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5800 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5805 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5811 status
= cli_close(cli1
, fnum1
);
5812 if (!NT_STATUS_IS_OK(status
)) {
5813 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5817 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5818 if (!NT_STATUS_IS_OK(status
)) {
5819 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5824 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5825 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5828 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5829 if (attr_results
[l
].num
== k
) {
5830 if (attr
!= attr_results
[l
].result_attr
||
5831 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5832 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5833 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5834 open_attrs_table
[i
],
5835 open_attrs_table
[j
],
5837 attr_results
[l
].result_attr
);
5847 cli_setatr(cli1
, fname
, 0, 0);
5848 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5850 printf("open attr test %s.\n", correct
? "passed" : "failed");
5852 if (!torture_close_connection(cli1
)) {
5858 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5859 const char *name
, void *state
)
5861 int *matched
= (int *)state
;
5862 if (matched
!= NULL
) {
5865 return NT_STATUS_OK
;
5869 test directory listing speed
5871 static bool run_dirtest(int dummy
)
5874 static struct cli_state
*cli
;
5876 struct timeval core_start
;
5877 bool correct
= True
;
5880 printf("starting directory test\n");
5882 if (!torture_open_connection(&cli
, 0)) {
5886 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5889 for (i
=0;i
<torture_numops
;i
++) {
5891 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5892 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5893 fprintf(stderr
,"Failed to open %s\n", fname
);
5896 cli_close(cli
, fnum
);
5899 core_start
= timeval_current();
5902 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5903 printf("Matched %d\n", matched
);
5906 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5907 printf("Matched %d\n", matched
);
5910 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5911 printf("Matched %d\n", matched
);
5913 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5916 for (i
=0;i
<torture_numops
;i
++) {
5918 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5919 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5922 if (!torture_close_connection(cli
)) {
5926 printf("finished dirtest\n");
5931 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5934 struct cli_state
*pcli
= (struct cli_state
*)state
;
5936 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5938 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5939 return NT_STATUS_OK
;
5941 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
5942 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5943 printf("del_fn: failed to rmdir %s\n,", fname
);
5945 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
5946 printf("del_fn: failed to unlink %s\n,", fname
);
5948 return NT_STATUS_OK
;
5953 sees what IOCTLs are supported
5955 bool torture_ioctl_test(int dummy
)
5957 static struct cli_state
*cli
;
5958 uint16_t device
, function
;
5960 const char *fname
= "\\ioctl.dat";
5964 if (!torture_open_connection(&cli
, 0)) {
5968 printf("starting ioctl test\n");
5970 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5972 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5973 if (!NT_STATUS_IS_OK(status
)) {
5974 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5978 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5979 printf("ioctl device info: %s\n", nt_errstr(status
));
5981 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5982 printf("ioctl job info: %s\n", nt_errstr(status
));
5984 for (device
=0;device
<0x100;device
++) {
5985 printf("ioctl test with device = 0x%x\n", device
);
5986 for (function
=0;function
<0x100;function
++) {
5987 uint32 code
= (device
<<16) | function
;
5989 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5991 if (NT_STATUS_IS_OK(status
)) {
5992 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5994 data_blob_free(&blob
);
5999 if (!torture_close_connection(cli
)) {
6008 tries varients of chkpath
6010 bool torture_chkpath_test(int dummy
)
6012 static struct cli_state
*cli
;
6017 if (!torture_open_connection(&cli
, 0)) {
6021 printf("starting chkpath test\n");
6023 /* cleanup from an old run */
6024 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6025 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6026 cli_rmdir(cli
, "\\chkpath.dir");
6028 status
= cli_mkdir(cli
, "\\chkpath.dir");
6029 if (!NT_STATUS_IS_OK(status
)) {
6030 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6034 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6035 if (!NT_STATUS_IS_OK(status
)) {
6036 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6040 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6042 if (!NT_STATUS_IS_OK(status
)) {
6043 printf("open1 failed (%s)\n", nt_errstr(status
));
6046 cli_close(cli
, fnum
);
6048 status
= cli_chkpath(cli
, "\\chkpath.dir");
6049 if (!NT_STATUS_IS_OK(status
)) {
6050 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6054 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6055 if (!NT_STATUS_IS_OK(status
)) {
6056 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6060 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6061 if (!NT_STATUS_IS_OK(status
)) {
6062 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6063 NT_STATUS_NOT_A_DIRECTORY
);
6065 printf("* chkpath on a file should fail\n");
6069 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6070 if (!NT_STATUS_IS_OK(status
)) {
6071 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6072 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6074 printf("* chkpath on a non existant file should fail\n");
6078 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6079 if (!NT_STATUS_IS_OK(status
)) {
6080 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6081 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6083 printf("* chkpath on a non existent component should fail\n");
6087 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6088 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6089 cli_rmdir(cli
, "\\chkpath.dir");
6091 if (!torture_close_connection(cli
)) {
6098 static bool run_eatest(int dummy
)
6100 static struct cli_state
*cli
;
6101 const char *fname
= "\\eatest.txt";
6102 bool correct
= True
;
6106 struct ea_struct
*ea_list
= NULL
;
6107 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6110 printf("starting eatest\n");
6112 if (!torture_open_connection(&cli
, 0)) {
6113 talloc_destroy(mem_ctx
);
6117 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6119 status
= cli_ntcreate(cli
, fname
, 0,
6120 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6121 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6123 if (!NT_STATUS_IS_OK(status
)) {
6124 printf("open failed - %s\n", nt_errstr(status
));
6125 talloc_destroy(mem_ctx
);
6129 for (i
= 0; i
< 10; i
++) {
6130 fstring ea_name
, ea_val
;
6132 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6133 memset(ea_val
, (char)i
+1, i
+1);
6134 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6135 if (!NT_STATUS_IS_OK(status
)) {
6136 printf("ea_set of name %s failed - %s\n", ea_name
,
6138 talloc_destroy(mem_ctx
);
6143 cli_close(cli
, fnum
);
6144 for (i
= 0; i
< 10; i
++) {
6145 fstring ea_name
, ea_val
;
6147 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6148 memset(ea_val
, (char)i
+1, i
+1);
6149 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6150 if (!NT_STATUS_IS_OK(status
)) {
6151 printf("ea_set of name %s failed - %s\n", ea_name
,
6153 talloc_destroy(mem_ctx
);
6158 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6159 if (!NT_STATUS_IS_OK(status
)) {
6160 printf("ea_get list failed - %s\n", nt_errstr(status
));
6164 printf("num_eas = %d\n", (int)num_eas
);
6166 if (num_eas
!= 20) {
6167 printf("Should be 20 EA's stored... failing.\n");
6171 for (i
= 0; i
< num_eas
; i
++) {
6172 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6173 dump_data(0, ea_list
[i
].value
.data
,
6174 ea_list
[i
].value
.length
);
6177 /* Setting EA's to zero length deletes them. Test this */
6178 printf("Now deleting all EA's - case indepenent....\n");
6181 cli_set_ea_path(cli
, fname
, "", "", 0);
6183 for (i
= 0; i
< 20; i
++) {
6185 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6186 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6187 if (!NT_STATUS_IS_OK(status
)) {
6188 printf("ea_set of name %s failed - %s\n", ea_name
,
6190 talloc_destroy(mem_ctx
);
6196 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6197 if (!NT_STATUS_IS_OK(status
)) {
6198 printf("ea_get list failed - %s\n", nt_errstr(status
));
6202 printf("num_eas = %d\n", (int)num_eas
);
6203 for (i
= 0; i
< num_eas
; i
++) {
6204 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6205 dump_data(0, ea_list
[i
].value
.data
,
6206 ea_list
[i
].value
.length
);
6210 printf("deleting EA's failed.\n");
6214 /* Try and delete a non existant EA. */
6215 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6216 if (!NT_STATUS_IS_OK(status
)) {
6217 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6222 talloc_destroy(mem_ctx
);
6223 if (!torture_close_connection(cli
)) {
6230 static bool run_dirtest1(int dummy
)
6233 static struct cli_state
*cli
;
6236 bool correct
= True
;
6238 printf("starting directory test\n");
6240 if (!torture_open_connection(&cli
, 0)) {
6244 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6246 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6247 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6248 cli_rmdir(cli
, "\\LISTDIR");
6249 cli_mkdir(cli
, "\\LISTDIR");
6251 /* Create 1000 files and 1000 directories. */
6252 for (i
=0;i
<1000;i
++) {
6254 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6255 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6256 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6257 fprintf(stderr
,"Failed to open %s\n", fname
);
6260 cli_close(cli
, fnum
);
6262 for (i
=0;i
<1000;i
++) {
6264 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6265 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6266 fprintf(stderr
,"Failed to open %s\n", fname
);
6271 /* Now ensure that doing an old list sees both files and directories. */
6273 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6274 printf("num_seen = %d\n", num_seen
);
6275 /* We should see 100 files + 1000 directories + . and .. */
6276 if (num_seen
!= 2002)
6279 /* Ensure if we have the "must have" bits we only see the
6283 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6284 printf("num_seen = %d\n", num_seen
);
6285 if (num_seen
!= 1002)
6289 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6290 printf("num_seen = %d\n", num_seen
);
6291 if (num_seen
!= 1000)
6294 /* Delete everything. */
6295 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6296 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6297 cli_rmdir(cli
, "\\LISTDIR");
6300 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6301 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6302 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6305 if (!torture_close_connection(cli
)) {
6309 printf("finished dirtest1\n");
6314 static bool run_error_map_extract(int dummy
) {
6316 static struct cli_state
*c_dos
;
6317 static struct cli_state
*c_nt
;
6329 /* NT-Error connection */
6331 disable_spnego
= true;
6332 if (!(c_nt
= open_nbt_connection())) {
6333 disable_spnego
= false;
6336 disable_spnego
= false;
6338 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
6341 if (!NT_STATUS_IS_OK(status
)) {
6342 printf("%s rejected the NT-error negprot (%s)\n", host
,
6348 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6349 if (!NT_STATUS_IS_OK(status
)) {
6350 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6354 /* DOS-Error connection */
6356 disable_spnego
= true;
6357 force_dos_errors
= true;
6358 if (!(c_dos
= open_nbt_connection())) {
6359 disable_spnego
= false;
6360 force_dos_errors
= false;
6363 disable_spnego
= false;
6364 force_dos_errors
= false;
6366 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
6368 if (!NT_STATUS_IS_OK(status
)) {
6369 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6371 cli_shutdown(c_dos
);
6375 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6376 if (!NT_STATUS_IS_OK(status
)) {
6377 printf("%s rejected the DOS-error initial session setup (%s)\n",
6378 host
, nt_errstr(status
));
6382 c_nt
->map_dos_errors
= false;
6383 c_dos
->map_dos_errors
= false;
6385 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6386 fstr_sprintf(user
, "%X", error
);
6388 status
= cli_session_setup(c_nt
, user
,
6389 password
, strlen(password
),
6390 password
, strlen(password
),
6392 if (NT_STATUS_IS_OK(status
)) {
6393 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6396 /* Case #1: 32-bit NT errors */
6397 if (!NT_STATUS_IS_DOS(status
)) {
6400 printf("/** Dos error on NT connection! (%s) */\n",
6402 nt_status
= NT_STATUS(0xc0000000);
6405 status
= cli_session_setup(c_dos
, user
,
6406 password
, strlen(password
),
6407 password
, strlen(password
),
6409 if (NT_STATUS_IS_OK(status
)) {
6410 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6413 /* Case #1: 32-bit NT errors */
6414 if (NT_STATUS_IS_DOS(status
)) {
6415 printf("/** NT error on DOS connection! (%s) */\n",
6417 errnum
= errclass
= 0;
6419 errclass
= NT_STATUS_DOS_CLASS(status
);
6420 errnum
= NT_STATUS_DOS_CODE(status
);
6423 if (NT_STATUS_V(nt_status
) != error
) {
6424 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6425 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6426 get_nt_error_c_code(talloc_tos(), nt_status
));
6429 printf("\t{%s,\t%s,\t%s},\n",
6430 smb_dos_err_class(errclass
),
6431 smb_dos_err_name(errclass
, errnum
),
6432 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6437 static bool run_sesssetup_bench(int dummy
)
6439 static struct cli_state
*c
;
6440 const char *fname
= "\\file.dat";
6445 if (!torture_open_connection(&c
, 0)) {
6449 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6450 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6451 FILE_DELETE_ON_CLOSE
, 0, &fnum
);
6452 if (!NT_STATUS_IS_OK(status
)) {
6453 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6457 for (i
=0; i
<torture_numops
; i
++) {
6458 status
= cli_session_setup(
6460 password
, strlen(password
),
6461 password
, strlen(password
),
6463 if (!NT_STATUS_IS_OK(status
)) {
6464 d_printf("(%s) cli_session_setup failed: %s\n",
6465 __location__
, nt_errstr(status
));
6469 d_printf("\r%d ", (int)cli_state_get_uid(c
));
6471 status
= cli_ulogoff(c
);
6472 if (!NT_STATUS_IS_OK(status
)) {
6473 d_printf("(%s) cli_ulogoff failed: %s\n",
6474 __location__
, nt_errstr(status
));
6482 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6483 uid_t uid
, gid_t gid
, const char *expected
)
6488 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
6490 if (strcmp(subst
, expected
) != 0) {
6491 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6492 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6501 static void chain1_open_completion(struct tevent_req
*req
)
6505 status
= cli_openx_recv(req
, &fnum
);
6508 d_printf("cli_openx_recv returned %s: %d\n",
6510 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6513 static void chain1_write_completion(struct tevent_req
*req
)
6517 status
= cli_write_andx_recv(req
, &written
);
6520 d_printf("cli_write_andx_recv returned %s: %d\n",
6522 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6525 static void chain1_close_completion(struct tevent_req
*req
)
6528 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6530 status
= cli_close_recv(req
);
6535 d_printf("cli_close returned %s\n", nt_errstr(status
));
6538 static bool run_chain1(int dummy
)
6540 struct cli_state
*cli1
;
6541 struct event_context
*evt
= event_context_init(NULL
);
6542 struct tevent_req
*reqs
[3], *smbreqs
[3];
6544 const char *str
= "foobar";
6547 printf("starting chain1 test\n");
6548 if (!torture_open_connection(&cli1
, 0)) {
6552 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6554 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, "\\test",
6555 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6556 if (reqs
[0] == NULL
) return false;
6557 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6560 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6561 (const uint8_t *)str
, 0, strlen(str
)+1,
6562 smbreqs
, 1, &smbreqs
[1]);
6563 if (reqs
[1] == NULL
) return false;
6564 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6566 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6567 if (reqs
[2] == NULL
) return false;
6568 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6570 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
6571 if (!NT_STATUS_IS_OK(status
)) {
6576 tevent_loop_once(evt
);
6579 torture_close_connection(cli1
);
6583 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6586 status
= cli_session_setup_guest_recv(req
);
6587 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6590 static void chain2_tcon_completion(struct tevent_req
*req
)
6592 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6594 status
= cli_tcon_andx_recv(req
);
6595 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6599 static bool run_chain2(int dummy
)
6601 struct cli_state
*cli1
;
6602 struct event_context
*evt
= event_context_init(NULL
);
6603 struct tevent_req
*reqs
[2], *smbreqs
[2];
6607 printf("starting chain2 test\n");
6608 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6609 port_to_use
, SMB_SIGNING_DEFAULT
, 0);
6610 if (!NT_STATUS_IS_OK(status
)) {
6614 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6616 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6618 if (reqs
[0] == NULL
) return false;
6619 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6621 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6622 "?????", NULL
, 0, &smbreqs
[1]);
6623 if (reqs
[1] == NULL
) return false;
6624 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6626 status
= smb1cli_req_chain_submit(smbreqs
, ARRAY_SIZE(smbreqs
));
6627 if (!NT_STATUS_IS_OK(status
)) {
6632 tevent_loop_once(evt
);
6635 torture_close_connection(cli1
);
6640 struct torture_createdel_state
{
6641 struct tevent_context
*ev
;
6642 struct cli_state
*cli
;
6645 static void torture_createdel_created(struct tevent_req
*subreq
);
6646 static void torture_createdel_closed(struct tevent_req
*subreq
);
6648 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6649 struct tevent_context
*ev
,
6650 struct cli_state
*cli
,
6653 struct tevent_req
*req
, *subreq
;
6654 struct torture_createdel_state
*state
;
6656 req
= tevent_req_create(mem_ctx
, &state
,
6657 struct torture_createdel_state
);
6664 subreq
= cli_ntcreate_send(
6665 state
, ev
, cli
, name
, 0,
6666 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6667 FILE_ATTRIBUTE_NORMAL
,
6668 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6669 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6671 if (tevent_req_nomem(subreq
, req
)) {
6672 return tevent_req_post(req
, ev
);
6674 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6678 static void torture_createdel_created(struct tevent_req
*subreq
)
6680 struct tevent_req
*req
= tevent_req_callback_data(
6681 subreq
, struct tevent_req
);
6682 struct torture_createdel_state
*state
= tevent_req_data(
6683 req
, struct torture_createdel_state
);
6687 status
= cli_ntcreate_recv(subreq
, &fnum
);
6688 TALLOC_FREE(subreq
);
6689 if (!NT_STATUS_IS_OK(status
)) {
6690 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6691 nt_errstr(status
)));
6692 tevent_req_nterror(req
, status
);
6696 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6697 if (tevent_req_nomem(subreq
, req
)) {
6700 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6703 static void torture_createdel_closed(struct tevent_req
*subreq
)
6705 struct tevent_req
*req
= tevent_req_callback_data(
6706 subreq
, struct tevent_req
);
6709 status
= cli_close_recv(subreq
);
6710 if (!NT_STATUS_IS_OK(status
)) {
6711 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6712 tevent_req_nterror(req
, status
);
6715 tevent_req_done(req
);
6718 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6720 return tevent_req_simple_recv_ntstatus(req
);
6723 struct torture_createdels_state
{
6724 struct tevent_context
*ev
;
6725 struct cli_state
*cli
;
6726 const char *base_name
;
6730 struct tevent_req
**reqs
;
6733 static void torture_createdels_done(struct tevent_req
*subreq
);
6735 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6736 struct tevent_context
*ev
,
6737 struct cli_state
*cli
,
6738 const char *base_name
,
6742 struct tevent_req
*req
;
6743 struct torture_createdels_state
*state
;
6746 req
= tevent_req_create(mem_ctx
, &state
,
6747 struct torture_createdels_state
);
6753 state
->base_name
= talloc_strdup(state
, base_name
);
6754 if (tevent_req_nomem(state
->base_name
, req
)) {
6755 return tevent_req_post(req
, ev
);
6757 state
->num_files
= MAX(num_parallel
, num_files
);
6759 state
->received
= 0;
6761 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6762 if (tevent_req_nomem(state
->reqs
, req
)) {
6763 return tevent_req_post(req
, ev
);
6766 for (i
=0; i
<num_parallel
; i
++) {
6769 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6771 if (tevent_req_nomem(name
, req
)) {
6772 return tevent_req_post(req
, ev
);
6774 state
->reqs
[i
] = torture_createdel_send(
6775 state
->reqs
, state
->ev
, state
->cli
, name
);
6776 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6777 return tevent_req_post(req
, ev
);
6779 name
= talloc_move(state
->reqs
[i
], &name
);
6780 tevent_req_set_callback(state
->reqs
[i
],
6781 torture_createdels_done
, req
);
6787 static void torture_createdels_done(struct tevent_req
*subreq
)
6789 struct tevent_req
*req
= tevent_req_callback_data(
6790 subreq
, struct tevent_req
);
6791 struct torture_createdels_state
*state
= tevent_req_data(
6792 req
, struct torture_createdels_state
);
6793 size_t num_parallel
= talloc_array_length(state
->reqs
);
6798 status
= torture_createdel_recv(subreq
);
6799 if (!NT_STATUS_IS_OK(status
)){
6800 DEBUG(10, ("torture_createdel_recv returned %s\n",
6801 nt_errstr(status
)));
6802 TALLOC_FREE(subreq
);
6803 tevent_req_nterror(req
, status
);
6807 for (i
=0; i
<num_parallel
; i
++) {
6808 if (subreq
== state
->reqs
[i
]) {
6812 if (i
== num_parallel
) {
6813 DEBUG(10, ("received something we did not send\n"));
6814 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6817 TALLOC_FREE(state
->reqs
[i
]);
6819 if (state
->sent
>= state
->num_files
) {
6820 tevent_req_done(req
);
6824 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6826 if (tevent_req_nomem(name
, req
)) {
6829 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6831 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6834 name
= talloc_move(state
->reqs
[i
], &name
);
6835 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6839 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6841 return tevent_req_simple_recv_ntstatus(req
);
6844 struct swallow_notify_state
{
6845 struct tevent_context
*ev
;
6846 struct cli_state
*cli
;
6848 uint32_t completion_filter
;
6850 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6854 static void swallow_notify_done(struct tevent_req
*subreq
);
6856 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6857 struct tevent_context
*ev
,
6858 struct cli_state
*cli
,
6860 uint32_t completion_filter
,
6862 bool (*fn
)(uint32_t action
,
6867 struct tevent_req
*req
, *subreq
;
6868 struct swallow_notify_state
*state
;
6870 req
= tevent_req_create(mem_ctx
, &state
,
6871 struct swallow_notify_state
);
6878 state
->completion_filter
= completion_filter
;
6879 state
->recursive
= recursive
;
6883 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6884 0xffff, state
->completion_filter
,
6886 if (tevent_req_nomem(subreq
, req
)) {
6887 return tevent_req_post(req
, ev
);
6889 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6893 static void swallow_notify_done(struct tevent_req
*subreq
)
6895 struct tevent_req
*req
= tevent_req_callback_data(
6896 subreq
, struct tevent_req
);
6897 struct swallow_notify_state
*state
= tevent_req_data(
6898 req
, struct swallow_notify_state
);
6900 uint32_t i
, num_changes
;
6901 struct notify_change
*changes
;
6903 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6904 TALLOC_FREE(subreq
);
6905 if (!NT_STATUS_IS_OK(status
)) {
6906 DEBUG(10, ("cli_notify_recv returned %s\n",
6907 nt_errstr(status
)));
6908 tevent_req_nterror(req
, status
);
6912 for (i
=0; i
<num_changes
; i
++) {
6913 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6915 TALLOC_FREE(changes
);
6917 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6918 0xffff, state
->completion_filter
,
6920 if (tevent_req_nomem(subreq
, req
)) {
6923 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6926 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6928 if (DEBUGLEVEL
> 5) {
6929 d_printf("%d %s\n", (int)action
, name
);
6934 static void notify_bench_done(struct tevent_req
*req
)
6936 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6940 static bool run_notify_bench(int dummy
)
6942 const char *dname
= "\\notify-bench";
6943 struct tevent_context
*ev
;
6946 struct tevent_req
*req1
;
6947 struct tevent_req
*req2
= NULL
;
6948 int i
, num_unc_names
;
6949 int num_finished
= 0;
6951 printf("starting notify-bench test\n");
6953 if (use_multishare_conn
) {
6955 unc_list
= file_lines_load(multishare_conn_fname
,
6956 &num_unc_names
, 0, NULL
);
6957 if (!unc_list
|| num_unc_names
<= 0) {
6958 d_printf("Failed to load unc names list from '%s'\n",
6959 multishare_conn_fname
);
6962 TALLOC_FREE(unc_list
);
6967 ev
= tevent_context_init(talloc_tos());
6969 d_printf("tevent_context_init failed\n");
6973 for (i
=0; i
<num_unc_names
; i
++) {
6974 struct cli_state
*cli
;
6977 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6979 if (base_fname
== NULL
) {
6983 if (!torture_open_connection(&cli
, i
)) {
6987 status
= cli_ntcreate(cli
, dname
, 0,
6988 MAXIMUM_ALLOWED_ACCESS
,
6989 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6991 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6994 if (!NT_STATUS_IS_OK(status
)) {
6995 d_printf("Could not create %s: %s\n", dname
,
7000 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
7001 FILE_NOTIFY_CHANGE_FILE_NAME
|
7002 FILE_NOTIFY_CHANGE_DIR_NAME
|
7003 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
7004 FILE_NOTIFY_CHANGE_LAST_WRITE
,
7005 false, print_notifies
, NULL
);
7007 d_printf("Could not create notify request\n");
7011 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
7012 base_fname
, 10, torture_numops
);
7014 d_printf("Could not create createdels request\n");
7017 TALLOC_FREE(base_fname
);
7019 tevent_req_set_callback(req2
, notify_bench_done
,
7023 while (num_finished
< num_unc_names
) {
7025 ret
= tevent_loop_once(ev
);
7027 d_printf("tevent_loop_once failed\n");
7032 if (!tevent_req_poll(req2
, ev
)) {
7033 d_printf("tevent_req_poll failed\n");
7036 status
= torture_createdels_recv(req2
);
7037 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7042 static bool run_mangle1(int dummy
)
7044 struct cli_state
*cli
;
7045 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7049 time_t change_time
, access_time
, write_time
;
7053 printf("starting mangle1 test\n");
7054 if (!torture_open_connection(&cli
, 0)) {
7058 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7060 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7061 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7063 if (!NT_STATUS_IS_OK(status
)) {
7064 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7067 cli_close(cli
, fnum
);
7069 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7070 if (!NT_STATUS_IS_OK(status
)) {
7071 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7075 d_printf("alt_name: %s\n", alt_name
);
7077 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7078 if (!NT_STATUS_IS_OK(status
)) {
7079 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
7083 cli_close(cli
, fnum
);
7085 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7086 &write_time
, &size
, &mode
);
7087 if (!NT_STATUS_IS_OK(status
)) {
7088 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7096 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7098 size_t *to_pull
= (size_t *)priv
;
7099 size_t thistime
= *to_pull
;
7101 thistime
= MIN(thistime
, n
);
7102 if (thistime
== 0) {
7106 memset(buf
, 0, thistime
);
7107 *to_pull
-= thistime
;
7111 static bool run_windows_write(int dummy
)
7113 struct cli_state
*cli1
;
7117 const char *fname
= "\\writetest.txt";
7118 struct timeval start_time
;
7123 printf("starting windows_write test\n");
7124 if (!torture_open_connection(&cli1
, 0)) {
7128 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7129 if (!NT_STATUS_IS_OK(status
)) {
7130 printf("open failed (%s)\n", nt_errstr(status
));
7134 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7136 start_time
= timeval_current();
7138 for (i
=0; i
<torture_numops
; i
++) {
7140 off_t start
= i
* torture_blocksize
;
7141 size_t to_pull
= torture_blocksize
- 1;
7143 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7144 start
+ torture_blocksize
- 1, 1, NULL
);
7145 if (!NT_STATUS_IS_OK(status
)) {
7146 printf("cli_write failed: %s\n", nt_errstr(status
));
7150 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7151 null_source
, &to_pull
);
7152 if (!NT_STATUS_IS_OK(status
)) {
7153 printf("cli_push returned: %s\n", nt_errstr(status
));
7158 seconds
= timeval_elapsed(&start_time
);
7159 kbytes
= (double)torture_blocksize
* torture_numops
;
7162 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7163 (double)seconds
, (int)(kbytes
/seconds
));
7167 cli_close(cli1
, fnum
);
7168 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7169 torture_close_connection(cli1
);
7173 static bool run_cli_echo(int dummy
)
7175 struct cli_state
*cli
;
7178 printf("starting cli_echo test\n");
7179 if (!torture_open_connection(&cli
, 0)) {
7182 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7184 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7186 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7188 torture_close_connection(cli
);
7189 return NT_STATUS_IS_OK(status
);
7192 static bool run_uid_regression_test(int dummy
)
7194 static struct cli_state
*cli
;
7197 bool correct
= True
;
7200 printf("starting uid regression test\n");
7202 if (!torture_open_connection(&cli
, 0)) {
7206 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7208 /* Ok - now save then logoff our current user. */
7209 old_vuid
= cli_state_get_uid(cli
);
7211 status
= cli_ulogoff(cli
);
7212 if (!NT_STATUS_IS_OK(status
)) {
7213 d_printf("(%s) cli_ulogoff failed: %s\n",
7214 __location__
, nt_errstr(status
));
7219 cli_state_set_uid(cli
, old_vuid
);
7221 /* Try an operation. */
7222 status
= cli_mkdir(cli
, "\\uid_reg_test");
7223 if (NT_STATUS_IS_OK(status
)) {
7224 d_printf("(%s) cli_mkdir succeeded\n",
7229 /* Should be bad uid. */
7230 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
7231 NT_STATUS_USER_SESSION_DELETED
)) {
7237 old_cnum
= cli_state_get_tid(cli
);
7239 /* Now try a SMBtdis with the invald vuid set to zero. */
7240 cli_state_set_uid(cli
, 0);
7242 /* This should succeed. */
7243 status
= cli_tdis(cli
);
7245 if (NT_STATUS_IS_OK(status
)) {
7246 d_printf("First tdis with invalid vuid should succeed.\n");
7248 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7253 cli_state_set_uid(cli
, old_vuid
);
7254 cli_state_set_tid(cli
, old_cnum
);
7256 /* This should fail. */
7257 status
= cli_tdis(cli
);
7258 if (NT_STATUS_IS_OK(status
)) {
7259 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7263 /* Should be bad tid. */
7264 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
7265 NT_STATUS_NETWORK_NAME_DELETED
)) {
7271 cli_rmdir(cli
, "\\uid_reg_test");
7280 static const char *illegal_chars
= "*\\/?<>|\":";
7281 static char force_shortname_chars
[] = " +,.[];=\177";
7283 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7284 const char *mask
, void *state
)
7286 struct cli_state
*pcli
= (struct cli_state
*)state
;
7288 NTSTATUS status
= NT_STATUS_OK
;
7290 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7292 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7293 return NT_STATUS_OK
;
7295 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7296 status
= cli_rmdir(pcli
, fname
);
7297 if (!NT_STATUS_IS_OK(status
)) {
7298 printf("del_fn: failed to rmdir %s\n,", fname
);
7301 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7302 if (!NT_STATUS_IS_OK(status
)) {
7303 printf("del_fn: failed to unlink %s\n,", fname
);
7315 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7316 const char *name
, void *state
)
7318 struct sn_state
*s
= (struct sn_state
*)state
;
7322 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7323 i
, finfo
->name
, finfo
->short_name
);
7326 if (strchr(force_shortname_chars
, i
)) {
7327 if (!finfo
->short_name
) {
7328 /* Shortname not created when it should be. */
7329 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7330 __location__
, finfo
->name
, i
);
7333 } else if (finfo
->short_name
){
7334 /* Shortname created when it should not be. */
7335 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7336 __location__
, finfo
->short_name
, finfo
->name
);
7340 return NT_STATUS_OK
;
7343 static bool run_shortname_test(int dummy
)
7345 static struct cli_state
*cli
;
7346 bool correct
= True
;
7352 printf("starting shortname test\n");
7354 if (!torture_open_connection(&cli
, 0)) {
7358 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7360 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7361 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7362 cli_rmdir(cli
, "\\shortname");
7364 status
= cli_mkdir(cli
, "\\shortname");
7365 if (!NT_STATUS_IS_OK(status
)) {
7366 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7367 __location__
, nt_errstr(status
));
7372 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
7376 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
7383 for (i
= 32; i
< 128; i
++) {
7384 uint16_t fnum
= (uint16_t)-1;
7388 if (strchr(illegal_chars
, i
)) {
7393 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7394 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
7395 if (!NT_STATUS_IS_OK(status
)) {
7396 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7397 __location__
, fname
, nt_errstr(status
));
7401 cli_close(cli
, fnum
);
7404 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7405 shortname_list_fn
, &s
);
7406 if (s
.matched
!= 1) {
7407 d_printf("(%s) failed to list %s: %s\n",
7408 __location__
, fname
, nt_errstr(status
));
7413 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7414 if (!NT_STATUS_IS_OK(status
)) {
7415 d_printf("(%s) failed to delete %s: %s\n",
7416 __location__
, fname
, nt_errstr(status
));
7429 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7430 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7431 cli_rmdir(cli
, "\\shortname");
7432 torture_close_connection(cli
);
7436 static void pagedsearch_cb(struct tevent_req
*req
)
7439 struct tldap_message
*msg
;
7442 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7443 if (rc
!= TLDAP_SUCCESS
) {
7444 d_printf("tldap_search_paged_recv failed: %s\n",
7445 tldap_err2string(rc
));
7448 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7452 if (!tldap_entry_dn(msg
, &dn
)) {
7453 d_printf("tldap_entry_dn failed\n");
7456 d_printf("%s\n", dn
);
7460 static bool run_tldap(int dummy
)
7462 struct tldap_context
*ld
;
7465 struct sockaddr_storage addr
;
7466 struct tevent_context
*ev
;
7467 struct tevent_req
*req
;
7471 if (!resolve_name(host
, &addr
, 0, false)) {
7472 d_printf("could not find host %s\n", host
);
7475 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7476 if (!NT_STATUS_IS_OK(status
)) {
7477 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7481 ld
= tldap_context_create(talloc_tos(), fd
);
7484 d_printf("tldap_context_create failed\n");
7488 rc
= tldap_fetch_rootdse(ld
);
7489 if (rc
!= TLDAP_SUCCESS
) {
7490 d_printf("tldap_fetch_rootdse failed: %s\n",
7491 tldap_errstr(talloc_tos(), ld
, rc
));
7495 basedn
= tldap_talloc_single_attribute(
7496 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7497 if (basedn
== NULL
) {
7498 d_printf("no defaultNamingContext\n");
7501 d_printf("defaultNamingContext: %s\n", basedn
);
7503 ev
= tevent_context_init(talloc_tos());
7505 d_printf("tevent_context_init failed\n");
7509 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7510 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7512 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7514 d_printf("tldap_search_paged_send failed\n");
7517 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7519 tevent_req_poll(req
, ev
);
7523 /* test search filters against rootDSE */
7524 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7525 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7527 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7528 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7529 talloc_tos(), NULL
, NULL
);
7530 if (rc
!= TLDAP_SUCCESS
) {
7531 d_printf("tldap_search with complex filter failed: %s\n",
7532 tldap_errstr(talloc_tos(), ld
, rc
));
7540 /* Torture test to ensure no regression of :
7541 https://bugzilla.samba.org/show_bug.cgi?id=7084
7544 static bool run_dir_createtime(int dummy
)
7546 struct cli_state
*cli
;
7547 const char *dname
= "\\testdir";
7548 const char *fname
= "\\testdir\\testfile";
7550 struct timespec create_time
;
7551 struct timespec create_time1
;
7555 if (!torture_open_connection(&cli
, 0)) {
7559 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7560 cli_rmdir(cli
, dname
);
7562 status
= cli_mkdir(cli
, dname
);
7563 if (!NT_STATUS_IS_OK(status
)) {
7564 printf("mkdir failed: %s\n", nt_errstr(status
));
7568 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7570 if (!NT_STATUS_IS_OK(status
)) {
7571 printf("cli_qpathinfo2 returned %s\n",
7576 /* Sleep 3 seconds, then create a file. */
7579 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7581 if (!NT_STATUS_IS_OK(status
)) {
7582 printf("cli_openx failed: %s\n", nt_errstr(status
));
7586 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7588 if (!NT_STATUS_IS_OK(status
)) {
7589 printf("cli_qpathinfo2 (2) returned %s\n",
7594 if (timespec_compare(&create_time1
, &create_time
)) {
7595 printf("run_dir_createtime: create time was updated (error)\n");
7597 printf("run_dir_createtime: create time was not updated (correct)\n");
7603 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7604 cli_rmdir(cli
, dname
);
7605 if (!torture_close_connection(cli
)) {
7612 static bool run_streamerror(int dummy
)
7614 struct cli_state
*cli
;
7615 const char *dname
= "\\testdir";
7616 const char *streamname
=
7617 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7619 time_t change_time
, access_time
, write_time
;
7621 uint16_t mode
, fnum
;
7624 if (!torture_open_connection(&cli
, 0)) {
7628 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7629 cli_rmdir(cli
, dname
);
7631 status
= cli_mkdir(cli
, dname
);
7632 if (!NT_STATUS_IS_OK(status
)) {
7633 printf("mkdir failed: %s\n", nt_errstr(status
));
7637 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
7638 &write_time
, &size
, &mode
);
7639 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7640 printf("pathinfo returned %s, expected "
7641 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7646 status
= cli_ntcreate(cli
, streamname
, 0x16,
7647 FILE_READ_DATA
|FILE_READ_EA
|
7648 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7649 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7650 FILE_OPEN
, 0, 0, &fnum
);
7652 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7653 printf("ntcreate returned %s, expected "
7654 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7660 cli_rmdir(cli
, dname
);
7664 static bool run_local_substitute(int dummy
)
7668 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7669 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7670 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7671 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7672 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7673 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7674 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7675 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7677 /* Different captialization rules in sub_basic... */
7679 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7685 static bool run_local_base64(int dummy
)
7690 for (i
=1; i
<2000; i
++) {
7691 DATA_BLOB blob1
, blob2
;
7694 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7696 generate_random_buffer(blob1
.data
, blob1
.length
);
7698 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7700 d_fprintf(stderr
, "base64_encode_data_blob failed "
7701 "for %d bytes\n", i
);
7704 blob2
= base64_decode_data_blob(b64
);
7707 if (data_blob_cmp(&blob1
, &blob2
)) {
7708 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7712 TALLOC_FREE(blob1
.data
);
7713 data_blob_free(&blob2
);
7718 static bool run_local_gencache(int dummy
)
7724 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7725 d_printf("%s: gencache_set() failed\n", __location__
);
7729 if (!gencache_get("foo", NULL
, NULL
)) {
7730 d_printf("%s: gencache_get() failed\n", __location__
);
7734 if (!gencache_get("foo", &val
, &tm
)) {
7735 d_printf("%s: gencache_get() failed\n", __location__
);
7739 if (strcmp(val
, "bar") != 0) {
7740 d_printf("%s: gencache_get() returned %s, expected %s\n",
7741 __location__
, val
, "bar");
7748 if (!gencache_del("foo")) {
7749 d_printf("%s: gencache_del() failed\n", __location__
);
7752 if (gencache_del("foo")) {
7753 d_printf("%s: second gencache_del() succeeded\n",
7758 if (gencache_get("foo", &val
, &tm
)) {
7759 d_printf("%s: gencache_get() on deleted entry "
7760 "succeeded\n", __location__
);
7764 blob
= data_blob_string_const_null("bar");
7765 tm
= time(NULL
) + 60;
7767 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7768 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7772 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7773 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7777 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7778 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7779 __location__
, (const char *)blob
.data
, "bar");
7780 data_blob_free(&blob
);
7784 data_blob_free(&blob
);
7786 if (!gencache_del("foo")) {
7787 d_printf("%s: gencache_del() failed\n", __location__
);
7790 if (gencache_del("foo")) {
7791 d_printf("%s: second gencache_del() succeeded\n",
7796 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7797 d_printf("%s: gencache_get_data_blob() on deleted entry "
7798 "succeeded\n", __location__
);
7805 static bool rbt_testval(struct db_context
*db
, const char *key
,
7808 struct db_record
*rec
;
7809 TDB_DATA data
= string_tdb_data(value
);
7814 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7816 d_fprintf(stderr
, "fetch_locked failed\n");
7819 status
= dbwrap_record_store(rec
, data
, 0);
7820 if (!NT_STATUS_IS_OK(status
)) {
7821 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7826 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7828 d_fprintf(stderr
, "second fetch_locked failed\n");
7832 dbvalue
= dbwrap_record_get_value(rec
);
7833 if ((dbvalue
.dsize
!= data
.dsize
)
7834 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7835 d_fprintf(stderr
, "Got wrong data back\n");
7845 static bool run_local_rbtree(int dummy
)
7847 struct db_context
*db
;
7851 db
= db_open_rbt(NULL
);
7854 d_fprintf(stderr
, "db_open_rbt failed\n");
7858 for (i
=0; i
<1000; i
++) {
7861 if (asprintf(&key
, "key%ld", random()) == -1) {
7864 if (asprintf(&value
, "value%ld", random()) == -1) {
7869 if (!rbt_testval(db
, key
, value
)) {
7876 if (asprintf(&value
, "value%ld", random()) == -1) {
7881 if (!rbt_testval(db
, key
, value
)) {
7900 local test for character set functions
7902 This is a very simple test for the functionality in convert_string_error()
7904 static bool run_local_convert_string(int dummy
)
7906 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
7907 const char *test_strings
[2] = { "March", "M\303\244rz" };
7911 for (i
=0; i
<2; i
++) {
7912 const char *str
= test_strings
[i
];
7913 int len
= strlen(str
);
7914 size_t converted_size
;
7917 memset(dst
, 'X', sizeof(dst
));
7919 /* first try with real source length */
7920 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7925 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7929 if (converted_size
!= len
) {
7930 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7931 str
, len
, (int)converted_size
);
7935 if (strncmp(str
, dst
, converted_size
) != 0) {
7936 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7940 if (strlen(str
) != converted_size
) {
7941 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7942 (int)strlen(str
), (int)converted_size
);
7946 if (dst
[converted_size
] != 'X') {
7947 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7951 /* now with srclen==-1, this causes the nul to be
7953 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7958 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7962 if (converted_size
!= len
+1) {
7963 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7964 str
, len
, (int)converted_size
);
7968 if (strncmp(str
, dst
, converted_size
) != 0) {
7969 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7973 if (len
+1 != converted_size
) {
7974 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7975 len
+1, (int)converted_size
);
7979 if (dst
[converted_size
] != 'X') {
7980 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7987 TALLOC_FREE(tmp_ctx
);
7990 TALLOC_FREE(tmp_ctx
);
7995 struct talloc_dict_test
{
7999 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
8001 int *count
= (int *)priv
;
8006 static bool run_local_talloc_dict(int dummy
)
8008 struct talloc_dict
*dict
;
8009 struct talloc_dict_test
*t
;
8010 int key
, count
, res
;
8013 dict
= talloc_dict_init(talloc_tos());
8018 t
= talloc(talloc_tos(), struct talloc_dict_test
);
8025 ok
= talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), &t
);
8031 res
= talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
);
8049 static bool run_local_string_to_sid(int dummy
) {
8052 if (string_to_sid(&sid
, "S--1-5-32-545")) {
8053 printf("allowing S--1-5-32-545\n");
8056 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
8057 printf("allowing S-1-5-32-+545\n");
8060 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")) {
8061 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8064 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
8065 printf("allowing S-1-5-32-545-abc\n");
8068 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
8069 printf("could not parse S-1-5-32-545\n");
8072 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
8073 printf("mis-parsed S-1-5-32-545 as %s\n",
8074 sid_string_tos(&sid
));
8080 static bool run_local_binary_to_sid(int dummy
) {
8081 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
8082 static const char good_binary_sid
[] = {
8083 0x1, /* revision number */
8085 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8086 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8098 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8099 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8100 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8103 static const char long_binary_sid
[] = {
8104 0x1, /* revision number */
8106 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8107 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8108 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8109 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8110 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8111 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8112 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8113 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8114 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8115 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8116 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8117 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8118 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8119 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8120 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8121 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8122 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8123 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8124 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8127 static const char long_binary_sid2
[] = {
8128 0x1, /* revision number */
8130 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8131 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8132 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8133 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8134 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8135 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8136 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8137 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8138 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8139 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8140 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8141 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8142 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8143 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8144 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8145 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8146 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8147 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8148 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8149 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8150 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8151 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8152 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8153 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8154 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8155 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8156 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8157 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8158 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8159 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8160 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8161 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8162 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8165 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8168 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8171 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8177 /* Split a path name into filename and stream name components. Canonicalise
8178 * such that an implicit $DATA token is always explicit.
8180 * The "specification" of this function can be found in the
8181 * run_local_stream_name() function in torture.c, I've tried those
8182 * combinations against a W2k3 server.
8185 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8186 char **pbase
, char **pstream
)
8189 char *stream
= NULL
;
8190 char *sname
; /* stream name */
8191 const char *stype
; /* stream type */
8193 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8195 sname
= strchr_m(fname
, ':');
8197 if (lp_posix_pathnames() || (sname
== NULL
)) {
8198 if (pbase
!= NULL
) {
8199 base
= talloc_strdup(mem_ctx
, fname
);
8200 NT_STATUS_HAVE_NO_MEMORY(base
);
8205 if (pbase
!= NULL
) {
8206 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8207 NT_STATUS_HAVE_NO_MEMORY(base
);
8212 stype
= strchr_m(sname
, ':');
8214 if (stype
== NULL
) {
8215 sname
= talloc_strdup(mem_ctx
, sname
);
8219 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8221 * If there is an explicit stream type, so far we only
8222 * allow $DATA. Is there anything else allowed? -- vl
8224 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8226 return NT_STATUS_OBJECT_NAME_INVALID
;
8228 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8232 if (sname
== NULL
) {
8234 return NT_STATUS_NO_MEMORY
;
8237 if (sname
[0] == '\0') {
8239 * no stream name, so no stream
8244 if (pstream
!= NULL
) {
8245 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8246 if (stream
== NULL
) {
8249 return NT_STATUS_NO_MEMORY
;
8252 * upper-case the type field
8254 strupper_m(strchr_m(stream
, ':')+1);
8258 if (pbase
!= NULL
) {
8261 if (pstream
!= NULL
) {
8264 return NT_STATUS_OK
;
8267 static bool test_stream_name(const char *fname
, const char *expected_base
,
8268 const char *expected_stream
,
8269 NTSTATUS expected_status
)
8273 char *stream
= NULL
;
8275 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8276 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8280 if (!NT_STATUS_IS_OK(status
)) {
8284 if (base
== NULL
) goto error
;
8286 if (strcmp(expected_base
, base
) != 0) goto error
;
8288 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8289 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8291 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8295 TALLOC_FREE(stream
);
8299 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8300 fname
, expected_base
? expected_base
: "<NULL>",
8301 expected_stream
? expected_stream
: "<NULL>",
8302 nt_errstr(expected_status
));
8303 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8304 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8307 TALLOC_FREE(stream
);
8311 static bool run_local_stream_name(int dummy
)
8315 ret
&= test_stream_name(
8316 "bla", "bla", NULL
, NT_STATUS_OK
);
8317 ret
&= test_stream_name(
8318 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8319 ret
&= test_stream_name(
8320 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8321 ret
&= test_stream_name(
8322 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8323 ret
&= test_stream_name(
8324 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8325 ret
&= test_stream_name(
8326 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8327 ret
&= test_stream_name(
8328 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8329 ret
&= test_stream_name(
8330 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8335 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8337 if (a
.length
!= b
.length
) {
8338 printf("a.length=%d != b.length=%d\n",
8339 (int)a
.length
, (int)b
.length
);
8342 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8343 printf("a.data and b.data differ\n");
8349 static bool run_local_memcache(int dummy
)
8351 struct memcache
*cache
;
8353 DATA_BLOB d1
, d2
, d3
;
8354 DATA_BLOB v1
, v2
, v3
;
8356 TALLOC_CTX
*mem_ctx
;
8358 size_t size1
, size2
;
8361 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
8363 if (cache
== NULL
) {
8364 printf("memcache_init failed\n");
8368 d1
= data_blob_const("d1", 2);
8369 d2
= data_blob_const("d2", 2);
8370 d3
= data_blob_const("d3", 2);
8372 k1
= data_blob_const("d1", 2);
8373 k2
= data_blob_const("d2", 2);
8375 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8376 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8378 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8379 printf("could not find k1\n");
8382 if (!data_blob_equal(d1
, v1
)) {
8386 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8387 printf("could not find k2\n");
8390 if (!data_blob_equal(d2
, v2
)) {
8394 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8396 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8397 printf("could not find replaced k1\n");
8400 if (!data_blob_equal(d3
, v3
)) {
8404 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8406 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8407 printf("Did find k2, should have been purged\n");
8413 cache
= memcache_init(NULL
, 0);
8415 mem_ctx
= talloc_init("foo");
8417 str1
= talloc_strdup(mem_ctx
, "string1");
8418 str2
= talloc_strdup(mem_ctx
, "string2");
8420 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8421 data_blob_string_const("torture"), &str1
);
8422 size1
= talloc_total_size(cache
);
8424 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8425 data_blob_string_const("torture"), &str2
);
8426 size2
= talloc_total_size(cache
);
8428 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8430 if (size2
> size1
) {
8431 printf("memcache leaks memory!\n");
8441 static void wbclient_done(struct tevent_req
*req
)
8444 struct winbindd_response
*wb_resp
;
8445 int *i
= (int *)tevent_req_callback_data_void(req
);
8447 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8450 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8453 static bool run_local_wbclient(int dummy
)
8455 struct event_context
*ev
;
8456 struct wb_context
**wb_ctx
;
8457 struct winbindd_request wb_req
;
8458 bool result
= false;
8461 BlockSignals(True
, SIGPIPE
);
8463 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
8468 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
8469 if (wb_ctx
== NULL
) {
8473 ZERO_STRUCT(wb_req
);
8474 wb_req
.cmd
= WINBINDD_PING
;
8476 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
8478 for (i
=0; i
<torture_nprocs
; i
++) {
8479 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8480 if (wb_ctx
[i
] == NULL
) {
8483 for (j
=0; j
<torture_numops
; j
++) {
8484 struct tevent_req
*req
;
8485 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8486 (j
% 2) == 0, &wb_req
);
8490 tevent_req_set_callback(req
, wbclient_done
, &i
);
8496 while (i
< torture_nprocs
* torture_numops
) {
8497 tevent_loop_once(ev
);
8506 static void getaddrinfo_finished(struct tevent_req
*req
)
8508 char *name
= (char *)tevent_req_callback_data_void(req
);
8509 struct addrinfo
*ainfo
;
8512 res
= getaddrinfo_recv(req
, &ainfo
);
8514 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
8517 d_printf("gai(%s) succeeded\n", name
);
8518 freeaddrinfo(ainfo
);
8521 static bool run_getaddrinfo_send(int dummy
)
8523 TALLOC_CTX
*frame
= talloc_stackframe();
8524 struct fncall_context
*ctx
;
8525 struct tevent_context
*ev
;
8526 bool result
= false;
8527 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
8528 "www.slashdot.org", "heise.de" };
8529 struct tevent_req
*reqs
[4];
8532 ev
= event_context_init(frame
);
8537 ctx
= fncall_context_init(frame
, 4);
8539 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
8540 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
8542 if (reqs
[i
] == NULL
) {
8545 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
8546 discard_const_p(void, names
[i
]));
8549 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
8550 tevent_loop_once(ev
);
8559 static bool dbtrans_inc(struct db_context
*db
)
8561 struct db_record
*rec
;
8567 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8569 printf(__location__
"fetch_lock failed\n");
8573 value
= dbwrap_record_get_value(rec
);
8575 if (value
.dsize
!= sizeof(uint32_t)) {
8576 printf(__location__
"value.dsize = %d\n",
8581 memcpy(&val
, value
.dptr
, sizeof(val
));
8584 status
= dbwrap_record_store(
8585 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
8586 if (!NT_STATUS_IS_OK(status
)) {
8587 printf(__location__
"store failed: %s\n",
8598 static bool run_local_dbtrans(int dummy
)
8600 struct db_context
*db
;
8601 struct db_record
*rec
;
8607 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
8608 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
);
8610 printf("Could not open transtest.db\n");
8614 res
= dbwrap_transaction_start(db
);
8616 printf(__location__
"transaction_start failed\n");
8620 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8622 printf(__location__
"fetch_lock failed\n");
8626 value
= dbwrap_record_get_value(rec
);
8628 if (value
.dptr
== NULL
) {
8630 status
= dbwrap_record_store(
8631 rec
, make_tdb_data((uint8_t *)&initial
,
8634 if (!NT_STATUS_IS_OK(status
)) {
8635 printf(__location__
"store returned %s\n",
8643 res
= dbwrap_transaction_commit(db
);
8645 printf(__location__
"transaction_commit failed\n");
8653 res
= dbwrap_transaction_start(db
);
8655 printf(__location__
"transaction_start failed\n");
8659 status
= dbwrap_fetch_uint32(db
, "transtest", &val
);
8660 if (!NT_STATUS_IS_OK(status
)) {
8661 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8666 for (i
=0; i
<10; i
++) {
8667 if (!dbtrans_inc(db
)) {
8672 status
= dbwrap_fetch_uint32(db
, "transtest", &val2
);
8673 if (!NT_STATUS_IS_OK(status
)) {
8674 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8679 if (val2
!= val
+ 10) {
8680 printf(__location__
"val=%d, val2=%d\n",
8681 (int)val
, (int)val2
);
8685 printf("val2=%d\r", val2
);
8687 res
= dbwrap_transaction_commit(db
);
8689 printf(__location__
"transaction_commit failed\n");
8699 * Just a dummy test to be run under a debugger. There's no real way
8700 * to inspect the tevent_select specific function from outside of
8704 static bool run_local_tevent_select(int dummy
)
8706 struct tevent_context
*ev
;
8707 struct tevent_fd
*fd1
, *fd2
;
8708 bool result
= false;
8710 ev
= tevent_context_init_byname(NULL
, "select");
8712 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8716 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8718 d_fprintf(stderr
, "tevent_add_fd failed\n");
8721 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8723 d_fprintf(stderr
, "tevent_add_fd failed\n");
8728 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8730 d_fprintf(stderr
, "tevent_add_fd failed\n");
8740 static bool run_local_hex_encode_buf(int dummy
)
8746 for (i
=0; i
<sizeof(src
); i
++) {
8749 hex_encode_buf(buf
, src
, sizeof(src
));
8750 if (strcmp(buf
, "0001020304050607") != 0) {
8753 hex_encode_buf(buf
, NULL
, 0);
8754 if (buf
[0] != '\0') {
8760 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
8782 "1001:1111:1111:1000:0:1111:1111:1111",
8791 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
8805 "1001:1111:1111:1000:0:1111:1111:1111"
8808 static bool run_local_remove_duplicate_addrs2(int dummy
)
8810 struct ip_service test_vector
[28];
8813 /* Construct the sockaddr_storage test vector. */
8814 for (i
= 0; i
< 28; i
++) {
8815 struct addrinfo hints
;
8816 struct addrinfo
*res
= NULL
;
8819 memset(&hints
, '\0', sizeof(hints
));
8820 hints
.ai_flags
= AI_NUMERICHOST
;
8821 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
8826 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
8827 remove_duplicate_addrs2_test_strings_vector
[i
]);
8830 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
8831 memcpy(&test_vector
[i
].ss
,
8837 count
= remove_duplicate_addrs2(test_vector
, i
);
8840 fprintf(stderr
, "count wrong (%d) should be 14\n",
8845 for (i
= 0; i
< count
; i
++) {
8846 char addr
[INET6_ADDRSTRLEN
];
8848 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
8850 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
8851 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
8854 remove_duplicate_addrs2_test_strings_result
[i
]);
8859 printf("run_local_remove_duplicate_addrs2: success\n");
8863 static double create_procs(bool (*fn
)(int), bool *result
)
8866 volatile pid_t
*child_status
;
8867 volatile bool *child_status_out
;
8870 struct timeval start
;
8874 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*torture_nprocs
);
8875 if (!child_status
) {
8876 printf("Failed to setup shared memory\n");
8880 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*torture_nprocs
);
8881 if (!child_status_out
) {
8882 printf("Failed to setup result status shared memory\n");
8886 for (i
= 0; i
< torture_nprocs
; i
++) {
8887 child_status
[i
] = 0;
8888 child_status_out
[i
] = True
;
8891 start
= timeval_current();
8893 for (i
=0;i
<torture_nprocs
;i
++) {
8896 pid_t mypid
= getpid();
8897 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8899 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8902 if (torture_open_connection(¤t_cli
, i
)) break;
8904 printf("pid %d failed to start\n", (int)getpid());
8910 child_status
[i
] = getpid();
8912 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8914 child_status_out
[i
] = fn(i
);
8921 for (i
=0;i
<torture_nprocs
;i
++) {
8922 if (child_status
[i
]) synccount
++;
8924 if (synccount
== torture_nprocs
) break;
8926 } while (timeval_elapsed(&start
) < 30);
8928 if (synccount
!= torture_nprocs
) {
8929 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
8931 return timeval_elapsed(&start
);
8934 /* start the client load */
8935 start
= timeval_current();
8937 for (i
=0;i
<torture_nprocs
;i
++) {
8938 child_status
[i
] = 0;
8941 printf("%d clients started\n", torture_nprocs
);
8943 for (i
=0;i
<torture_nprocs
;i
++) {
8944 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8949 for (i
=0;i
<torture_nprocs
;i
++) {
8950 if (!child_status_out
[i
]) {
8954 return timeval_elapsed(&start
);
8957 #define FLAG_MULTIPROC 1
8964 {"FDPASS", run_fdpasstest
, 0},
8965 {"LOCK1", run_locktest1
, 0},
8966 {"LOCK2", run_locktest2
, 0},
8967 {"LOCK3", run_locktest3
, 0},
8968 {"LOCK4", run_locktest4
, 0},
8969 {"LOCK5", run_locktest5
, 0},
8970 {"LOCK6", run_locktest6
, 0},
8971 {"LOCK7", run_locktest7
, 0},
8972 {"LOCK8", run_locktest8
, 0},
8973 {"LOCK9", run_locktest9
, 0},
8974 {"UNLINK", run_unlinktest
, 0},
8975 {"BROWSE", run_browsetest
, 0},
8976 {"ATTR", run_attrtest
, 0},
8977 {"TRANS2", run_trans2test
, 0},
8978 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8979 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8980 {"RANDOMIPC", run_randomipc
, 0},
8981 {"NEGNOWAIT", run_negprot_nowait
, 0},
8982 {"NBENCH", run_nbench
, 0},
8983 {"NBENCH2", run_nbench2
, 0},
8984 {"OPLOCK1", run_oplock1
, 0},
8985 {"OPLOCK2", run_oplock2
, 0},
8986 {"OPLOCK4", run_oplock4
, 0},
8987 {"DIR", run_dirtest
, 0},
8988 {"DIR1", run_dirtest1
, 0},
8989 {"DIR-CREATETIME", run_dir_createtime
, 0},
8990 {"DENY1", torture_denytest1
, 0},
8991 {"DENY2", torture_denytest2
, 0},
8992 {"TCON", run_tcon_test
, 0},
8993 {"TCONDEV", run_tcon_devtype_test
, 0},
8994 {"RW1", run_readwritetest
, 0},
8995 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8996 {"RW3", run_readwritelarge
, 0},
8997 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8998 {"OPEN", run_opentest
, 0},
8999 {"POSIX", run_simple_posix_open_test
, 0},
9000 {"POSIX-APPEND", run_posix_append
, 0},
9001 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
9002 {"ASYNC-ECHO", run_async_echo
, 0},
9003 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
9004 { "SHORTNAME-TEST", run_shortname_test
, 0},
9005 { "ADDRCHANGE", run_addrchange
, 0},
9007 {"OPENATTR", run_openattrtest
, 0},
9009 {"XCOPY", run_xcopy
, 0},
9010 {"RENAME", run_rename
, 0},
9011 {"DELETE", run_deletetest
, 0},
9012 {"DELETE-LN", run_deletetest_ln
, 0},
9013 {"PROPERTIES", run_properties
, 0},
9014 {"MANGLE", torture_mangle
, 0},
9015 {"MANGLE1", run_mangle1
, 0},
9016 {"W2K", run_w2ktest
, 0},
9017 {"TRANS2SCAN", torture_trans2_scan
, 0},
9018 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
9019 {"UTABLE", torture_utable
, 0},
9020 {"CASETABLE", torture_casetable
, 0},
9021 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
9022 {"PIPE_NUMBER", run_pipe_number
, 0},
9023 {"TCON2", run_tcon2_test
, 0},
9024 {"IOCTL", torture_ioctl_test
, 0},
9025 {"CHKPATH", torture_chkpath_test
, 0},
9026 {"FDSESS", run_fdsesstest
, 0},
9027 { "EATEST", run_eatest
, 0},
9028 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
9029 { "CHAIN1", run_chain1
, 0},
9030 { "CHAIN2", run_chain2
, 0},
9031 { "CHAIN3", run_chain3
, 0},
9032 { "WINDOWS-WRITE", run_windows_write
, 0},
9033 { "NTTRANS-CREATE", run_nttrans_create
, 0},
9034 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
9035 { "CLI_ECHO", run_cli_echo
, 0},
9036 { "GETADDRINFO", run_getaddrinfo_send
, 0},
9037 { "TLDAP", run_tldap
},
9038 { "STREAMERROR", run_streamerror
},
9039 { "NOTIFY-BENCH", run_notify_bench
},
9040 { "NOTIFY-BENCH2", run_notify_bench2
},
9041 { "NOTIFY-BENCH3", run_notify_bench3
},
9042 { "BAD-NBT-SESSION", run_bad_nbt_session
},
9043 { "SMB-ANY-CONNECT", run_smb_any_connect
},
9044 { "NOTIFY-ONLINE", run_notify_online
},
9045 { "SMB2-BASIC", run_smb2_basic
},
9046 { "SMB2-NEGPROT", run_smb2_negprot
},
9047 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
9048 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
9049 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
9050 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
9051 { "CLEANUP1", run_cleanup1
},
9052 { "CLEANUP2", run_cleanup2
},
9053 { "CLEANUP3", run_cleanup3
},
9054 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
9055 { "LOCAL-GENCACHE", run_local_gencache
, 0},
9056 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
9057 { "LOCAL-CTDB-CONN", run_ctdb_conn
, 0},
9058 { "LOCAL-MSG", run_msg_test
, 0},
9059 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
9060 { "LOCAL-BASE64", run_local_base64
, 0},
9061 { "LOCAL-RBTREE", run_local_rbtree
, 0},
9062 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
9063 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
9064 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
9065 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
9066 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
9067 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
9068 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
9069 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
9070 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
9071 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
9072 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
9073 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
9074 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
9079 /****************************************************************************
9080 run a specified test or "ALL"
9081 ****************************************************************************/
9082 static bool run_test(const char *name
)
9089 if (strequal(name
,"ALL")) {
9090 for (i
=0;torture_ops
[i
].name
;i
++) {
9091 run_test(torture_ops
[i
].name
);
9096 for (i
=0;torture_ops
[i
].name
;i
++) {
9097 fstr_sprintf(randomfname
, "\\XX%x",
9098 (unsigned)random());
9100 if (strequal(name
, torture_ops
[i
].name
)) {
9102 printf("Running %s\n", name
);
9103 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
9104 t
= create_procs(torture_ops
[i
].fn
, &result
);
9107 printf("TEST %s FAILED!\n", name
);
9110 struct timeval start
;
9111 start
= timeval_current();
9112 if (!torture_ops
[i
].fn(0)) {
9114 printf("TEST %s FAILED!\n", name
);
9116 t
= timeval_elapsed(&start
);
9118 printf("%s took %g secs\n\n", name
, t
);
9123 printf("Did not find a test named %s\n", name
);
9131 static void usage(void)
9135 printf("WARNING samba4 test suite is much more complete nowadays.\n");
9136 printf("Please use samba4 torture.\n\n");
9138 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9140 printf("\t-d debuglevel\n");
9141 printf("\t-U user%%pass\n");
9142 printf("\t-k use kerberos\n");
9143 printf("\t-N numprocs\n");
9144 printf("\t-n my_netbios_name\n");
9145 printf("\t-W workgroup\n");
9146 printf("\t-o num_operations\n");
9147 printf("\t-O socket_options\n");
9148 printf("\t-m maximum protocol\n");
9149 printf("\t-L use oplocks\n");
9150 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
9151 printf("\t-A showall\n");
9152 printf("\t-p port\n");
9153 printf("\t-s seed\n");
9154 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
9155 printf("\t-f filename filename to test\n");
9158 printf("tests are:");
9159 for (i
=0;torture_ops
[i
].name
;i
++) {
9160 printf(" %s", torture_ops
[i
].name
);
9164 printf("default test is ALL\n");
9169 /****************************************************************************
9171 ****************************************************************************/
9172 int main(int argc
,char *argv
[])
9178 bool correct
= True
;
9179 TALLOC_CTX
*frame
= talloc_stackframe();
9180 int seed
= time(NULL
);
9182 #ifdef HAVE_SETBUFFER
9183 setbuffer(stdout
, NULL
, 0);
9186 setup_logging("smbtorture", DEBUG_STDOUT
);
9190 if (is_default_dyn_CONFIGFILE()) {
9191 if(getenv("SMB_CONF_PATH")) {
9192 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9195 lp_load_global(get_dyn_CONFIGFILE());
9202 for(p
= argv
[1]; *p
; p
++)
9206 if (strncmp(argv
[1], "//", 2)) {
9210 fstrcpy(host
, &argv
[1][2]);
9211 p
= strchr_m(&host
[2],'/');
9216 fstrcpy(share
, p
+1);
9218 fstrcpy(myname
, get_myname(talloc_tos()));
9220 fprintf(stderr
, "Failed to get my hostname.\n");
9224 if (*username
== 0 && getenv("LOGNAME")) {
9225 fstrcpy(username
,getenv("LOGNAME"));
9231 fstrcpy(workgroup
, lp_workgroup());
9233 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9237 port_to_use
= atoi(optarg
);
9240 seed
= atoi(optarg
);
9243 fstrcpy(workgroup
,optarg
);
9246 max_protocol
= interpret_protocol(optarg
, max_protocol
);
9249 torture_nprocs
= atoi(optarg
);
9252 torture_numops
= atoi(optarg
);
9255 lp_set_cmdline("log level", optarg
);
9264 local_path
= optarg
;
9267 torture_showall
= True
;
9270 fstrcpy(myname
, optarg
);
9273 client_txt
= optarg
;
9280 use_kerberos
= True
;
9282 d_printf("No kerberos support compiled in\n");
9288 fstrcpy(username
,optarg
);
9289 p
= strchr_m(username
,'%');
9292 fstrcpy(password
, p
+1);
9297 fstrcpy(multishare_conn_fname
, optarg
);
9298 use_multishare_conn
= True
;
9301 torture_blocksize
= atoi(optarg
);
9304 test_filename
= SMB_STRDUP(optarg
);
9307 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
9312 d_printf("using seed %d\n", seed
);
9316 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9319 p
= getpass("Password:");
9321 fstrcpy(password
, p
);
9326 printf("host=%s share=%s user=%s myname=%s\n",
9327 host
, share
, username
, myname
);
9329 if (argc
== optind
) {
9330 correct
= run_test("ALL");
9332 for (i
=optind
;i
<argc
;i
++) {
9333 if (!run_test(argv
[i
])) {