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 /* Test ftruncate - set file size back to zero. */
5406 status
= cli_ftruncate(cli1
, fnum1
, 0);
5407 if (!NT_STATUS_IS_OK(status
)) {
5408 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5412 status
= cli_close(cli1
, fnum1
);
5413 if (!NT_STATUS_IS_OK(status
)) {
5414 printf("close failed (%s)\n", nt_errstr(status
));
5418 /* Now open the file again for read only. */
5419 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5420 if (!NT_STATUS_IS_OK(status
)) {
5421 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5425 /* Now unlink while open. */
5426 status
= cli_posix_unlink(cli1
, fname
);
5427 if (!NT_STATUS_IS_OK(status
)) {
5428 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5432 status
= cli_close(cli1
, fnum1
);
5433 if (!NT_STATUS_IS_OK(status
)) {
5434 printf("close(2) failed (%s)\n", nt_errstr(status
));
5438 /* Ensure the file has gone. */
5439 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5440 if (NT_STATUS_IS_OK(status
)) {
5441 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5445 /* Create again to test open with O_TRUNC. */
5446 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5447 if (!NT_STATUS_IS_OK(status
)) {
5448 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5452 /* Test ftruncate - set file size. */
5453 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5454 if (!NT_STATUS_IS_OK(status
)) {
5455 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5459 /* Ensure st_size == 1000 */
5460 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5461 if (!NT_STATUS_IS_OK(status
)) {
5462 printf("stat failed (%s)\n", nt_errstr(status
));
5466 if (sbuf
.st_ex_size
!= 1000) {
5467 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5471 status
= cli_close(cli1
, fnum1
);
5472 if (!NT_STATUS_IS_OK(status
)) {
5473 printf("close(2) failed (%s)\n", nt_errstr(status
));
5477 /* Re-open with O_TRUNC. */
5478 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5479 if (!NT_STATUS_IS_OK(status
)) {
5480 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5484 /* Ensure st_size == 0 */
5485 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5486 if (!NT_STATUS_IS_OK(status
)) {
5487 printf("stat failed (%s)\n", nt_errstr(status
));
5491 if (sbuf
.st_ex_size
!= 0) {
5492 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5496 status
= cli_close(cli1
, fnum1
);
5497 if (!NT_STATUS_IS_OK(status
)) {
5498 printf("close failed (%s)\n", nt_errstr(status
));
5502 status
= cli_posix_unlink(cli1
, fname
);
5503 if (!NT_STATUS_IS_OK(status
)) {
5504 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5508 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5509 if (!NT_STATUS_IS_OK(status
)) {
5510 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5511 dname
, nt_errstr(status
));
5515 cli_close(cli1
, fnum1
);
5517 /* What happens when we try and POSIX open a directory for write ? */
5518 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5519 if (NT_STATUS_IS_OK(status
)) {
5520 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5523 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5524 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5529 /* Create the file. */
5530 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5532 if (!NT_STATUS_IS_OK(status
)) {
5533 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5537 /* Write some data into it. */
5538 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5540 if (!NT_STATUS_IS_OK(status
)) {
5541 printf("cli_write failed: %s\n", nt_errstr(status
));
5545 cli_close(cli1
, fnum1
);
5547 /* Now create a hardlink. */
5548 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5549 if (!NT_STATUS_IS_OK(status
)) {
5550 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5554 /* Now create a symlink. */
5555 status
= cli_posix_symlink(cli1
, fname
, sname
);
5556 if (!NT_STATUS_IS_OK(status
)) {
5557 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5561 /* Open the hardlink for read. */
5562 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5563 if (!NT_STATUS_IS_OK(status
)) {
5564 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5568 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5569 if (!NT_STATUS_IS_OK(status
)) {
5570 printf("POSIX read of %s failed (%s)\n", hname
,
5573 } else if (nread
!= 10) {
5574 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5575 hname
, (unsigned long)nread
, 10);
5579 if (memcmp(buf
, "TEST DATA\n", 10)) {
5580 printf("invalid data read from hardlink\n");
5584 /* Do a POSIX lock/unlock. */
5585 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5586 if (!NT_STATUS_IS_OK(status
)) {
5587 printf("POSIX lock failed %s\n", nt_errstr(status
));
5591 /* Punch a hole in the locked area. */
5592 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5593 if (!NT_STATUS_IS_OK(status
)) {
5594 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5598 cli_close(cli1
, fnum1
);
5600 /* Open the symlink for read - this should fail. A POSIX
5601 client should not be doing opens on a symlink. */
5602 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5603 if (NT_STATUS_IS_OK(status
)) {
5604 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5607 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5608 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5609 printf("POSIX open of %s should have failed "
5610 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5611 "failed with %s instead.\n",
5612 sname
, nt_errstr(status
));
5617 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5618 if (!NT_STATUS_IS_OK(status
)) {
5619 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5623 if (strcmp(namebuf
, fname
) != 0) {
5624 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5625 sname
, fname
, namebuf
);
5629 status
= cli_posix_rmdir(cli1
, dname
);
5630 if (!NT_STATUS_IS_OK(status
)) {
5631 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5635 printf("Simple POSIX open test passed\n");
5640 if (fnum1
!= (uint16_t)-1) {
5641 cli_close(cli1
, fnum1
);
5642 fnum1
= (uint16_t)-1;
5645 cli_setatr(cli1
, sname
, 0, 0);
5646 cli_posix_unlink(cli1
, sname
);
5647 cli_setatr(cli1
, hname
, 0, 0);
5648 cli_posix_unlink(cli1
, hname
);
5649 cli_setatr(cli1
, fname
, 0, 0);
5650 cli_posix_unlink(cli1
, fname
);
5651 cli_setatr(cli1
, dname
, 0, 0);
5652 cli_posix_rmdir(cli1
, dname
);
5654 if (!torture_close_connection(cli1
)) {
5662 static uint32 open_attrs_table
[] = {
5663 FILE_ATTRIBUTE_NORMAL
,
5664 FILE_ATTRIBUTE_ARCHIVE
,
5665 FILE_ATTRIBUTE_READONLY
,
5666 FILE_ATTRIBUTE_HIDDEN
,
5667 FILE_ATTRIBUTE_SYSTEM
,
5669 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5670 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5671 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5672 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5673 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5674 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5676 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5677 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5678 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5679 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5682 struct trunc_open_results
{
5689 static struct trunc_open_results attr_results
[] = {
5690 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5691 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5692 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5693 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5694 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5695 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5696 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5697 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5698 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5699 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5700 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5701 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5702 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5703 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5704 { 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
},
5705 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5706 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5707 { 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
},
5708 { 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
},
5709 { 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
},
5710 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5711 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5712 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5713 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5714 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5715 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5718 static bool run_openattrtest(int dummy
)
5720 static struct cli_state
*cli1
;
5721 const char *fname
= "\\openattr.file";
5723 bool correct
= True
;
5725 unsigned int i
, j
, k
, l
;
5728 printf("starting open attr test\n");
5730 if (!torture_open_connection(&cli1
, 0)) {
5734 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
5736 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5737 cli_setatr(cli1
, fname
, 0, 0);
5738 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5740 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5741 open_attrs_table
[i
], FILE_SHARE_NONE
,
5742 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5743 if (!NT_STATUS_IS_OK(status
)) {
5744 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5748 status
= cli_close(cli1
, fnum1
);
5749 if (!NT_STATUS_IS_OK(status
)) {
5750 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5754 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5755 status
= cli_ntcreate(cli1
, fname
, 0,
5756 FILE_READ_DATA
|FILE_WRITE_DATA
,
5757 open_attrs_table
[j
],
5758 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5760 if (!NT_STATUS_IS_OK(status
)) {
5761 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5762 if (attr_results
[l
].num
== k
) {
5763 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5764 k
, open_attrs_table
[i
],
5765 open_attrs_table
[j
],
5766 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5771 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5772 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5773 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5778 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5784 status
= cli_close(cli1
, fnum1
);
5785 if (!NT_STATUS_IS_OK(status
)) {
5786 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5790 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5791 if (!NT_STATUS_IS_OK(status
)) {
5792 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5797 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5798 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5801 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5802 if (attr_results
[l
].num
== k
) {
5803 if (attr
!= attr_results
[l
].result_attr
||
5804 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5805 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5806 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5807 open_attrs_table
[i
],
5808 open_attrs_table
[j
],
5810 attr_results
[l
].result_attr
);
5820 cli_setatr(cli1
, fname
, 0, 0);
5821 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5823 printf("open attr test %s.\n", correct
? "passed" : "failed");
5825 if (!torture_close_connection(cli1
)) {
5831 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5832 const char *name
, void *state
)
5834 int *matched
= (int *)state
;
5835 if (matched
!= NULL
) {
5838 return NT_STATUS_OK
;
5842 test directory listing speed
5844 static bool run_dirtest(int dummy
)
5847 static struct cli_state
*cli
;
5849 struct timeval core_start
;
5850 bool correct
= True
;
5853 printf("starting directory test\n");
5855 if (!torture_open_connection(&cli
, 0)) {
5859 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
5862 for (i
=0;i
<torture_numops
;i
++) {
5864 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5865 if (!NT_STATUS_IS_OK(cli_openx(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5866 fprintf(stderr
,"Failed to open %s\n", fname
);
5869 cli_close(cli
, fnum
);
5872 core_start
= timeval_current();
5875 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5876 printf("Matched %d\n", matched
);
5879 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5880 printf("Matched %d\n", matched
);
5883 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5884 printf("Matched %d\n", matched
);
5886 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5889 for (i
=0;i
<torture_numops
;i
++) {
5891 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5892 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5895 if (!torture_close_connection(cli
)) {
5899 printf("finished dirtest\n");
5904 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5907 struct cli_state
*pcli
= (struct cli_state
*)state
;
5909 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5911 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5912 return NT_STATUS_OK
;
5914 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
5915 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5916 printf("del_fn: failed to rmdir %s\n,", fname
);
5918 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
5919 printf("del_fn: failed to unlink %s\n,", fname
);
5921 return NT_STATUS_OK
;
5926 sees what IOCTLs are supported
5928 bool torture_ioctl_test(int dummy
)
5930 static struct cli_state
*cli
;
5931 uint16_t device
, function
;
5933 const char *fname
= "\\ioctl.dat";
5937 if (!torture_open_connection(&cli
, 0)) {
5941 printf("starting ioctl test\n");
5943 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5945 status
= cli_openx(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5946 if (!NT_STATUS_IS_OK(status
)) {
5947 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5951 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5952 printf("ioctl device info: %s\n", nt_errstr(status
));
5954 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5955 printf("ioctl job info: %s\n", nt_errstr(status
));
5957 for (device
=0;device
<0x100;device
++) {
5958 printf("ioctl test with device = 0x%x\n", device
);
5959 for (function
=0;function
<0x100;function
++) {
5960 uint32 code
= (device
<<16) | function
;
5962 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5964 if (NT_STATUS_IS_OK(status
)) {
5965 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5967 data_blob_free(&blob
);
5972 if (!torture_close_connection(cli
)) {
5981 tries varients of chkpath
5983 bool torture_chkpath_test(int dummy
)
5985 static struct cli_state
*cli
;
5990 if (!torture_open_connection(&cli
, 0)) {
5994 printf("starting chkpath test\n");
5996 /* cleanup from an old run */
5997 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5998 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5999 cli_rmdir(cli
, "\\chkpath.dir");
6001 status
= cli_mkdir(cli
, "\\chkpath.dir");
6002 if (!NT_STATUS_IS_OK(status
)) {
6003 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6007 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6008 if (!NT_STATUS_IS_OK(status
)) {
6009 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6013 status
= cli_openx(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6015 if (!NT_STATUS_IS_OK(status
)) {
6016 printf("open1 failed (%s)\n", nt_errstr(status
));
6019 cli_close(cli
, fnum
);
6021 status
= cli_chkpath(cli
, "\\chkpath.dir");
6022 if (!NT_STATUS_IS_OK(status
)) {
6023 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6027 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6028 if (!NT_STATUS_IS_OK(status
)) {
6029 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6033 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6034 if (!NT_STATUS_IS_OK(status
)) {
6035 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6036 NT_STATUS_NOT_A_DIRECTORY
);
6038 printf("* chkpath on a file should fail\n");
6042 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6043 if (!NT_STATUS_IS_OK(status
)) {
6044 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6045 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6047 printf("* chkpath on a non existant file should fail\n");
6051 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6052 if (!NT_STATUS_IS_OK(status
)) {
6053 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6054 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6056 printf("* chkpath on a non existent component should fail\n");
6060 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6061 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6062 cli_rmdir(cli
, "\\chkpath.dir");
6064 if (!torture_close_connection(cli
)) {
6071 static bool run_eatest(int dummy
)
6073 static struct cli_state
*cli
;
6074 const char *fname
= "\\eatest.txt";
6075 bool correct
= True
;
6079 struct ea_struct
*ea_list
= NULL
;
6080 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6083 printf("starting eatest\n");
6085 if (!torture_open_connection(&cli
, 0)) {
6086 talloc_destroy(mem_ctx
);
6090 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6092 status
= cli_ntcreate(cli
, fname
, 0,
6093 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6094 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6096 if (!NT_STATUS_IS_OK(status
)) {
6097 printf("open failed - %s\n", nt_errstr(status
));
6098 talloc_destroy(mem_ctx
);
6102 for (i
= 0; i
< 10; i
++) {
6103 fstring ea_name
, ea_val
;
6105 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6106 memset(ea_val
, (char)i
+1, i
+1);
6107 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6108 if (!NT_STATUS_IS_OK(status
)) {
6109 printf("ea_set of name %s failed - %s\n", ea_name
,
6111 talloc_destroy(mem_ctx
);
6116 cli_close(cli
, fnum
);
6117 for (i
= 0; i
< 10; i
++) {
6118 fstring ea_name
, ea_val
;
6120 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6121 memset(ea_val
, (char)i
+1, i
+1);
6122 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6123 if (!NT_STATUS_IS_OK(status
)) {
6124 printf("ea_set of name %s failed - %s\n", ea_name
,
6126 talloc_destroy(mem_ctx
);
6131 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6132 if (!NT_STATUS_IS_OK(status
)) {
6133 printf("ea_get list failed - %s\n", nt_errstr(status
));
6137 printf("num_eas = %d\n", (int)num_eas
);
6139 if (num_eas
!= 20) {
6140 printf("Should be 20 EA's stored... failing.\n");
6144 for (i
= 0; i
< num_eas
; i
++) {
6145 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6146 dump_data(0, ea_list
[i
].value
.data
,
6147 ea_list
[i
].value
.length
);
6150 /* Setting EA's to zero length deletes them. Test this */
6151 printf("Now deleting all EA's - case indepenent....\n");
6154 cli_set_ea_path(cli
, fname
, "", "", 0);
6156 for (i
= 0; i
< 20; i
++) {
6158 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6159 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6160 if (!NT_STATUS_IS_OK(status
)) {
6161 printf("ea_set of name %s failed - %s\n", ea_name
,
6163 talloc_destroy(mem_ctx
);
6169 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6170 if (!NT_STATUS_IS_OK(status
)) {
6171 printf("ea_get list failed - %s\n", nt_errstr(status
));
6175 printf("num_eas = %d\n", (int)num_eas
);
6176 for (i
= 0; i
< num_eas
; i
++) {
6177 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6178 dump_data(0, ea_list
[i
].value
.data
,
6179 ea_list
[i
].value
.length
);
6183 printf("deleting EA's failed.\n");
6187 /* Try and delete a non existant EA. */
6188 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6189 if (!NT_STATUS_IS_OK(status
)) {
6190 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6195 talloc_destroy(mem_ctx
);
6196 if (!torture_close_connection(cli
)) {
6203 static bool run_dirtest1(int dummy
)
6206 static struct cli_state
*cli
;
6209 bool correct
= True
;
6211 printf("starting directory test\n");
6213 if (!torture_open_connection(&cli
, 0)) {
6217 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
6219 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6220 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6221 cli_rmdir(cli
, "\\LISTDIR");
6222 cli_mkdir(cli
, "\\LISTDIR");
6224 /* Create 1000 files and 1000 directories. */
6225 for (i
=0;i
<1000;i
++) {
6227 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6228 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6229 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6230 fprintf(stderr
,"Failed to open %s\n", fname
);
6233 cli_close(cli
, fnum
);
6235 for (i
=0;i
<1000;i
++) {
6237 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6238 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6239 fprintf(stderr
,"Failed to open %s\n", fname
);
6244 /* Now ensure that doing an old list sees both files and directories. */
6246 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6247 printf("num_seen = %d\n", num_seen
);
6248 /* We should see 100 files + 1000 directories + . and .. */
6249 if (num_seen
!= 2002)
6252 /* Ensure if we have the "must have" bits we only see the
6256 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6257 printf("num_seen = %d\n", num_seen
);
6258 if (num_seen
!= 1002)
6262 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6263 printf("num_seen = %d\n", num_seen
);
6264 if (num_seen
!= 1000)
6267 /* Delete everything. */
6268 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6269 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6270 cli_rmdir(cli
, "\\LISTDIR");
6273 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6274 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6275 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6278 if (!torture_close_connection(cli
)) {
6282 printf("finished dirtest1\n");
6287 static bool run_error_map_extract(int dummy
) {
6289 static struct cli_state
*c_dos
;
6290 static struct cli_state
*c_nt
;
6302 /* NT-Error connection */
6304 disable_spnego
= true;
6305 if (!(c_nt
= open_nbt_connection())) {
6306 disable_spnego
= false;
6309 disable_spnego
= false;
6311 status
= smbXcli_negprot(c_nt
->conn
, c_nt
->timeout
, PROTOCOL_CORE
,
6314 if (!NT_STATUS_IS_OK(status
)) {
6315 printf("%s rejected the NT-error negprot (%s)\n", host
,
6321 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6322 if (!NT_STATUS_IS_OK(status
)) {
6323 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6327 /* DOS-Error connection */
6329 disable_spnego
= true;
6330 force_dos_errors
= true;
6331 if (!(c_dos
= open_nbt_connection())) {
6332 disable_spnego
= false;
6333 force_dos_errors
= false;
6336 disable_spnego
= false;
6337 force_dos_errors
= false;
6339 status
= smbXcli_negprot(c_dos
->conn
, c_dos
->timeout
, PROTOCOL_CORE
,
6341 if (!NT_STATUS_IS_OK(status
)) {
6342 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6344 cli_shutdown(c_dos
);
6348 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6349 if (!NT_STATUS_IS_OK(status
)) {
6350 printf("%s rejected the DOS-error initial session setup (%s)\n",
6351 host
, nt_errstr(status
));
6355 c_nt
->map_dos_errors
= false;
6356 c_dos
->map_dos_errors
= false;
6358 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6359 fstr_sprintf(user
, "%X", error
);
6361 status
= cli_session_setup(c_nt
, user
,
6362 password
, strlen(password
),
6363 password
, strlen(password
),
6365 if (NT_STATUS_IS_OK(status
)) {
6366 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6369 /* Case #1: 32-bit NT errors */
6370 if (!NT_STATUS_IS_DOS(status
)) {
6373 printf("/** Dos error on NT connection! (%s) */\n",
6375 nt_status
= NT_STATUS(0xc0000000);
6378 status
= cli_session_setup(c_dos
, user
,
6379 password
, strlen(password
),
6380 password
, strlen(password
),
6382 if (NT_STATUS_IS_OK(status
)) {
6383 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6386 /* Case #1: 32-bit NT errors */
6387 if (NT_STATUS_IS_DOS(status
)) {
6388 printf("/** NT error on DOS connection! (%s) */\n",
6390 errnum
= errclass
= 0;
6392 errclass
= NT_STATUS_DOS_CLASS(status
);
6393 errnum
= NT_STATUS_DOS_CODE(status
);
6396 if (NT_STATUS_V(nt_status
) != error
) {
6397 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6398 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6399 get_nt_error_c_code(talloc_tos(), nt_status
));
6402 printf("\t{%s,\t%s,\t%s},\n",
6403 smb_dos_err_class(errclass
),
6404 smb_dos_err_name(errclass
, errnum
),
6405 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6410 static bool run_sesssetup_bench(int dummy
)
6412 static struct cli_state
*c
;
6413 const char *fname
= "\\file.dat";
6418 if (!torture_open_connection(&c
, 0)) {
6422 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6423 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6424 FILE_DELETE_ON_CLOSE
, 0, &fnum
);
6425 if (!NT_STATUS_IS_OK(status
)) {
6426 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6430 for (i
=0; i
<torture_numops
; i
++) {
6431 status
= cli_session_setup(
6433 password
, strlen(password
),
6434 password
, strlen(password
),
6436 if (!NT_STATUS_IS_OK(status
)) {
6437 d_printf("(%s) cli_session_setup failed: %s\n",
6438 __location__
, nt_errstr(status
));
6442 d_printf("\r%d ", (int)cli_state_get_uid(c
));
6444 status
= cli_ulogoff(c
);
6445 if (!NT_STATUS_IS_OK(status
)) {
6446 d_printf("(%s) cli_ulogoff failed: %s\n",
6447 __location__
, nt_errstr(status
));
6455 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6456 uid_t uid
, gid_t gid
, const char *expected
)
6461 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
6463 if (strcmp(subst
, expected
) != 0) {
6464 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6465 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6474 static void chain1_open_completion(struct tevent_req
*req
)
6478 status
= cli_openx_recv(req
, &fnum
);
6481 d_printf("cli_openx_recv returned %s: %d\n",
6483 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6486 static void chain1_write_completion(struct tevent_req
*req
)
6490 status
= cli_write_andx_recv(req
, &written
);
6493 d_printf("cli_write_andx_recv returned %s: %d\n",
6495 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6498 static void chain1_close_completion(struct tevent_req
*req
)
6501 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6503 status
= cli_close_recv(req
);
6508 d_printf("cli_close returned %s\n", nt_errstr(status
));
6511 static bool run_chain1(int dummy
)
6513 struct cli_state
*cli1
;
6514 struct event_context
*evt
= event_context_init(NULL
);
6515 struct tevent_req
*reqs
[3], *smbreqs
[3];
6517 const char *str
= "foobar";
6520 printf("starting chain1 test\n");
6521 if (!torture_open_connection(&cli1
, 0)) {
6525 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6527 reqs
[0] = cli_openx_create(talloc_tos(), evt
, cli1
, "\\test",
6528 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6529 if (reqs
[0] == NULL
) return false;
6530 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6533 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6534 (const uint8_t *)str
, 0, strlen(str
)+1,
6535 smbreqs
, 1, &smbreqs
[1]);
6536 if (reqs
[1] == NULL
) return false;
6537 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6539 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6540 if (reqs
[2] == NULL
) return false;
6541 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6543 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6544 if (!NT_STATUS_IS_OK(status
)) {
6549 tevent_loop_once(evt
);
6552 torture_close_connection(cli1
);
6556 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6559 status
= cli_session_setup_guest_recv(req
);
6560 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6563 static void chain2_tcon_completion(struct tevent_req
*req
)
6565 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6567 status
= cli_tcon_andx_recv(req
);
6568 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6572 static bool run_chain2(int dummy
)
6574 struct cli_state
*cli1
;
6575 struct event_context
*evt
= event_context_init(NULL
);
6576 struct tevent_req
*reqs
[2], *smbreqs
[2];
6580 printf("starting chain2 test\n");
6581 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6582 port_to_use
, SMB_SIGNING_DEFAULT
, 0);
6583 if (!NT_STATUS_IS_OK(status
)) {
6587 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
6589 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6591 if (reqs
[0] == NULL
) return false;
6592 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6594 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6595 "?????", NULL
, 0, &smbreqs
[1]);
6596 if (reqs
[1] == NULL
) return false;
6597 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6599 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6600 if (!NT_STATUS_IS_OK(status
)) {
6605 tevent_loop_once(evt
);
6608 torture_close_connection(cli1
);
6613 struct torture_createdel_state
{
6614 struct tevent_context
*ev
;
6615 struct cli_state
*cli
;
6618 static void torture_createdel_created(struct tevent_req
*subreq
);
6619 static void torture_createdel_closed(struct tevent_req
*subreq
);
6621 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6622 struct tevent_context
*ev
,
6623 struct cli_state
*cli
,
6626 struct tevent_req
*req
, *subreq
;
6627 struct torture_createdel_state
*state
;
6629 req
= tevent_req_create(mem_ctx
, &state
,
6630 struct torture_createdel_state
);
6637 subreq
= cli_ntcreate_send(
6638 state
, ev
, cli
, name
, 0,
6639 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6640 FILE_ATTRIBUTE_NORMAL
,
6641 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6642 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6644 if (tevent_req_nomem(subreq
, req
)) {
6645 return tevent_req_post(req
, ev
);
6647 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6651 static void torture_createdel_created(struct tevent_req
*subreq
)
6653 struct tevent_req
*req
= tevent_req_callback_data(
6654 subreq
, struct tevent_req
);
6655 struct torture_createdel_state
*state
= tevent_req_data(
6656 req
, struct torture_createdel_state
);
6660 status
= cli_ntcreate_recv(subreq
, &fnum
);
6661 TALLOC_FREE(subreq
);
6662 if (!NT_STATUS_IS_OK(status
)) {
6663 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6664 nt_errstr(status
)));
6665 tevent_req_nterror(req
, status
);
6669 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6670 if (tevent_req_nomem(subreq
, req
)) {
6673 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6676 static void torture_createdel_closed(struct tevent_req
*subreq
)
6678 struct tevent_req
*req
= tevent_req_callback_data(
6679 subreq
, struct tevent_req
);
6682 status
= cli_close_recv(subreq
);
6683 if (!NT_STATUS_IS_OK(status
)) {
6684 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6685 tevent_req_nterror(req
, status
);
6688 tevent_req_done(req
);
6691 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6693 return tevent_req_simple_recv_ntstatus(req
);
6696 struct torture_createdels_state
{
6697 struct tevent_context
*ev
;
6698 struct cli_state
*cli
;
6699 const char *base_name
;
6703 struct tevent_req
**reqs
;
6706 static void torture_createdels_done(struct tevent_req
*subreq
);
6708 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6709 struct tevent_context
*ev
,
6710 struct cli_state
*cli
,
6711 const char *base_name
,
6715 struct tevent_req
*req
;
6716 struct torture_createdels_state
*state
;
6719 req
= tevent_req_create(mem_ctx
, &state
,
6720 struct torture_createdels_state
);
6726 state
->base_name
= talloc_strdup(state
, base_name
);
6727 if (tevent_req_nomem(state
->base_name
, req
)) {
6728 return tevent_req_post(req
, ev
);
6730 state
->num_files
= MAX(num_parallel
, num_files
);
6732 state
->received
= 0;
6734 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6735 if (tevent_req_nomem(state
->reqs
, req
)) {
6736 return tevent_req_post(req
, ev
);
6739 for (i
=0; i
<num_parallel
; i
++) {
6742 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6744 if (tevent_req_nomem(name
, req
)) {
6745 return tevent_req_post(req
, ev
);
6747 state
->reqs
[i
] = torture_createdel_send(
6748 state
->reqs
, state
->ev
, state
->cli
, name
);
6749 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6750 return tevent_req_post(req
, ev
);
6752 name
= talloc_move(state
->reqs
[i
], &name
);
6753 tevent_req_set_callback(state
->reqs
[i
],
6754 torture_createdels_done
, req
);
6760 static void torture_createdels_done(struct tevent_req
*subreq
)
6762 struct tevent_req
*req
= tevent_req_callback_data(
6763 subreq
, struct tevent_req
);
6764 struct torture_createdels_state
*state
= tevent_req_data(
6765 req
, struct torture_createdels_state
);
6766 size_t num_parallel
= talloc_array_length(state
->reqs
);
6771 status
= torture_createdel_recv(subreq
);
6772 if (!NT_STATUS_IS_OK(status
)){
6773 DEBUG(10, ("torture_createdel_recv returned %s\n",
6774 nt_errstr(status
)));
6775 TALLOC_FREE(subreq
);
6776 tevent_req_nterror(req
, status
);
6780 for (i
=0; i
<num_parallel
; i
++) {
6781 if (subreq
== state
->reqs
[i
]) {
6785 if (i
== num_parallel
) {
6786 DEBUG(10, ("received something we did not send\n"));
6787 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6790 TALLOC_FREE(state
->reqs
[i
]);
6792 if (state
->sent
>= state
->num_files
) {
6793 tevent_req_done(req
);
6797 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6799 if (tevent_req_nomem(name
, req
)) {
6802 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6804 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6807 name
= talloc_move(state
->reqs
[i
], &name
);
6808 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6812 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6814 return tevent_req_simple_recv_ntstatus(req
);
6817 struct swallow_notify_state
{
6818 struct tevent_context
*ev
;
6819 struct cli_state
*cli
;
6821 uint32_t completion_filter
;
6823 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6827 static void swallow_notify_done(struct tevent_req
*subreq
);
6829 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6830 struct tevent_context
*ev
,
6831 struct cli_state
*cli
,
6833 uint32_t completion_filter
,
6835 bool (*fn
)(uint32_t action
,
6840 struct tevent_req
*req
, *subreq
;
6841 struct swallow_notify_state
*state
;
6843 req
= tevent_req_create(mem_ctx
, &state
,
6844 struct swallow_notify_state
);
6851 state
->completion_filter
= completion_filter
;
6852 state
->recursive
= recursive
;
6856 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6857 0xffff, state
->completion_filter
,
6859 if (tevent_req_nomem(subreq
, req
)) {
6860 return tevent_req_post(req
, ev
);
6862 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6866 static void swallow_notify_done(struct tevent_req
*subreq
)
6868 struct tevent_req
*req
= tevent_req_callback_data(
6869 subreq
, struct tevent_req
);
6870 struct swallow_notify_state
*state
= tevent_req_data(
6871 req
, struct swallow_notify_state
);
6873 uint32_t i
, num_changes
;
6874 struct notify_change
*changes
;
6876 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6877 TALLOC_FREE(subreq
);
6878 if (!NT_STATUS_IS_OK(status
)) {
6879 DEBUG(10, ("cli_notify_recv returned %s\n",
6880 nt_errstr(status
)));
6881 tevent_req_nterror(req
, status
);
6885 for (i
=0; i
<num_changes
; i
++) {
6886 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6888 TALLOC_FREE(changes
);
6890 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6891 0xffff, state
->completion_filter
,
6893 if (tevent_req_nomem(subreq
, req
)) {
6896 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6899 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6901 if (DEBUGLEVEL
> 5) {
6902 d_printf("%d %s\n", (int)action
, name
);
6907 static void notify_bench_done(struct tevent_req
*req
)
6909 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6913 static bool run_notify_bench(int dummy
)
6915 const char *dname
= "\\notify-bench";
6916 struct tevent_context
*ev
;
6919 struct tevent_req
*req1
;
6920 struct tevent_req
*req2
= NULL
;
6921 int i
, num_unc_names
;
6922 int num_finished
= 0;
6924 printf("starting notify-bench test\n");
6926 if (use_multishare_conn
) {
6928 unc_list
= file_lines_load(multishare_conn_fname
,
6929 &num_unc_names
, 0, NULL
);
6930 if (!unc_list
|| num_unc_names
<= 0) {
6931 d_printf("Failed to load unc names list from '%s'\n",
6932 multishare_conn_fname
);
6935 TALLOC_FREE(unc_list
);
6940 ev
= tevent_context_init(talloc_tos());
6942 d_printf("tevent_context_init failed\n");
6946 for (i
=0; i
<num_unc_names
; i
++) {
6947 struct cli_state
*cli
;
6950 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6952 if (base_fname
== NULL
) {
6956 if (!torture_open_connection(&cli
, i
)) {
6960 status
= cli_ntcreate(cli
, dname
, 0,
6961 MAXIMUM_ALLOWED_ACCESS
,
6962 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6964 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6967 if (!NT_STATUS_IS_OK(status
)) {
6968 d_printf("Could not create %s: %s\n", dname
,
6973 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6974 FILE_NOTIFY_CHANGE_FILE_NAME
|
6975 FILE_NOTIFY_CHANGE_DIR_NAME
|
6976 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6977 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6978 false, print_notifies
, NULL
);
6980 d_printf("Could not create notify request\n");
6984 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6985 base_fname
, 10, torture_numops
);
6987 d_printf("Could not create createdels request\n");
6990 TALLOC_FREE(base_fname
);
6992 tevent_req_set_callback(req2
, notify_bench_done
,
6996 while (num_finished
< num_unc_names
) {
6998 ret
= tevent_loop_once(ev
);
7000 d_printf("tevent_loop_once failed\n");
7005 if (!tevent_req_poll(req2
, ev
)) {
7006 d_printf("tevent_req_poll failed\n");
7009 status
= torture_createdels_recv(req2
);
7010 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7015 static bool run_mangle1(int dummy
)
7017 struct cli_state
*cli
;
7018 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7022 time_t change_time
, access_time
, write_time
;
7026 printf("starting mangle1 test\n");
7027 if (!torture_open_connection(&cli
, 0)) {
7031 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7033 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7034 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7036 if (!NT_STATUS_IS_OK(status
)) {
7037 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7040 cli_close(cli
, fnum
);
7042 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7043 if (!NT_STATUS_IS_OK(status
)) {
7044 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7048 d_printf("alt_name: %s\n", alt_name
);
7050 status
= cli_openx(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7051 if (!NT_STATUS_IS_OK(status
)) {
7052 d_printf("cli_openx(%s) failed: %s\n", alt_name
,
7056 cli_close(cli
, fnum
);
7058 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7059 &write_time
, &size
, &mode
);
7060 if (!NT_STATUS_IS_OK(status
)) {
7061 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7069 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7071 size_t *to_pull
= (size_t *)priv
;
7072 size_t thistime
= *to_pull
;
7074 thistime
= MIN(thistime
, n
);
7075 if (thistime
== 0) {
7079 memset(buf
, 0, thistime
);
7080 *to_pull
-= thistime
;
7084 static bool run_windows_write(int dummy
)
7086 struct cli_state
*cli1
;
7090 const char *fname
= "\\writetest.txt";
7091 struct timeval start_time
;
7096 printf("starting windows_write test\n");
7097 if (!torture_open_connection(&cli1
, 0)) {
7101 status
= cli_openx(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7102 if (!NT_STATUS_IS_OK(status
)) {
7103 printf("open failed (%s)\n", nt_errstr(status
));
7107 smbXcli_conn_set_sockopt(cli1
->conn
, sockops
);
7109 start_time
= timeval_current();
7111 for (i
=0; i
<torture_numops
; i
++) {
7113 off_t start
= i
* torture_blocksize
;
7114 size_t to_pull
= torture_blocksize
- 1;
7116 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7117 start
+ torture_blocksize
- 1, 1, NULL
);
7118 if (!NT_STATUS_IS_OK(status
)) {
7119 printf("cli_write failed: %s\n", nt_errstr(status
));
7123 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7124 null_source
, &to_pull
);
7125 if (!NT_STATUS_IS_OK(status
)) {
7126 printf("cli_push returned: %s\n", nt_errstr(status
));
7131 seconds
= timeval_elapsed(&start_time
);
7132 kbytes
= (double)torture_blocksize
* torture_numops
;
7135 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7136 (double)seconds
, (int)(kbytes
/seconds
));
7140 cli_close(cli1
, fnum
);
7141 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7142 torture_close_connection(cli1
);
7146 static bool run_cli_echo(int dummy
)
7148 struct cli_state
*cli
;
7151 printf("starting cli_echo test\n");
7152 if (!torture_open_connection(&cli
, 0)) {
7155 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7157 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7159 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7161 torture_close_connection(cli
);
7162 return NT_STATUS_IS_OK(status
);
7165 static bool run_uid_regression_test(int dummy
)
7167 static struct cli_state
*cli
;
7170 bool correct
= True
;
7173 printf("starting uid regression test\n");
7175 if (!torture_open_connection(&cli
, 0)) {
7179 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7181 /* Ok - now save then logoff our current user. */
7182 old_vuid
= cli_state_get_uid(cli
);
7184 status
= cli_ulogoff(cli
);
7185 if (!NT_STATUS_IS_OK(status
)) {
7186 d_printf("(%s) cli_ulogoff failed: %s\n",
7187 __location__
, nt_errstr(status
));
7192 cli_state_set_uid(cli
, old_vuid
);
7194 /* Try an operation. */
7195 status
= cli_mkdir(cli
, "\\uid_reg_test");
7196 if (NT_STATUS_IS_OK(status
)) {
7197 d_printf("(%s) cli_mkdir succeeded\n",
7202 /* Should be bad uid. */
7203 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
7204 NT_STATUS_USER_SESSION_DELETED
)) {
7210 old_cnum
= cli_state_get_tid(cli
);
7212 /* Now try a SMBtdis with the invald vuid set to zero. */
7213 cli_state_set_uid(cli
, 0);
7215 /* This should succeed. */
7216 status
= cli_tdis(cli
);
7218 if (NT_STATUS_IS_OK(status
)) {
7219 d_printf("First tdis with invalid vuid should succeed.\n");
7221 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7226 cli_state_set_uid(cli
, old_vuid
);
7227 cli_state_set_tid(cli
, old_cnum
);
7229 /* This should fail. */
7230 status
= cli_tdis(cli
);
7231 if (NT_STATUS_IS_OK(status
)) {
7232 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7236 /* Should be bad tid. */
7237 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
7238 NT_STATUS_NETWORK_NAME_DELETED
)) {
7244 cli_rmdir(cli
, "\\uid_reg_test");
7253 static const char *illegal_chars
= "*\\/?<>|\":";
7254 static char force_shortname_chars
[] = " +,.[];=\177";
7256 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7257 const char *mask
, void *state
)
7259 struct cli_state
*pcli
= (struct cli_state
*)state
;
7261 NTSTATUS status
= NT_STATUS_OK
;
7263 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7265 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7266 return NT_STATUS_OK
;
7268 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7269 status
= cli_rmdir(pcli
, fname
);
7270 if (!NT_STATUS_IS_OK(status
)) {
7271 printf("del_fn: failed to rmdir %s\n,", fname
);
7274 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7275 if (!NT_STATUS_IS_OK(status
)) {
7276 printf("del_fn: failed to unlink %s\n,", fname
);
7288 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7289 const char *name
, void *state
)
7291 struct sn_state
*s
= (struct sn_state
*)state
;
7295 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7296 i
, finfo
->name
, finfo
->short_name
);
7299 if (strchr(force_shortname_chars
, i
)) {
7300 if (!finfo
->short_name
) {
7301 /* Shortname not created when it should be. */
7302 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7303 __location__
, finfo
->name
, i
);
7306 } else if (finfo
->short_name
){
7307 /* Shortname created when it should not be. */
7308 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7309 __location__
, finfo
->short_name
, finfo
->name
);
7313 return NT_STATUS_OK
;
7316 static bool run_shortname_test(int dummy
)
7318 static struct cli_state
*cli
;
7319 bool correct
= True
;
7325 printf("starting shortname test\n");
7327 if (!torture_open_connection(&cli
, 0)) {
7331 smbXcli_conn_set_sockopt(cli
->conn
, sockops
);
7333 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7334 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7335 cli_rmdir(cli
, "\\shortname");
7337 status
= cli_mkdir(cli
, "\\shortname");
7338 if (!NT_STATUS_IS_OK(status
)) {
7339 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7340 __location__
, nt_errstr(status
));
7345 if (strlcpy(fname
, "\\shortname\\", sizeof(fname
)) >= sizeof(fname
)) {
7349 if (strlcat(fname
, "test .txt", sizeof(fname
)) >= sizeof(fname
)) {
7356 for (i
= 32; i
< 128; i
++) {
7357 uint16_t fnum
= (uint16_t)-1;
7361 if (strchr(illegal_chars
, i
)) {
7366 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7367 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
7368 if (!NT_STATUS_IS_OK(status
)) {
7369 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7370 __location__
, fname
, nt_errstr(status
));
7374 cli_close(cli
, fnum
);
7377 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7378 shortname_list_fn
, &s
);
7379 if (s
.matched
!= 1) {
7380 d_printf("(%s) failed to list %s: %s\n",
7381 __location__
, fname
, nt_errstr(status
));
7386 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7387 if (!NT_STATUS_IS_OK(status
)) {
7388 d_printf("(%s) failed to delete %s: %s\n",
7389 __location__
, fname
, nt_errstr(status
));
7402 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7403 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7404 cli_rmdir(cli
, "\\shortname");
7405 torture_close_connection(cli
);
7409 static void pagedsearch_cb(struct tevent_req
*req
)
7412 struct tldap_message
*msg
;
7415 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7416 if (rc
!= TLDAP_SUCCESS
) {
7417 d_printf("tldap_search_paged_recv failed: %s\n",
7418 tldap_err2string(rc
));
7421 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7425 if (!tldap_entry_dn(msg
, &dn
)) {
7426 d_printf("tldap_entry_dn failed\n");
7429 d_printf("%s\n", dn
);
7433 static bool run_tldap(int dummy
)
7435 struct tldap_context
*ld
;
7438 struct sockaddr_storage addr
;
7439 struct tevent_context
*ev
;
7440 struct tevent_req
*req
;
7444 if (!resolve_name(host
, &addr
, 0, false)) {
7445 d_printf("could not find host %s\n", host
);
7448 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7449 if (!NT_STATUS_IS_OK(status
)) {
7450 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7454 ld
= tldap_context_create(talloc_tos(), fd
);
7457 d_printf("tldap_context_create failed\n");
7461 rc
= tldap_fetch_rootdse(ld
);
7462 if (rc
!= TLDAP_SUCCESS
) {
7463 d_printf("tldap_fetch_rootdse failed: %s\n",
7464 tldap_errstr(talloc_tos(), ld
, rc
));
7468 basedn
= tldap_talloc_single_attribute(
7469 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7470 if (basedn
== NULL
) {
7471 d_printf("no defaultNamingContext\n");
7474 d_printf("defaultNamingContext: %s\n", basedn
);
7476 ev
= tevent_context_init(talloc_tos());
7478 d_printf("tevent_context_init failed\n");
7482 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7483 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7485 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7487 d_printf("tldap_search_paged_send failed\n");
7490 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7492 tevent_req_poll(req
, ev
);
7496 /* test search filters against rootDSE */
7497 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7498 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7500 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7501 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7502 talloc_tos(), NULL
, NULL
);
7503 if (rc
!= TLDAP_SUCCESS
) {
7504 d_printf("tldap_search with complex filter failed: %s\n",
7505 tldap_errstr(talloc_tos(), ld
, rc
));
7513 /* Torture test to ensure no regression of :
7514 https://bugzilla.samba.org/show_bug.cgi?id=7084
7517 static bool run_dir_createtime(int dummy
)
7519 struct cli_state
*cli
;
7520 const char *dname
= "\\testdir";
7521 const char *fname
= "\\testdir\\testfile";
7523 struct timespec create_time
;
7524 struct timespec create_time1
;
7528 if (!torture_open_connection(&cli
, 0)) {
7532 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7533 cli_rmdir(cli
, dname
);
7535 status
= cli_mkdir(cli
, dname
);
7536 if (!NT_STATUS_IS_OK(status
)) {
7537 printf("mkdir failed: %s\n", nt_errstr(status
));
7541 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7543 if (!NT_STATUS_IS_OK(status
)) {
7544 printf("cli_qpathinfo2 returned %s\n",
7549 /* Sleep 3 seconds, then create a file. */
7552 status
= cli_openx(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7554 if (!NT_STATUS_IS_OK(status
)) {
7555 printf("cli_openx failed: %s\n", nt_errstr(status
));
7559 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7561 if (!NT_STATUS_IS_OK(status
)) {
7562 printf("cli_qpathinfo2 (2) returned %s\n",
7567 if (timespec_compare(&create_time1
, &create_time
)) {
7568 printf("run_dir_createtime: create time was updated (error)\n");
7570 printf("run_dir_createtime: create time was not updated (correct)\n");
7576 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7577 cli_rmdir(cli
, dname
);
7578 if (!torture_close_connection(cli
)) {
7585 static bool run_streamerror(int dummy
)
7587 struct cli_state
*cli
;
7588 const char *dname
= "\\testdir";
7589 const char *streamname
=
7590 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7592 time_t change_time
, access_time
, write_time
;
7594 uint16_t mode
, fnum
;
7597 if (!torture_open_connection(&cli
, 0)) {
7601 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7602 cli_rmdir(cli
, dname
);
7604 status
= cli_mkdir(cli
, dname
);
7605 if (!NT_STATUS_IS_OK(status
)) {
7606 printf("mkdir failed: %s\n", nt_errstr(status
));
7610 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
7611 &write_time
, &size
, &mode
);
7612 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7613 printf("pathinfo returned %s, expected "
7614 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7619 status
= cli_ntcreate(cli
, streamname
, 0x16,
7620 FILE_READ_DATA
|FILE_READ_EA
|
7621 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7622 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7623 FILE_OPEN
, 0, 0, &fnum
);
7625 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7626 printf("ntcreate returned %s, expected "
7627 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7633 cli_rmdir(cli
, dname
);
7637 static bool run_local_substitute(int dummy
)
7641 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7642 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7643 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7644 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7645 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7646 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7647 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7648 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7650 /* Different captialization rules in sub_basic... */
7652 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7658 static bool run_local_base64(int dummy
)
7663 for (i
=1; i
<2000; i
++) {
7664 DATA_BLOB blob1
, blob2
;
7667 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7669 generate_random_buffer(blob1
.data
, blob1
.length
);
7671 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7673 d_fprintf(stderr
, "base64_encode_data_blob failed "
7674 "for %d bytes\n", i
);
7677 blob2
= base64_decode_data_blob(b64
);
7680 if (data_blob_cmp(&blob1
, &blob2
)) {
7681 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7685 TALLOC_FREE(blob1
.data
);
7686 data_blob_free(&blob2
);
7691 static bool run_local_gencache(int dummy
)
7697 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7698 d_printf("%s: gencache_set() failed\n", __location__
);
7702 if (!gencache_get("foo", NULL
, NULL
)) {
7703 d_printf("%s: gencache_get() failed\n", __location__
);
7707 if (!gencache_get("foo", &val
, &tm
)) {
7708 d_printf("%s: gencache_get() failed\n", __location__
);
7712 if (strcmp(val
, "bar") != 0) {
7713 d_printf("%s: gencache_get() returned %s, expected %s\n",
7714 __location__
, val
, "bar");
7721 if (!gencache_del("foo")) {
7722 d_printf("%s: gencache_del() failed\n", __location__
);
7725 if (gencache_del("foo")) {
7726 d_printf("%s: second gencache_del() succeeded\n",
7731 if (gencache_get("foo", &val
, &tm
)) {
7732 d_printf("%s: gencache_get() on deleted entry "
7733 "succeeded\n", __location__
);
7737 blob
= data_blob_string_const_null("bar");
7738 tm
= time(NULL
) + 60;
7740 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7741 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7745 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7746 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7750 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7751 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7752 __location__
, (const char *)blob
.data
, "bar");
7753 data_blob_free(&blob
);
7757 data_blob_free(&blob
);
7759 if (!gencache_del("foo")) {
7760 d_printf("%s: gencache_del() failed\n", __location__
);
7763 if (gencache_del("foo")) {
7764 d_printf("%s: second gencache_del() succeeded\n",
7769 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7770 d_printf("%s: gencache_get_data_blob() on deleted entry "
7771 "succeeded\n", __location__
);
7778 static bool rbt_testval(struct db_context
*db
, const char *key
,
7781 struct db_record
*rec
;
7782 TDB_DATA data
= string_tdb_data(value
);
7787 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7789 d_fprintf(stderr
, "fetch_locked failed\n");
7792 status
= dbwrap_record_store(rec
, data
, 0);
7793 if (!NT_STATUS_IS_OK(status
)) {
7794 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7799 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7801 d_fprintf(stderr
, "second fetch_locked failed\n");
7805 dbvalue
= dbwrap_record_get_value(rec
);
7806 if ((dbvalue
.dsize
!= data
.dsize
)
7807 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7808 d_fprintf(stderr
, "Got wrong data back\n");
7818 static bool run_local_rbtree(int dummy
)
7820 struct db_context
*db
;
7824 db
= db_open_rbt(NULL
);
7827 d_fprintf(stderr
, "db_open_rbt failed\n");
7831 for (i
=0; i
<1000; i
++) {
7834 if (asprintf(&key
, "key%ld", random()) == -1) {
7837 if (asprintf(&value
, "value%ld", random()) == -1) {
7842 if (!rbt_testval(db
, key
, value
)) {
7849 if (asprintf(&value
, "value%ld", random()) == -1) {
7854 if (!rbt_testval(db
, key
, value
)) {
7873 local test for character set functions
7875 This is a very simple test for the functionality in convert_string_error()
7877 static bool run_local_convert_string(int dummy
)
7879 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
7880 const char *test_strings
[2] = { "March", "M\303\244rz" };
7884 for (i
=0; i
<2; i
++) {
7885 const char *str
= test_strings
[i
];
7886 int len
= strlen(str
);
7887 size_t converted_size
;
7890 memset(dst
, 'X', sizeof(dst
));
7892 /* first try with real source length */
7893 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7898 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7902 if (converted_size
!= len
) {
7903 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7904 str
, len
, (int)converted_size
);
7908 if (strncmp(str
, dst
, converted_size
) != 0) {
7909 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7913 if (strlen(str
) != converted_size
) {
7914 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7915 (int)strlen(str
), (int)converted_size
);
7919 if (dst
[converted_size
] != 'X') {
7920 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7924 /* now with srclen==-1, this causes the nul to be
7926 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7931 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7935 if (converted_size
!= len
+1) {
7936 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7937 str
, len
, (int)converted_size
);
7941 if (strncmp(str
, dst
, converted_size
) != 0) {
7942 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7946 if (len
+1 != converted_size
) {
7947 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7948 len
+1, (int)converted_size
);
7952 if (dst
[converted_size
] != 'X') {
7953 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7960 TALLOC_FREE(tmp_ctx
);
7963 TALLOC_FREE(tmp_ctx
);
7968 struct talloc_dict_test
{
7972 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7974 int *count
= (int *)priv
;
7979 static bool run_local_talloc_dict(int dummy
)
7981 struct talloc_dict
*dict
;
7982 struct talloc_dict_test
*t
;
7983 int key
, count
, res
;
7986 dict
= talloc_dict_init(talloc_tos());
7991 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7998 ok
= talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), &t
);
8004 res
= talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
);
8022 static bool run_local_string_to_sid(int dummy
) {
8025 if (string_to_sid(&sid
, "S--1-5-32-545")) {
8026 printf("allowing S--1-5-32-545\n");
8029 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
8030 printf("allowing S-1-5-32-+545\n");
8033 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")) {
8034 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8037 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
8038 printf("allowing S-1-5-32-545-abc\n");
8041 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
8042 printf("could not parse S-1-5-32-545\n");
8045 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
8046 printf("mis-parsed S-1-5-32-545 as %s\n",
8047 sid_string_tos(&sid
));
8053 static bool run_local_binary_to_sid(int dummy
) {
8054 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
8055 static const char good_binary_sid
[] = {
8056 0x1, /* revision number */
8058 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8059 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8060 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8061 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8062 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8063 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8067 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8068 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8069 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8070 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8071 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8072 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8073 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8076 static const char long_binary_sid
[] = {
8077 0x1, /* revision number */
8079 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8080 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8081 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8082 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8083 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8084 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8100 static const char long_binary_sid2
[] = {
8101 0x1, /* revision number */
8103 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8104 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8105 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8106 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8107 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8108 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8109 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8110 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8111 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8112 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8113 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8114 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8115 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8116 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8117 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8118 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8119 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8120 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8121 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8122 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8123 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8124 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8125 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8126 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8127 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8128 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8129 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8130 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8131 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8132 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8133 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8134 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8135 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8138 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8141 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8144 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8150 /* Split a path name into filename and stream name components. Canonicalise
8151 * such that an implicit $DATA token is always explicit.
8153 * The "specification" of this function can be found in the
8154 * run_local_stream_name() function in torture.c, I've tried those
8155 * combinations against a W2k3 server.
8158 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8159 char **pbase
, char **pstream
)
8162 char *stream
= NULL
;
8163 char *sname
; /* stream name */
8164 const char *stype
; /* stream type */
8166 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8168 sname
= strchr_m(fname
, ':');
8170 if (lp_posix_pathnames() || (sname
== NULL
)) {
8171 if (pbase
!= NULL
) {
8172 base
= talloc_strdup(mem_ctx
, fname
);
8173 NT_STATUS_HAVE_NO_MEMORY(base
);
8178 if (pbase
!= NULL
) {
8179 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8180 NT_STATUS_HAVE_NO_MEMORY(base
);
8185 stype
= strchr_m(sname
, ':');
8187 if (stype
== NULL
) {
8188 sname
= talloc_strdup(mem_ctx
, sname
);
8192 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8194 * If there is an explicit stream type, so far we only
8195 * allow $DATA. Is there anything else allowed? -- vl
8197 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8199 return NT_STATUS_OBJECT_NAME_INVALID
;
8201 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8205 if (sname
== NULL
) {
8207 return NT_STATUS_NO_MEMORY
;
8210 if (sname
[0] == '\0') {
8212 * no stream name, so no stream
8217 if (pstream
!= NULL
) {
8218 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8219 if (stream
== NULL
) {
8222 return NT_STATUS_NO_MEMORY
;
8225 * upper-case the type field
8227 strupper_m(strchr_m(stream
, ':')+1);
8231 if (pbase
!= NULL
) {
8234 if (pstream
!= NULL
) {
8237 return NT_STATUS_OK
;
8240 static bool test_stream_name(const char *fname
, const char *expected_base
,
8241 const char *expected_stream
,
8242 NTSTATUS expected_status
)
8246 char *stream
= NULL
;
8248 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8249 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8253 if (!NT_STATUS_IS_OK(status
)) {
8257 if (base
== NULL
) goto error
;
8259 if (strcmp(expected_base
, base
) != 0) goto error
;
8261 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8262 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8264 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8268 TALLOC_FREE(stream
);
8272 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8273 fname
, expected_base
? expected_base
: "<NULL>",
8274 expected_stream
? expected_stream
: "<NULL>",
8275 nt_errstr(expected_status
));
8276 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8277 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8280 TALLOC_FREE(stream
);
8284 static bool run_local_stream_name(int dummy
)
8288 ret
&= test_stream_name(
8289 "bla", "bla", NULL
, NT_STATUS_OK
);
8290 ret
&= test_stream_name(
8291 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8292 ret
&= test_stream_name(
8293 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8294 ret
&= test_stream_name(
8295 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8296 ret
&= test_stream_name(
8297 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8298 ret
&= test_stream_name(
8299 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8300 ret
&= test_stream_name(
8301 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8302 ret
&= test_stream_name(
8303 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8308 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8310 if (a
.length
!= b
.length
) {
8311 printf("a.length=%d != b.length=%d\n",
8312 (int)a
.length
, (int)b
.length
);
8315 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8316 printf("a.data and b.data differ\n");
8322 static bool run_local_memcache(int dummy
)
8324 struct memcache
*cache
;
8326 DATA_BLOB d1
, d2
, d3
;
8327 DATA_BLOB v1
, v2
, v3
;
8329 TALLOC_CTX
*mem_ctx
;
8331 size_t size1
, size2
;
8334 cache
= memcache_init(NULL
, sizeof(void *) == 8 ? 200 : 100);
8336 if (cache
== NULL
) {
8337 printf("memcache_init failed\n");
8341 d1
= data_blob_const("d1", 2);
8342 d2
= data_blob_const("d2", 2);
8343 d3
= data_blob_const("d3", 2);
8345 k1
= data_blob_const("d1", 2);
8346 k2
= data_blob_const("d2", 2);
8348 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8349 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8351 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8352 printf("could not find k1\n");
8355 if (!data_blob_equal(d1
, v1
)) {
8359 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8360 printf("could not find k2\n");
8363 if (!data_blob_equal(d2
, v2
)) {
8367 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8369 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8370 printf("could not find replaced k1\n");
8373 if (!data_blob_equal(d3
, v3
)) {
8377 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8379 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8380 printf("Did find k2, should have been purged\n");
8386 cache
= memcache_init(NULL
, 0);
8388 mem_ctx
= talloc_init("foo");
8390 str1
= talloc_strdup(mem_ctx
, "string1");
8391 str2
= talloc_strdup(mem_ctx
, "string2");
8393 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8394 data_blob_string_const("torture"), &str1
);
8395 size1
= talloc_total_size(cache
);
8397 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8398 data_blob_string_const("torture"), &str2
);
8399 size2
= talloc_total_size(cache
);
8401 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8403 if (size2
> size1
) {
8404 printf("memcache leaks memory!\n");
8414 static void wbclient_done(struct tevent_req
*req
)
8417 struct winbindd_response
*wb_resp
;
8418 int *i
= (int *)tevent_req_callback_data_void(req
);
8420 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8423 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8426 static bool run_local_wbclient(int dummy
)
8428 struct event_context
*ev
;
8429 struct wb_context
**wb_ctx
;
8430 struct winbindd_request wb_req
;
8431 bool result
= false;
8434 BlockSignals(True
, SIGPIPE
);
8436 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
8441 wb_ctx
= talloc_array(ev
, struct wb_context
*, torture_nprocs
);
8442 if (wb_ctx
== NULL
) {
8446 ZERO_STRUCT(wb_req
);
8447 wb_req
.cmd
= WINBINDD_PING
;
8449 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs
, (int)torture_numops
);
8451 for (i
=0; i
<torture_nprocs
; i
++) {
8452 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8453 if (wb_ctx
[i
] == NULL
) {
8456 for (j
=0; j
<torture_numops
; j
++) {
8457 struct tevent_req
*req
;
8458 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8459 (j
% 2) == 0, &wb_req
);
8463 tevent_req_set_callback(req
, wbclient_done
, &i
);
8469 while (i
< torture_nprocs
* torture_numops
) {
8470 tevent_loop_once(ev
);
8479 static void getaddrinfo_finished(struct tevent_req
*req
)
8481 char *name
= (char *)tevent_req_callback_data_void(req
);
8482 struct addrinfo
*ainfo
;
8485 res
= getaddrinfo_recv(req
, &ainfo
);
8487 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
8490 d_printf("gai(%s) succeeded\n", name
);
8491 freeaddrinfo(ainfo
);
8494 static bool run_getaddrinfo_send(int dummy
)
8496 TALLOC_CTX
*frame
= talloc_stackframe();
8497 struct fncall_context
*ctx
;
8498 struct tevent_context
*ev
;
8499 bool result
= false;
8500 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
8501 "www.slashdot.org", "heise.de" };
8502 struct tevent_req
*reqs
[4];
8505 ev
= event_context_init(frame
);
8510 ctx
= fncall_context_init(frame
, 4);
8512 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
8513 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
8515 if (reqs
[i
] == NULL
) {
8518 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
8519 discard_const_p(void, names
[i
]));
8522 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
8523 tevent_loop_once(ev
);
8532 static bool dbtrans_inc(struct db_context
*db
)
8534 struct db_record
*rec
;
8540 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8542 printf(__location__
"fetch_lock failed\n");
8546 value
= dbwrap_record_get_value(rec
);
8548 if (value
.dsize
!= sizeof(uint32_t)) {
8549 printf(__location__
"value.dsize = %d\n",
8554 memcpy(&val
, value
.dptr
, sizeof(val
));
8557 status
= dbwrap_record_store(
8558 rec
, make_tdb_data((uint8_t *)&val
, sizeof(val
)), 0);
8559 if (!NT_STATUS_IS_OK(status
)) {
8560 printf(__location__
"store failed: %s\n",
8571 static bool run_local_dbtrans(int dummy
)
8573 struct db_context
*db
;
8574 struct db_record
*rec
;
8580 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
8581 O_RDWR
|O_CREAT
, 0600, DBWRAP_LOCK_ORDER_1
);
8583 printf("Could not open transtest.db\n");
8587 res
= dbwrap_transaction_start(db
);
8589 printf(__location__
"transaction_start failed\n");
8593 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8595 printf(__location__
"fetch_lock failed\n");
8599 value
= dbwrap_record_get_value(rec
);
8601 if (value
.dptr
== NULL
) {
8603 status
= dbwrap_record_store(
8604 rec
, make_tdb_data((uint8_t *)&initial
,
8607 if (!NT_STATUS_IS_OK(status
)) {
8608 printf(__location__
"store returned %s\n",
8616 res
= dbwrap_transaction_commit(db
);
8618 printf(__location__
"transaction_commit failed\n");
8626 res
= dbwrap_transaction_start(db
);
8628 printf(__location__
"transaction_start failed\n");
8632 status
= dbwrap_fetch_uint32(db
, "transtest", &val
);
8633 if (!NT_STATUS_IS_OK(status
)) {
8634 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8639 for (i
=0; i
<10; i
++) {
8640 if (!dbtrans_inc(db
)) {
8645 status
= dbwrap_fetch_uint32(db
, "transtest", &val2
);
8646 if (!NT_STATUS_IS_OK(status
)) {
8647 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8652 if (val2
!= val
+ 10) {
8653 printf(__location__
"val=%d, val2=%d\n",
8654 (int)val
, (int)val2
);
8658 printf("val2=%d\r", val2
);
8660 res
= dbwrap_transaction_commit(db
);
8662 printf(__location__
"transaction_commit failed\n");
8672 * Just a dummy test to be run under a debugger. There's no real way
8673 * to inspect the tevent_select specific function from outside of
8677 static bool run_local_tevent_select(int dummy
)
8679 struct tevent_context
*ev
;
8680 struct tevent_fd
*fd1
, *fd2
;
8681 bool result
= false;
8683 ev
= tevent_context_init_byname(NULL
, "select");
8685 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8689 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8691 d_fprintf(stderr
, "tevent_add_fd failed\n");
8694 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8696 d_fprintf(stderr
, "tevent_add_fd failed\n");
8701 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8703 d_fprintf(stderr
, "tevent_add_fd failed\n");
8713 static bool run_local_hex_encode_buf(int dummy
)
8719 for (i
=0; i
<sizeof(src
); i
++) {
8722 hex_encode_buf(buf
, src
, sizeof(src
));
8723 if (strcmp(buf
, "0001020304050607") != 0) {
8726 hex_encode_buf(buf
, NULL
, 0);
8727 if (buf
[0] != '\0') {
8733 static const char *remove_duplicate_addrs2_test_strings_vector
[] = {
8755 "1001:1111:1111:1000:0:1111:1111:1111",
8764 static const char *remove_duplicate_addrs2_test_strings_result
[] = {
8778 "1001:1111:1111:1000:0:1111:1111:1111"
8781 static bool run_local_remove_duplicate_addrs2(int dummy
)
8783 struct ip_service test_vector
[28];
8786 /* Construct the sockaddr_storage test vector. */
8787 for (i
= 0; i
< 28; i
++) {
8788 struct addrinfo hints
;
8789 struct addrinfo
*res
= NULL
;
8792 memset(&hints
, '\0', sizeof(hints
));
8793 hints
.ai_flags
= AI_NUMERICHOST
;
8794 ret
= getaddrinfo(remove_duplicate_addrs2_test_strings_vector
[i
],
8799 fprintf(stderr
, "getaddrinfo failed on [%s]\n",
8800 remove_duplicate_addrs2_test_strings_vector
[i
]);
8803 memset(&test_vector
[i
], '\0', sizeof(test_vector
[i
]));
8804 memcpy(&test_vector
[i
].ss
,
8810 count
= remove_duplicate_addrs2(test_vector
, i
);
8813 fprintf(stderr
, "count wrong (%d) should be 14\n",
8818 for (i
= 0; i
< count
; i
++) {
8819 char addr
[INET6_ADDRSTRLEN
];
8821 print_sockaddr(addr
, sizeof(addr
), &test_vector
[i
].ss
);
8823 if (strcmp(addr
, remove_duplicate_addrs2_test_strings_result
[i
]) != 0) {
8824 fprintf(stderr
, "mismatch on [%d] [%s] [%s]\n",
8827 remove_duplicate_addrs2_test_strings_result
[i
]);
8832 printf("run_local_remove_duplicate_addrs2: success\n");
8836 static double create_procs(bool (*fn
)(int), bool *result
)
8839 volatile pid_t
*child_status
;
8840 volatile bool *child_status_out
;
8843 struct timeval start
;
8847 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*torture_nprocs
);
8848 if (!child_status
) {
8849 printf("Failed to setup shared memory\n");
8853 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*torture_nprocs
);
8854 if (!child_status_out
) {
8855 printf("Failed to setup result status shared memory\n");
8859 for (i
= 0; i
< torture_nprocs
; i
++) {
8860 child_status
[i
] = 0;
8861 child_status_out
[i
] = True
;
8864 start
= timeval_current();
8866 for (i
=0;i
<torture_nprocs
;i
++) {
8869 pid_t mypid
= getpid();
8870 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8872 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8875 if (torture_open_connection(¤t_cli
, i
)) break;
8877 printf("pid %d failed to start\n", (int)getpid());
8883 child_status
[i
] = getpid();
8885 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8887 child_status_out
[i
] = fn(i
);
8894 for (i
=0;i
<torture_nprocs
;i
++) {
8895 if (child_status
[i
]) synccount
++;
8897 if (synccount
== torture_nprocs
) break;
8899 } while (timeval_elapsed(&start
) < 30);
8901 if (synccount
!= torture_nprocs
) {
8902 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs
, synccount
);
8904 return timeval_elapsed(&start
);
8907 /* start the client load */
8908 start
= timeval_current();
8910 for (i
=0;i
<torture_nprocs
;i
++) {
8911 child_status
[i
] = 0;
8914 printf("%d clients started\n", torture_nprocs
);
8916 for (i
=0;i
<torture_nprocs
;i
++) {
8917 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8922 for (i
=0;i
<torture_nprocs
;i
++) {
8923 if (!child_status_out
[i
]) {
8927 return timeval_elapsed(&start
);
8930 #define FLAG_MULTIPROC 1
8937 {"FDPASS", run_fdpasstest
, 0},
8938 {"LOCK1", run_locktest1
, 0},
8939 {"LOCK2", run_locktest2
, 0},
8940 {"LOCK3", run_locktest3
, 0},
8941 {"LOCK4", run_locktest4
, 0},
8942 {"LOCK5", run_locktest5
, 0},
8943 {"LOCK6", run_locktest6
, 0},
8944 {"LOCK7", run_locktest7
, 0},
8945 {"LOCK8", run_locktest8
, 0},
8946 {"LOCK9", run_locktest9
, 0},
8947 {"UNLINK", run_unlinktest
, 0},
8948 {"BROWSE", run_browsetest
, 0},
8949 {"ATTR", run_attrtest
, 0},
8950 {"TRANS2", run_trans2test
, 0},
8951 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8952 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8953 {"RANDOMIPC", run_randomipc
, 0},
8954 {"NEGNOWAIT", run_negprot_nowait
, 0},
8955 {"NBENCH", run_nbench
, 0},
8956 {"NBENCH2", run_nbench2
, 0},
8957 {"OPLOCK1", run_oplock1
, 0},
8958 {"OPLOCK2", run_oplock2
, 0},
8959 {"OPLOCK4", run_oplock4
, 0},
8960 {"DIR", run_dirtest
, 0},
8961 {"DIR1", run_dirtest1
, 0},
8962 {"DIR-CREATETIME", run_dir_createtime
, 0},
8963 {"DENY1", torture_denytest1
, 0},
8964 {"DENY2", torture_denytest2
, 0},
8965 {"TCON", run_tcon_test
, 0},
8966 {"TCONDEV", run_tcon_devtype_test
, 0},
8967 {"RW1", run_readwritetest
, 0},
8968 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8969 {"RW3", run_readwritelarge
, 0},
8970 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8971 {"OPEN", run_opentest
, 0},
8972 {"POSIX", run_simple_posix_open_test
, 0},
8973 {"POSIX-APPEND", run_posix_append
, 0},
8974 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
8975 {"ASYNC-ECHO", run_async_echo
, 0},
8976 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8977 { "SHORTNAME-TEST", run_shortname_test
, 0},
8978 { "ADDRCHANGE", run_addrchange
, 0},
8980 {"OPENATTR", run_openattrtest
, 0},
8982 {"XCOPY", run_xcopy
, 0},
8983 {"RENAME", run_rename
, 0},
8984 {"DELETE", run_deletetest
, 0},
8985 {"DELETE-LN", run_deletetest_ln
, 0},
8986 {"PROPERTIES", run_properties
, 0},
8987 {"MANGLE", torture_mangle
, 0},
8988 {"MANGLE1", run_mangle1
, 0},
8989 {"W2K", run_w2ktest
, 0},
8990 {"TRANS2SCAN", torture_trans2_scan
, 0},
8991 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8992 {"UTABLE", torture_utable
, 0},
8993 {"CASETABLE", torture_casetable
, 0},
8994 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8995 {"PIPE_NUMBER", run_pipe_number
, 0},
8996 {"TCON2", run_tcon2_test
, 0},
8997 {"IOCTL", torture_ioctl_test
, 0},
8998 {"CHKPATH", torture_chkpath_test
, 0},
8999 {"FDSESS", run_fdsesstest
, 0},
9000 { "EATEST", run_eatest
, 0},
9001 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
9002 { "CHAIN1", run_chain1
, 0},
9003 { "CHAIN2", run_chain2
, 0},
9004 { "CHAIN3", run_chain3
, 0},
9005 { "WINDOWS-WRITE", run_windows_write
, 0},
9006 { "NTTRANS-CREATE", run_nttrans_create
, 0},
9007 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
9008 { "CLI_ECHO", run_cli_echo
, 0},
9009 { "GETADDRINFO", run_getaddrinfo_send
, 0},
9010 { "TLDAP", run_tldap
},
9011 { "STREAMERROR", run_streamerror
},
9012 { "NOTIFY-BENCH", run_notify_bench
},
9013 { "NOTIFY-BENCH2", run_notify_bench2
},
9014 { "NOTIFY-BENCH3", run_notify_bench3
},
9015 { "BAD-NBT-SESSION", run_bad_nbt_session
},
9016 { "SMB-ANY-CONNECT", run_smb_any_connect
},
9017 { "NOTIFY-ONLINE", run_notify_online
},
9018 { "SMB2-BASIC", run_smb2_basic
},
9019 { "SMB2-NEGPROT", run_smb2_negprot
},
9020 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect
},
9021 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence
},
9022 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel
},
9023 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth
},
9024 { "CLEANUP1", run_cleanup1
},
9025 { "CLEANUP2", run_cleanup2
},
9026 { "CLEANUP3", run_cleanup3
},
9027 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
9028 { "LOCAL-GENCACHE", run_local_gencache
, 0},
9029 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
9030 { "LOCAL-CTDB-CONN", run_ctdb_conn
, 0},
9031 { "LOCAL-MSG", run_msg_test
, 0},
9032 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1
, 0 },
9033 { "LOCAL-BASE64", run_local_base64
, 0},
9034 { "LOCAL-RBTREE", run_local_rbtree
, 0},
9035 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
9036 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
9037 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
9038 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
9039 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
9040 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
9041 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
9042 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
9043 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
9044 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
9045 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf
, 0},
9046 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test
, 0},
9047 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2
, 0},
9052 /****************************************************************************
9053 run a specified test or "ALL"
9054 ****************************************************************************/
9055 static bool run_test(const char *name
)
9062 if (strequal(name
,"ALL")) {
9063 for (i
=0;torture_ops
[i
].name
;i
++) {
9064 run_test(torture_ops
[i
].name
);
9069 for (i
=0;torture_ops
[i
].name
;i
++) {
9070 fstr_sprintf(randomfname
, "\\XX%x",
9071 (unsigned)random());
9073 if (strequal(name
, torture_ops
[i
].name
)) {
9075 printf("Running %s\n", name
);
9076 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
9077 t
= create_procs(torture_ops
[i
].fn
, &result
);
9080 printf("TEST %s FAILED!\n", name
);
9083 struct timeval start
;
9084 start
= timeval_current();
9085 if (!torture_ops
[i
].fn(0)) {
9087 printf("TEST %s FAILED!\n", name
);
9089 t
= timeval_elapsed(&start
);
9091 printf("%s took %g secs\n\n", name
, t
);
9096 printf("Did not find a test named %s\n", name
);
9104 static void usage(void)
9108 printf("WARNING samba4 test suite is much more complete nowadays.\n");
9109 printf("Please use samba4 torture.\n\n");
9111 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9113 printf("\t-d debuglevel\n");
9114 printf("\t-U user%%pass\n");
9115 printf("\t-k use kerberos\n");
9116 printf("\t-N numprocs\n");
9117 printf("\t-n my_netbios_name\n");
9118 printf("\t-W workgroup\n");
9119 printf("\t-o num_operations\n");
9120 printf("\t-O socket_options\n");
9121 printf("\t-m maximum protocol\n");
9122 printf("\t-L use oplocks\n");
9123 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
9124 printf("\t-A showall\n");
9125 printf("\t-p port\n");
9126 printf("\t-s seed\n");
9127 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
9128 printf("\t-f filename filename to test\n");
9131 printf("tests are:");
9132 for (i
=0;torture_ops
[i
].name
;i
++) {
9133 printf(" %s", torture_ops
[i
].name
);
9137 printf("default test is ALL\n");
9142 /****************************************************************************
9144 ****************************************************************************/
9145 int main(int argc
,char *argv
[])
9151 bool correct
= True
;
9152 TALLOC_CTX
*frame
= talloc_stackframe();
9153 int seed
= time(NULL
);
9155 #ifdef HAVE_SETBUFFER
9156 setbuffer(stdout
, NULL
, 0);
9159 setup_logging("smbtorture", DEBUG_STDOUT
);
9163 if (is_default_dyn_CONFIGFILE()) {
9164 if(getenv("SMB_CONF_PATH")) {
9165 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9168 lp_load_global(get_dyn_CONFIGFILE());
9175 for(p
= argv
[1]; *p
; p
++)
9179 if (strncmp(argv
[1], "//", 2)) {
9183 fstrcpy(host
, &argv
[1][2]);
9184 p
= strchr_m(&host
[2],'/');
9189 fstrcpy(share
, p
+1);
9191 fstrcpy(myname
, get_myname(talloc_tos()));
9193 fprintf(stderr
, "Failed to get my hostname.\n");
9197 if (*username
== 0 && getenv("LOGNAME")) {
9198 fstrcpy(username
,getenv("LOGNAME"));
9204 fstrcpy(workgroup
, lp_workgroup());
9206 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9210 port_to_use
= atoi(optarg
);
9213 seed
= atoi(optarg
);
9216 fstrcpy(workgroup
,optarg
);
9219 max_protocol
= interpret_protocol(optarg
, max_protocol
);
9222 torture_nprocs
= atoi(optarg
);
9225 torture_numops
= atoi(optarg
);
9228 lp_set_cmdline("log level", optarg
);
9237 local_path
= optarg
;
9240 torture_showall
= True
;
9243 fstrcpy(myname
, optarg
);
9246 client_txt
= optarg
;
9253 use_kerberos
= True
;
9255 d_printf("No kerberos support compiled in\n");
9261 fstrcpy(username
,optarg
);
9262 p
= strchr_m(username
,'%');
9265 fstrcpy(password
, p
+1);
9270 fstrcpy(multishare_conn_fname
, optarg
);
9271 use_multishare_conn
= True
;
9274 torture_blocksize
= atoi(optarg
);
9277 test_filename
= SMB_STRDUP(optarg
);
9280 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
9285 d_printf("using seed %d\n", seed
);
9289 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9292 p
= getpass("Password:");
9294 fstrcpy(password
, p
);
9299 printf("host=%s share=%s user=%s myname=%s\n",
9300 host
, share
, username
, myname
);
9302 if (argc
== optind
) {
9303 correct
= run_test("ALL");
9305 for (i
=optind
;i
<argc
;i
++) {
9306 if (!run_test(argv
[i
])) {