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"
47 fstring host
, workgroup
, share
, password
, username
, myname
;
48 static int max_protocol
= PROTOCOL_NT1
;
49 static const char *sockops
="TCP_NODELAY";
51 static int port_to_use
=0;
52 int torture_numops
=100;
53 int torture_blocksize
=1024*1024;
54 static int procnum
; /* records process count number when forking */
55 static struct cli_state
*current_cli
;
56 static fstring randomfname
;
57 static bool use_oplocks
;
58 static bool use_level_II_oplocks
;
59 static const char *client_txt
= "client_oplocks.txt";
60 static bool disable_spnego
;
61 static bool use_kerberos
;
62 static bool force_dos_errors
;
63 static fstring multishare_conn_fname
;
64 static bool use_multishare_conn
= False
;
65 static bool do_encrypt
;
66 static const char *local_path
= NULL
;
67 static int signing_state
= SMB_SIGNING_DEFAULT
;
70 bool torture_showall
= False
;
72 static double create_procs(bool (*fn
)(int), bool *result
);
75 /* return a pointer to a anonymous shared memory segment of size "size"
76 which will persist across fork() but will disappear when all processes
79 The memory is not zeroed
81 This function uses system5 shared memory. It takes advantage of a property
82 that the memory is not destroyed if it is attached when the id is removed
84 void *shm_setup(int size
)
90 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
92 printf("can't get shared memory\n");
95 shm_unlink("private");
96 if (ftruncate(shmid
, size
) == -1) {
97 printf("can't set shared memory size\n");
100 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
101 if (ret
== MAP_FAILED
) {
102 printf("can't map shared memory\n");
106 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
108 printf("can't get shared memory\n");
111 ret
= (void *)shmat(shmid
, 0, 0);
112 if (!ret
|| ret
== (void *)-1) {
113 printf("can't attach to shared memory\n");
116 /* the following releases the ipc, but note that this process
117 and all its children will still have access to the memory, its
118 just that the shmid is no longer valid for other shm calls. This
119 means we don't leave behind lots of shm segments after we exit
121 See Stevens "advanced programming in unix env" for details
123 shmctl(shmid
, IPC_RMID
, 0);
129 /********************************************************************
130 Ensure a connection is encrypted.
131 ********************************************************************/
133 static bool force_cli_encryption(struct cli_state
*c
,
134 const char *sharename
)
137 uint32 caplow
, caphigh
;
140 if (!SERVER_HAS_UNIX_CIFS(c
)) {
141 d_printf("Encryption required and "
142 "server that doesn't support "
143 "UNIX extensions - failing connect\n");
147 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
149 if (!NT_STATUS_IS_OK(status
)) {
150 d_printf("Encryption required and "
151 "can't get UNIX CIFS extensions "
152 "version from server: %s\n", nt_errstr(status
));
156 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
157 d_printf("Encryption required and "
158 "share %s doesn't support "
159 "encryption.\n", sharename
);
163 if (c
->use_kerberos
) {
164 status
= cli_gss_smb_encryption_start(c
);
166 status
= cli_raw_ntlm_smb_encryption_start(c
,
172 if (!NT_STATUS_IS_OK(status
)) {
173 d_printf("Encryption required and "
174 "setup failed with error %s.\n",
183 static struct cli_state
*open_nbt_connection(void)
189 if (disable_spnego
) {
190 flags
|= CLI_FULL_CONNECTION_DONT_SPNEGO
;
194 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
197 if (use_level_II_oplocks
) {
198 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
202 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
205 if (force_dos_errors
) {
206 flags
|= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS
;
209 status
= cli_connect_nb(host
, NULL
, port_to_use
, 0x20, myname
,
210 signing_state
, flags
, &c
);
211 if (!NT_STATUS_IS_OK(status
)) {
212 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
216 cli_set_timeout(c
, 120000); /* set a really long timeout (2 minutes) */
221 /****************************************************************************
222 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
223 ****************************************************************************/
225 static bool cli_bad_session_request(int fd
,
226 struct nmb_name
*calling
, struct nmb_name
*called
)
235 uint8_t message_type
;
237 struct event_context
*ev
;
238 struct tevent_req
*req
;
240 frame
= talloc_stackframe();
242 iov
[0].iov_base
= len_buf
;
243 iov
[0].iov_len
= sizeof(len_buf
);
245 /* put in the destination name */
247 iov
[1].iov_base
= name_mangle(talloc_tos(), called
->name
,
249 if (iov
[1].iov_base
== NULL
) {
252 iov
[1].iov_len
= name_len((unsigned char *)iov
[1].iov_base
,
253 talloc_get_size(iov
[1].iov_base
));
257 iov
[2].iov_base
= name_mangle(talloc_tos(), calling
->name
,
259 if (iov
[2].iov_base
== NULL
) {
262 iov
[2].iov_len
= name_len((unsigned char *)iov
[2].iov_base
,
263 talloc_get_size(iov
[2].iov_base
));
265 /* Deliberately corrupt the name len (first byte) */
266 *((uint8_t *)iov
[2].iov_base
) = 100;
268 /* send a session request (RFC 1002) */
269 /* setup the packet length
270 * Remove four bytes from the length count, since the length
271 * field in the NBT Session Service header counts the number
272 * of bytes which follow. The cli_send_smb() function knows
273 * about this and accounts for those four bytes.
277 _smb_setlen(len_buf
, iov
[1].iov_len
+ iov
[2].iov_len
);
278 SCVAL(len_buf
,0,0x81);
280 len
= write_data_iov(fd
, iov
, 3);
285 ev
= event_context_init(frame
);
289 req
= read_smb_send(frame
, ev
, fd
);
293 if (!tevent_req_poll(req
, ev
)) {
296 len
= read_smb_recv(req
, talloc_tos(), &inbuf
, &err
);
303 message_type
= CVAL(inbuf
, 0);
304 if (message_type
!= 0x83) {
305 d_fprintf(stderr
, "Expected msg type 0x83, got 0x%2.2x\n",
310 if (smb_len(inbuf
) != 1) {
311 d_fprintf(stderr
, "Expected smb_len 1, got %d\n",
312 (int)smb_len(inbuf
));
316 error
= CVAL(inbuf
, 4);
318 d_fprintf(stderr
, "Expected error 0x82, got %d\n",
329 /* Insert a NULL at the first separator of the given path and return a pointer
330 * to the remainder of the string.
333 terminate_path_at_separator(char * path
)
341 if ((p
= strchr_m(path
, '/'))) {
346 if ((p
= strchr_m(path
, '\\'))) {
356 parse a //server/share type UNC name
358 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
359 char **hostname
, char **sharename
)
363 *hostname
= *sharename
= NULL
;
365 if (strncmp(unc_name
, "\\\\", 2) &&
366 strncmp(unc_name
, "//", 2)) {
370 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
371 p
= terminate_path_at_separator(*hostname
);
374 *sharename
= talloc_strdup(mem_ctx
, p
);
375 terminate_path_at_separator(*sharename
);
378 if (*hostname
&& *sharename
) {
382 TALLOC_FREE(*hostname
);
383 TALLOC_FREE(*sharename
);
387 static bool torture_open_connection_share(struct cli_state
**c
,
388 const char *hostname
,
389 const char *sharename
)
395 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
397 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
398 if (use_level_II_oplocks
)
399 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
401 status
= cli_full_connection(c
, myname
,
402 hostname
, NULL
, port_to_use
,
405 password
, flags
, signing_state
);
406 if (!NT_STATUS_IS_OK(status
)) {
407 printf("failed to open share connection: //%s/%s port:%d - %s\n",
408 hostname
, sharename
, port_to_use
, nt_errstr(status
));
412 cli_set_timeout(*c
, 120000); /* set a really long timeout (2 minutes) */
415 return force_cli_encryption(*c
,
421 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
423 char **unc_list
= NULL
;
424 int num_unc_names
= 0;
427 if (use_multishare_conn
==True
) {
429 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
430 if (!unc_list
|| num_unc_names
<= 0) {
431 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
435 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
437 printf("Failed to parse UNC name %s\n",
438 unc_list
[conn_index
% num_unc_names
]);
439 TALLOC_FREE(unc_list
);
443 result
= torture_open_connection_share(c
, h
, s
);
445 /* h, s were copied earlier */
446 TALLOC_FREE(unc_list
);
450 return torture_open_connection_share(c
, host
, share
);
453 bool torture_init_connection(struct cli_state
**pcli
)
455 struct cli_state
*cli
;
457 cli
= open_nbt_connection();
466 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
468 uint16_t old_vuid
= cli_state_get_uid(cli
);
469 fstring old_user_name
;
470 size_t passlen
= strlen(password
);
474 fstrcpy(old_user_name
, cli
->user_name
);
475 cli_state_set_uid(cli
, 0);
476 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
480 *new_vuid
= cli_state_get_uid(cli
);
481 cli_state_set_uid(cli
, old_vuid
);
482 status
= cli_set_username(cli
, old_user_name
);
483 if (!NT_STATUS_IS_OK(status
)) {
490 bool torture_close_connection(struct cli_state
*c
)
495 status
= cli_tdis(c
);
496 if (!NT_STATUS_IS_OK(status
)) {
497 printf("tdis failed (%s)\n", nt_errstr(status
));
507 /* check if the server produced the expected dos or nt error code */
508 static bool check_both_error(int line
, NTSTATUS status
,
509 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
511 if (NT_STATUS_IS_DOS(status
)) {
515 /* Check DOS error */
516 cclass
= NT_STATUS_DOS_CLASS(status
);
517 num
= NT_STATUS_DOS_CODE(status
);
519 if (eclass
!= cclass
|| ecode
!= num
) {
520 printf("unexpected error code class=%d code=%d\n",
521 (int)cclass
, (int)num
);
522 printf(" expected %d/%d %s (line=%d)\n",
523 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
528 if (!NT_STATUS_EQUAL(nterr
, status
)) {
529 printf("unexpected error code %s\n",
531 printf(" expected %s (line=%d)\n",
532 nt_errstr(nterr
), line
);
541 /* check if the server produced the expected error code */
542 static bool check_error(int line
, NTSTATUS status
,
543 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
545 if (NT_STATUS_IS_DOS(status
)) {
549 /* Check DOS error */
551 cclass
= NT_STATUS_DOS_CLASS(status
);
552 num
= NT_STATUS_DOS_CODE(status
);
554 if (eclass
!= cclass
|| ecode
!= num
) {
555 printf("unexpected error code class=%d code=%d\n",
556 (int)cclass
, (int)num
);
557 printf(" expected %d/%d %s (line=%d)\n",
558 (int)eclass
, (int)ecode
, nt_errstr(nterr
),
566 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
567 printf("unexpected error code %s\n",
569 printf(" expected %s (line=%d)\n", nt_errstr(nterr
),
579 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
583 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
585 while (!NT_STATUS_IS_OK(status
)) {
586 if (!check_both_error(__LINE__
, status
, ERRDOS
,
587 ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) {
591 status
= cli_lock32(c
, fnum
, offset
, len
, -1, WRITE_LOCK
);
598 static bool rw_torture(struct cli_state
*c
)
600 const char *lockfname
= "\\torture.lck";
604 pid_t pid2
, pid
= getpid();
611 memset(buf
, '\0', sizeof(buf
));
613 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
615 if (!NT_STATUS_IS_OK(status
)) {
616 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
618 if (!NT_STATUS_IS_OK(status
)) {
619 printf("open of %s failed (%s)\n",
620 lockfname
, nt_errstr(status
));
624 for (i
=0;i
<torture_numops
;i
++) {
625 unsigned n
= (unsigned)sys_random()%10;
628 printf("%d\r", i
); fflush(stdout
);
630 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
632 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
636 status
= cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
,
638 if (!NT_STATUS_IS_OK(status
)) {
639 printf("open failed (%s)\n", nt_errstr(status
));
644 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)&pid
, 0,
646 if (!NT_STATUS_IS_OK(status
)) {
647 printf("write failed (%s)\n", nt_errstr(status
));
652 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
,
653 sizeof(pid
)+(j
*sizeof(buf
)),
655 if (!NT_STATUS_IS_OK(status
)) {
656 printf("write failed (%s)\n",
664 status
= cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
),
666 if (!NT_STATUS_IS_OK(status
)) {
667 printf("read failed (%s)\n", nt_errstr(status
));
669 } else if (nread
!= sizeof(pid
)) {
670 printf("read/write compare failed: "
671 "recv %ld req %ld\n", (unsigned long)nread
,
672 (unsigned long)sizeof(pid
));
677 printf("data corruption!\n");
681 status
= cli_close(c
, fnum
);
682 if (!NT_STATUS_IS_OK(status
)) {
683 printf("close failed (%s)\n", nt_errstr(status
));
687 status
= cli_unlink(c
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
688 if (!NT_STATUS_IS_OK(status
)) {
689 printf("unlink failed (%s)\n", nt_errstr(status
));
693 status
= cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int));
694 if (!NT_STATUS_IS_OK(status
)) {
695 printf("unlock failed (%s)\n", nt_errstr(status
));
701 cli_unlink(c
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
708 static bool run_torture(int dummy
)
710 struct cli_state
*cli
;
715 cli_sockopt(cli
, sockops
);
717 ret
= rw_torture(cli
);
719 if (!torture_close_connection(cli
)) {
726 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
728 uint16_t fnum
= (uint16_t)-1;
733 unsigned countprev
= 0;
736 NTSTATUS status
= NT_STATUS_OK
;
739 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
741 SIVAL(buf
, i
, sys_random());
748 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
749 if (!NT_STATUS_IS_OK(status
)) {
750 printf("unlink failed (%s) (normal, this file should "
751 "not exist)\n", nt_errstr(status
));
754 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
756 if (!NT_STATUS_IS_OK(status
)) {
757 printf("first open read/write of %s failed (%s)\n",
758 lockfname
, nt_errstr(status
));
764 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
766 status
= cli_open(c
, lockfname
, O_RDONLY
,
768 if (!NT_STATUS_IS_OK(status
)) {
773 if (!NT_STATUS_IS_OK(status
)) {
774 printf("second open read-only of %s failed (%s)\n",
775 lockfname
, nt_errstr(status
));
781 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
783 if (count
>= countprev
) {
784 printf("%d %8d\r", i
, count
);
787 countprev
+= (sizeof(buf
) / 20);
792 sent
= ((unsigned)sys_random()%(20))+ 1;
793 if (sent
> sizeof(buf
) - count
)
795 sent
= sizeof(buf
) - count
;
798 status
= cli_writeall(c
, fnum
, 0, (uint8_t *)buf
+count
,
800 if (!NT_STATUS_IS_OK(status
)) {
801 printf("write failed (%s)\n",
808 status
= cli_read(c
, fnum
, buf_rd
+count
, count
,
809 sizeof(buf
)-count
, &sent
);
810 if(!NT_STATUS_IS_OK(status
)) {
811 printf("read failed offset:%d size:%ld (%s)\n",
812 count
, (unsigned long)sizeof(buf
)-count
,
816 } else if (sent
> 0) {
817 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
819 printf("read/write compare failed\n");
820 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
829 status
= cli_close(c
, fnum
);
830 if (!NT_STATUS_IS_OK(status
)) {
831 printf("close failed (%s)\n", nt_errstr(status
));
838 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
840 const char *lockfname
= "\\torture2.lck";
850 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
851 if (!NT_STATUS_IS_OK(status
)) {
852 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status
));
855 status
= cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
857 if (!NT_STATUS_IS_OK(status
)) {
858 printf("first open read/write of %s failed (%s)\n",
859 lockfname
, nt_errstr(status
));
863 status
= cli_open(c2
, lockfname
, O_RDONLY
, DENY_NONE
, &fnum2
);
864 if (!NT_STATUS_IS_OK(status
)) {
865 printf("second open read-only of %s failed (%s)\n",
866 lockfname
, nt_errstr(status
));
867 cli_close(c1
, fnum1
);
871 for (i
= 0; i
< torture_numops
; i
++)
873 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
875 printf("%d\r", i
); fflush(stdout
);
878 generate_random_buffer((unsigned char *)buf
, buf_size
);
880 status
= cli_writeall(c1
, fnum1
, 0, (uint8_t *)buf
, 0,
882 if (!NT_STATUS_IS_OK(status
)) {
883 printf("write failed (%s)\n", nt_errstr(status
));
888 status
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
, &bytes_read
);
889 if(!NT_STATUS_IS_OK(status
)) {
890 printf("read failed (%s)\n", nt_errstr(status
));
893 } else if (bytes_read
!= buf_size
) {
894 printf("read failed\n");
895 printf("read %ld, expected %ld\n",
896 (unsigned long)bytes_read
,
897 (unsigned long)buf_size
);
902 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
904 printf("read/write compare failed\n");
910 status
= cli_close(c2
, fnum2
);
911 if (!NT_STATUS_IS_OK(status
)) {
912 printf("close failed (%s)\n", nt_errstr(status
));
916 status
= cli_close(c1
, fnum1
);
917 if (!NT_STATUS_IS_OK(status
)) {
918 printf("close failed (%s)\n", nt_errstr(status
));
922 status
= cli_unlink(c1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
923 if (!NT_STATUS_IS_OK(status
)) {
924 printf("unlink failed (%s)\n", nt_errstr(status
));
931 static bool run_readwritetest(int dummy
)
933 struct cli_state
*cli1
, *cli2
;
934 bool test1
, test2
= False
;
936 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
939 cli_sockopt(cli1
, sockops
);
940 cli_sockopt(cli2
, sockops
);
942 printf("starting readwritetest\n");
944 test1
= rw_torture2(cli1
, cli2
);
945 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
948 test2
= rw_torture2(cli1
, cli1
);
949 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
952 if (!torture_close_connection(cli1
)) {
956 if (!torture_close_connection(cli2
)) {
960 return (test1
&& test2
);
963 static bool run_readwritemulti(int dummy
)
965 struct cli_state
*cli
;
970 cli_sockopt(cli
, sockops
);
972 printf("run_readwritemulti: fname %s\n", randomfname
);
973 test
= rw_torture3(cli
, randomfname
);
975 if (!torture_close_connection(cli
)) {
982 static bool run_readwritelarge_internal(void)
984 static struct cli_state
*cli1
;
986 const char *lockfname
= "\\large.dat";
992 if (!torture_open_connection(&cli1
, 0)) {
995 cli_sockopt(cli1
, sockops
);
996 memset(buf
,'\0',sizeof(buf
));
998 printf("starting readwritelarge_internal\n");
1000 cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1002 status
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1004 if (!NT_STATUS_IS_OK(status
)) {
1005 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1009 cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
), NULL
);
1011 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1013 if (!NT_STATUS_IS_OK(status
)) {
1014 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1018 if (fsize
== sizeof(buf
))
1019 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1020 (unsigned long)fsize
);
1022 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1023 (unsigned long)fsize
);
1027 status
= cli_close(cli1
, fnum1
);
1028 if (!NT_STATUS_IS_OK(status
)) {
1029 printf("close failed (%s)\n", nt_errstr(status
));
1033 status
= cli_unlink(cli1
, lockfname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1034 if (!NT_STATUS_IS_OK(status
)) {
1035 printf("unlink failed (%s)\n", nt_errstr(status
));
1039 status
= cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
1041 if (!NT_STATUS_IS_OK(status
)) {
1042 printf("open read/write of %s failed (%s)\n", lockfname
, nt_errstr(status
));
1046 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
), NULL
);
1048 status
= cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
,
1050 if (!NT_STATUS_IS_OK(status
)) {
1051 printf("qfileinfo failed (%s)\n", nt_errstr(status
));
1055 if (fsize
== sizeof(buf
))
1056 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1057 (unsigned long)fsize
);
1059 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1060 (unsigned long)fsize
);
1065 /* ToDo - set allocation. JRA */
1066 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
1067 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
1070 if (!cli_qfileinfo_basic(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
,
1072 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
1076 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
1079 status
= cli_close(cli1
, fnum1
);
1080 if (!NT_STATUS_IS_OK(status
)) {
1081 printf("close failed (%s)\n", nt_errstr(status
));
1085 if (!torture_close_connection(cli1
)) {
1091 static bool run_readwritelarge(int dummy
)
1093 return run_readwritelarge_internal();
1096 static bool run_readwritelarge_signtest(int dummy
)
1099 signing_state
= SMB_SIGNING_REQUIRED
;
1100 ret
= run_readwritelarge_internal();
1101 signing_state
= SMB_SIGNING_DEFAULT
;
1108 #define ival(s) strtol(s, NULL, 0)
1110 /* run a test that simulates an approximate netbench client load */
1111 static bool run_netbench(int client
)
1113 struct cli_state
*cli
;
1118 const char *params
[20];
1119 bool correct
= True
;
1125 cli_sockopt(cli
, sockops
);
1129 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
1131 f
= fopen(client_txt
, "r");
1138 while (fgets(line
, sizeof(line
)-1, f
)) {
1142 line
[strlen(line
)-1] = 0;
1144 /* printf("[%d] %s\n", line_count, line); */
1146 all_string_sub(line
,"client1", cname
, sizeof(line
));
1148 /* parse the command parameters */
1149 params
[0] = strtok_r(line
, " ", &saveptr
);
1151 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
1155 if (i
< 2) continue;
1157 if (!strncmp(params
[0],"SMB", 3)) {
1158 printf("ERROR: You are using a dbench 1 load file\n");
1162 if (!strcmp(params
[0],"NTCreateX")) {
1163 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
1165 } else if (!strcmp(params
[0],"Close")) {
1166 nb_close(ival(params
[1]));
1167 } else if (!strcmp(params
[0],"Rename")) {
1168 nb_rename(params
[1], params
[2]);
1169 } else if (!strcmp(params
[0],"Unlink")) {
1170 nb_unlink(params
[1]);
1171 } else if (!strcmp(params
[0],"Deltree")) {
1172 nb_deltree(params
[1]);
1173 } else if (!strcmp(params
[0],"Rmdir")) {
1174 nb_rmdir(params
[1]);
1175 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
1176 nb_qpathinfo(params
[1]);
1177 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
1178 nb_qfileinfo(ival(params
[1]));
1179 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
1180 nb_qfsinfo(ival(params
[1]));
1181 } else if (!strcmp(params
[0],"FIND_FIRST")) {
1182 nb_findfirst(params
[1]);
1183 } else if (!strcmp(params
[0],"WriteX")) {
1184 nb_writex(ival(params
[1]),
1185 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1186 } else if (!strcmp(params
[0],"ReadX")) {
1187 nb_readx(ival(params
[1]),
1188 ival(params
[2]), ival(params
[3]), ival(params
[4]));
1189 } else if (!strcmp(params
[0],"Flush")) {
1190 nb_flush(ival(params
[1]));
1192 printf("Unknown operation %s\n", params
[0]);
1200 if (!torture_close_connection(cli
)) {
1208 /* run a test that simulates an approximate netbench client load */
1209 static bool run_nbench(int dummy
)
1212 bool correct
= True
;
1218 signal(SIGALRM
, nb_alarm
);
1220 t
= create_procs(run_netbench
, &correct
);
1223 printf("\nThroughput %g MB/sec\n",
1224 1.0e-6 * nbio_total() / t
);
1230 This test checks for two things:
1232 1) correct support for retaining locks over a close (ie. the server
1233 must not use posix semantics)
1234 2) support for lock timeouts
1236 static bool run_locktest1(int dummy
)
1238 struct cli_state
*cli1
, *cli2
;
1239 const char *fname
= "\\lockt1.lck";
1240 uint16_t fnum1
, fnum2
, fnum3
;
1242 unsigned lock_timeout
;
1245 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1248 cli_sockopt(cli1
, sockops
);
1249 cli_sockopt(cli2
, sockops
);
1251 printf("starting locktest1\n");
1253 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1255 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1257 if (!NT_STATUS_IS_OK(status
)) {
1258 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1262 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1263 if (!NT_STATUS_IS_OK(status
)) {
1264 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1268 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1269 if (!NT_STATUS_IS_OK(status
)) {
1270 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1274 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1275 if (!NT_STATUS_IS_OK(status
)) {
1276 printf("lock1 failed (%s)\n", nt_errstr(status
));
1280 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1281 if (NT_STATUS_IS_OK(status
)) {
1282 printf("lock2 succeeded! This is a locking bug\n");
1285 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1286 NT_STATUS_LOCK_NOT_GRANTED
)) {
1291 lock_timeout
= (1 + (random() % 20));
1292 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1294 status
= cli_lock32(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
);
1295 if (NT_STATUS_IS_OK(status
)) {
1296 printf("lock3 succeeded! This is a locking bug\n");
1299 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1300 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1306 if (ABS(t2
- t1
) < lock_timeout
-1) {
1307 printf("error: This server appears not to support timed lock requests\n");
1310 printf("server slept for %u seconds for a %u second timeout\n",
1311 (unsigned int)(t2
-t1
), lock_timeout
);
1313 status
= cli_close(cli1
, fnum2
);
1314 if (!NT_STATUS_IS_OK(status
)) {
1315 printf("close1 failed (%s)\n", nt_errstr(status
));
1319 status
= cli_lock32(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1320 if (NT_STATUS_IS_OK(status
)) {
1321 printf("lock4 succeeded! This is a locking bug\n");
1324 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1325 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1330 status
= cli_close(cli1
, fnum1
);
1331 if (!NT_STATUS_IS_OK(status
)) {
1332 printf("close2 failed (%s)\n", nt_errstr(status
));
1336 status
= cli_close(cli2
, fnum3
);
1337 if (!NT_STATUS_IS_OK(status
)) {
1338 printf("close3 failed (%s)\n", nt_errstr(status
));
1342 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1343 if (!NT_STATUS_IS_OK(status
)) {
1344 printf("unlink failed (%s)\n", nt_errstr(status
));
1349 if (!torture_close_connection(cli1
)) {
1353 if (!torture_close_connection(cli2
)) {
1357 printf("Passed locktest1\n");
1362 this checks to see if a secondary tconx can use open files from an
1365 static bool run_tcon_test(int dummy
)
1367 static struct cli_state
*cli
;
1368 const char *fname
= "\\tcontest.tmp";
1370 uint16 cnum1
, cnum2
, cnum3
;
1371 uint16 vuid1
, vuid2
;
1376 memset(buf
, '\0', sizeof(buf
));
1378 if (!torture_open_connection(&cli
, 0)) {
1381 cli_sockopt(cli
, sockops
);
1383 printf("starting tcontest\n");
1385 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1387 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1388 if (!NT_STATUS_IS_OK(status
)) {
1389 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1393 cnum1
= cli_state_get_tid(cli
);
1394 vuid1
= cli_state_get_uid(cli
);
1396 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1397 if (!NT_STATUS_IS_OK(status
)) {
1398 printf("initial write failed (%s)", nt_errstr(status
));
1402 status
= cli_tcon_andx(cli
, share
, "?????",
1403 password
, strlen(password
)+1);
1404 if (!NT_STATUS_IS_OK(status
)) {
1405 printf("%s refused 2nd tree connect (%s)\n", host
,
1411 cnum2
= cli_state_get_tid(cli
);
1412 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1413 vuid2
= cli_state_get_uid(cli
) + 1;
1415 /* try a write with the wrong tid */
1416 cli_state_set_tid(cli
, cnum2
);
1418 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1419 if (NT_STATUS_IS_OK(status
)) {
1420 printf("* server allows write with wrong TID\n");
1423 printf("server fails write with wrong TID : %s\n",
1428 /* try a write with an invalid tid */
1429 cli_state_set_tid(cli
, cnum3
);
1431 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1432 if (NT_STATUS_IS_OK(status
)) {
1433 printf("* server allows write with invalid TID\n");
1436 printf("server fails write with invalid TID : %s\n",
1440 /* try a write with an invalid vuid */
1441 cli_state_set_uid(cli
, vuid2
);
1442 cli_state_set_tid(cli
, cnum1
);
1444 status
= cli_writeall(cli
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
1445 if (NT_STATUS_IS_OK(status
)) {
1446 printf("* server allows write with invalid VUID\n");
1449 printf("server fails write with invalid VUID : %s\n",
1453 cli_state_set_tid(cli
, cnum1
);
1454 cli_state_set_uid(cli
, vuid1
);
1456 status
= cli_close(cli
, fnum1
);
1457 if (!NT_STATUS_IS_OK(status
)) {
1458 printf("close failed (%s)\n", nt_errstr(status
));
1462 cli_state_set_tid(cli
, cnum2
);
1464 status
= cli_tdis(cli
);
1465 if (!NT_STATUS_IS_OK(status
)) {
1466 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1470 cli_state_set_tid(cli
, cnum1
);
1472 if (!torture_close_connection(cli
)) {
1481 checks for old style tcon support
1483 static bool run_tcon2_test(int dummy
)
1485 static struct cli_state
*cli
;
1486 uint16 cnum
, max_xmit
;
1490 if (!torture_open_connection(&cli
, 0)) {
1493 cli_sockopt(cli
, sockops
);
1495 printf("starting tcon2 test\n");
1497 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1501 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1505 if (!NT_STATUS_IS_OK(status
)) {
1506 printf("tcon2 failed : %s\n", nt_errstr(status
));
1508 printf("tcon OK : max_xmit=%d cnum=%d\n",
1509 (int)max_xmit
, (int)cnum
);
1512 if (!torture_close_connection(cli
)) {
1516 printf("Passed tcon2 test\n");
1520 static bool tcon_devtest(struct cli_state
*cli
,
1521 const char *myshare
, const char *devtype
,
1522 const char *return_devtype
,
1523 NTSTATUS expected_error
)
1528 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1529 password
, strlen(password
)+1);
1531 if (NT_STATUS_IS_OK(expected_error
)) {
1532 if (NT_STATUS_IS_OK(status
)) {
1533 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1536 printf("tconX to share %s with type %s "
1537 "succeeded but returned the wrong "
1538 "device type (got [%s] but should have got [%s])\n",
1539 myshare
, devtype
, cli
->dev
, return_devtype
);
1543 printf("tconX to share %s with type %s "
1544 "should have succeeded but failed\n",
1550 if (NT_STATUS_IS_OK(status
)) {
1551 printf("tconx to share %s with type %s "
1552 "should have failed but succeeded\n",
1556 if (NT_STATUS_EQUAL(status
, expected_error
)) {
1559 printf("Returned unexpected error\n");
1568 checks for correct tconX support
1570 static bool run_tcon_devtype_test(int dummy
)
1572 static struct cli_state
*cli1
= NULL
;
1577 status
= cli_full_connection(&cli1
, myname
,
1578 host
, NULL
, port_to_use
,
1580 username
, workgroup
,
1581 password
, flags
, signing_state
);
1583 if (!NT_STATUS_IS_OK(status
)) {
1584 printf("could not open connection\n");
1588 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1591 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1594 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1597 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1600 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1603 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1606 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1609 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1612 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1615 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1621 printf("Passed tcondevtest\n");
1628 This test checks that
1630 1) the server supports multiple locking contexts on the one SMB
1631 connection, distinguished by PID.
1633 2) the server correctly fails overlapping locks made by the same PID (this
1634 goes against POSIX behaviour, which is why it is tricky to implement)
1636 3) the server denies unlock requests by an incorrect client PID
1638 static bool run_locktest2(int dummy
)
1640 static struct cli_state
*cli
;
1641 const char *fname
= "\\lockt2.lck";
1642 uint16_t fnum1
, fnum2
, fnum3
;
1643 bool correct
= True
;
1646 if (!torture_open_connection(&cli
, 0)) {
1650 cli_sockopt(cli
, sockops
);
1652 printf("starting locktest2\n");
1654 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1658 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1659 if (!NT_STATUS_IS_OK(status
)) {
1660 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1664 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1665 if (!NT_STATUS_IS_OK(status
)) {
1666 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1672 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1673 if (!NT_STATUS_IS_OK(status
)) {
1674 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1680 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1681 if (!NT_STATUS_IS_OK(status
)) {
1682 printf("lock1 failed (%s)\n", nt_errstr(status
));
1686 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1687 if (NT_STATUS_IS_OK(status
)) {
1688 printf("WRITE lock1 succeeded! This is a locking bug\n");
1691 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1692 NT_STATUS_LOCK_NOT_GRANTED
)) {
1697 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1698 if (NT_STATUS_IS_OK(status
)) {
1699 printf("WRITE lock2 succeeded! This is a locking bug\n");
1702 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1703 NT_STATUS_LOCK_NOT_GRANTED
)) {
1708 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1709 if (NT_STATUS_IS_OK(status
)) {
1710 printf("READ lock2 succeeded! This is a locking bug\n");
1713 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1714 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1719 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1720 if (!NT_STATUS_IS_OK(status
)) {
1721 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1724 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1725 printf("unlock at 100 succeeded! This is a locking bug\n");
1729 status
= cli_unlock(cli
, fnum1
, 0, 4);
1730 if (NT_STATUS_IS_OK(status
)) {
1731 printf("unlock1 succeeded! This is a locking bug\n");
1734 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1735 NT_STATUS_RANGE_NOT_LOCKED
)) {
1740 status
= cli_unlock(cli
, fnum1
, 0, 8);
1741 if (NT_STATUS_IS_OK(status
)) {
1742 printf("unlock2 succeeded! This is a locking bug\n");
1745 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1746 NT_STATUS_RANGE_NOT_LOCKED
)) {
1751 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1752 if (NT_STATUS_IS_OK(status
)) {
1753 printf("lock3 succeeded! This is a locking bug\n");
1756 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1757 NT_STATUS_LOCK_NOT_GRANTED
)) {
1764 status
= cli_close(cli
, fnum1
);
1765 if (!NT_STATUS_IS_OK(status
)) {
1766 printf("close1 failed (%s)\n", nt_errstr(status
));
1770 status
= cli_close(cli
, fnum2
);
1771 if (!NT_STATUS_IS_OK(status
)) {
1772 printf("close2 failed (%s)\n", nt_errstr(status
));
1776 status
= cli_close(cli
, fnum3
);
1777 if (!NT_STATUS_IS_OK(status
)) {
1778 printf("close3 failed (%s)\n", nt_errstr(status
));
1782 if (!torture_close_connection(cli
)) {
1786 printf("locktest2 finished\n");
1793 This test checks that
1795 1) the server supports the full offset range in lock requests
1797 static bool run_locktest3(int dummy
)
1799 static struct cli_state
*cli1
, *cli2
;
1800 const char *fname
= "\\lockt3.lck";
1801 uint16_t fnum1
, fnum2
;
1804 bool correct
= True
;
1807 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1809 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1812 cli_sockopt(cli1
, sockops
);
1813 cli_sockopt(cli2
, sockops
);
1815 printf("starting locktest3\n");
1817 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1819 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1821 if (!NT_STATUS_IS_OK(status
)) {
1822 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1826 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1827 if (!NT_STATUS_IS_OK(status
)) {
1828 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1832 for (offset
=i
=0;i
<torture_numops
;i
++) {
1835 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1836 if (!NT_STATUS_IS_OK(status
)) {
1837 printf("lock1 %d failed (%s)\n",
1843 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1844 if (!NT_STATUS_IS_OK(status
)) {
1845 printf("lock2 %d failed (%s)\n",
1852 for (offset
=i
=0;i
<torture_numops
;i
++) {
1855 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1856 if (NT_STATUS_IS_OK(status
)) {
1857 printf("error: lock1 %d succeeded!\n", i
);
1861 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1862 if (NT_STATUS_IS_OK(status
)) {
1863 printf("error: lock2 %d succeeded!\n", i
);
1867 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1868 if (NT_STATUS_IS_OK(status
)) {
1869 printf("error: lock3 %d succeeded!\n", i
);
1873 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1874 if (NT_STATUS_IS_OK(status
)) {
1875 printf("error: lock4 %d succeeded!\n", i
);
1880 for (offset
=i
=0;i
<torture_numops
;i
++) {
1883 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1884 if (!NT_STATUS_IS_OK(status
)) {
1885 printf("unlock1 %d failed (%s)\n",
1891 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1892 if (!NT_STATUS_IS_OK(status
)) {
1893 printf("unlock2 %d failed (%s)\n",
1900 status
= cli_close(cli1
, fnum1
);
1901 if (!NT_STATUS_IS_OK(status
)) {
1902 printf("close1 failed (%s)\n", nt_errstr(status
));
1906 status
= cli_close(cli2
, fnum2
);
1907 if (!NT_STATUS_IS_OK(status
)) {
1908 printf("close2 failed (%s)\n", nt_errstr(status
));
1912 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1913 if (!NT_STATUS_IS_OK(status
)) {
1914 printf("unlink failed (%s)\n", nt_errstr(status
));
1918 if (!torture_close_connection(cli1
)) {
1922 if (!torture_close_connection(cli2
)) {
1926 printf("finished locktest3\n");
1931 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1932 char *buf
, off_t offset
, size_t size
,
1933 size_t *nread
, size_t expect
)
1938 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1940 if(!NT_STATUS_IS_OK(status
)) {
1942 } else if (l_nread
!= expect
) {
1953 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1954 printf("** "); correct = False; \
1958 looks at overlapping locks
1960 static bool run_locktest4(int dummy
)
1962 static struct cli_state
*cli1
, *cli2
;
1963 const char *fname
= "\\lockt4.lck";
1964 uint16_t fnum1
, fnum2
, f
;
1967 bool correct
= True
;
1970 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1974 cli_sockopt(cli1
, sockops
);
1975 cli_sockopt(cli2
, sockops
);
1977 printf("starting locktest4\n");
1979 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1981 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1982 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1984 memset(buf
, 0, sizeof(buf
));
1986 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1988 if (!NT_STATUS_IS_OK(status
)) {
1989 printf("Failed to create file: %s\n", nt_errstr(status
));
1994 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1995 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1996 EXPECTED(ret
, False
);
1997 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1999 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
2000 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
2001 EXPECTED(ret
, True
);
2002 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
2004 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
2005 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
2006 EXPECTED(ret
, False
);
2007 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
2009 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
2010 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
2011 EXPECTED(ret
, True
);
2012 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
2014 ret
= (cli_setpid(cli1
, 1),
2015 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
2016 (cli_setpid(cli1
, 2),
2017 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
2018 EXPECTED(ret
, False
);
2019 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
2021 ret
= (cli_setpid(cli1
, 1),
2022 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
2023 (cli_setpid(cli1
, 2),
2024 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
2025 EXPECTED(ret
, True
);
2026 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
2028 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
2029 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
2030 EXPECTED(ret
, True
);
2031 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
2033 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
2034 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
2035 EXPECTED(ret
, False
);
2036 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
2038 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
2039 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
2040 EXPECTED(ret
, False
);
2041 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
2043 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
2044 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
2045 EXPECTED(ret
, True
);
2046 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2048 ret
= (cli_setpid(cli1
, 1),
2049 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2050 (cli_setpid(cli1
, 2),
2051 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2052 EXPECTED(ret
, False
);
2053 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2055 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2056 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2057 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2058 EXPECTED(ret
, False
);
2059 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2062 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2063 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2064 EXPECTED(ret
, False
);
2065 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2067 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2068 ret
= NT_STATUS_IS_OK(status
);
2070 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2072 ret
= NT_STATUS_IS_OK(status
);
2074 EXPECTED(ret
, False
);
2075 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2078 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2079 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2082 EXPECTED(ret
, True
);
2083 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2086 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2087 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2088 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2089 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2090 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2092 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2093 EXPECTED(ret
, True
);
2094 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2096 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2097 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2098 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2100 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2101 EXPECTED(ret
, True
);
2102 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2104 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2105 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2106 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2108 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2109 EXPECTED(ret
, True
);
2110 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2112 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2113 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2114 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2115 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2117 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2118 EXPECTED(ret
, True
);
2119 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2121 cli_close(cli1
, fnum1
);
2122 cli_close(cli2
, fnum2
);
2123 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2124 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2125 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2126 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2127 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2128 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2129 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2131 cli_close(cli1
, fnum1
);
2132 EXPECTED(ret
, True
);
2133 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2136 cli_close(cli1
, fnum1
);
2137 cli_close(cli2
, fnum2
);
2138 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2139 torture_close_connection(cli1
);
2140 torture_close_connection(cli2
);
2142 printf("finished locktest4\n");
2147 looks at lock upgrade/downgrade.
2149 static bool run_locktest5(int dummy
)
2151 static struct cli_state
*cli1
, *cli2
;
2152 const char *fname
= "\\lockt5.lck";
2153 uint16_t fnum1
, fnum2
, fnum3
;
2156 bool correct
= True
;
2159 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2163 cli_sockopt(cli1
, sockops
);
2164 cli_sockopt(cli2
, sockops
);
2166 printf("starting locktest5\n");
2168 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2170 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2171 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2172 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2174 memset(buf
, 0, sizeof(buf
));
2176 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2178 if (!NT_STATUS_IS_OK(status
)) {
2179 printf("Failed to create file: %s\n", nt_errstr(status
));
2184 /* Check for NT bug... */
2185 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2186 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2187 cli_close(cli1
, fnum1
);
2188 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2189 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2190 ret
= NT_STATUS_IS_OK(status
);
2191 EXPECTED(ret
, True
);
2192 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2193 cli_close(cli1
, fnum1
);
2194 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2195 cli_unlock(cli1
, fnum3
, 0, 1);
2197 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2198 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2199 EXPECTED(ret
, True
);
2200 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2202 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2203 ret
= NT_STATUS_IS_OK(status
);
2204 EXPECTED(ret
, False
);
2206 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2208 /* Unlock the process 2 lock. */
2209 cli_unlock(cli2
, fnum2
, 0, 4);
2211 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2212 ret
= NT_STATUS_IS_OK(status
);
2213 EXPECTED(ret
, False
);
2215 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2217 /* Unlock the process 1 fnum3 lock. */
2218 cli_unlock(cli1
, fnum3
, 0, 4);
2220 /* Stack 2 more locks here. */
2221 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2222 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2224 EXPECTED(ret
, True
);
2225 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2227 /* Unlock the first process lock, then check this was the WRITE lock that was
2230 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2231 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2233 EXPECTED(ret
, True
);
2234 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2236 /* Unlock the process 2 lock. */
2237 cli_unlock(cli2
, fnum2
, 0, 4);
2239 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2241 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2242 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2243 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2245 EXPECTED(ret
, True
);
2246 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2248 /* Ensure the next unlock fails. */
2249 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2250 EXPECTED(ret
, False
);
2251 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2253 /* Ensure connection 2 can get a write lock. */
2254 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2255 ret
= NT_STATUS_IS_OK(status
);
2256 EXPECTED(ret
, True
);
2258 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2262 cli_close(cli1
, fnum1
);
2263 cli_close(cli2
, fnum2
);
2264 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2265 if (!torture_close_connection(cli1
)) {
2268 if (!torture_close_connection(cli2
)) {
2272 printf("finished locktest5\n");
2278 tries the unusual lockingX locktype bits
2280 static bool run_locktest6(int dummy
)
2282 static struct cli_state
*cli
;
2283 const char *fname
[1] = { "\\lock6.txt" };
2288 if (!torture_open_connection(&cli
, 0)) {
2292 cli_sockopt(cli
, sockops
);
2294 printf("starting locktest6\n");
2297 printf("Testing %s\n", fname
[i
]);
2299 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2301 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2302 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2303 cli_close(cli
, fnum
);
2304 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2306 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2307 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2308 cli_close(cli
, fnum
);
2309 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2311 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2314 torture_close_connection(cli
);
2316 printf("finished locktest6\n");
2320 static bool run_locktest7(int dummy
)
2322 struct cli_state
*cli1
;
2323 const char *fname
= "\\lockt7.lck";
2326 bool correct
= False
;
2330 if (!torture_open_connection(&cli1
, 0)) {
2334 cli_sockopt(cli1
, sockops
);
2336 printf("starting locktest7\n");
2338 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2340 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2342 memset(buf
, 0, sizeof(buf
));
2344 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2346 if (!NT_STATUS_IS_OK(status
)) {
2347 printf("Failed to create file: %s\n", nt_errstr(status
));
2351 cli_setpid(cli1
, 1);
2353 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2354 if (!NT_STATUS_IS_OK(status
)) {
2355 printf("Unable to apply read lock on range 130:4, "
2356 "error was %s\n", nt_errstr(status
));
2359 printf("pid1 successfully locked range 130:4 for READ\n");
2362 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2363 if (!NT_STATUS_IS_OK(status
)) {
2364 printf("pid1 unable to read the range 130:4, error was %s\n",
2367 } else if (nread
!= 4) {
2368 printf("pid1 unable to read the range 130:4, "
2369 "recv %ld req %d\n", (unsigned long)nread
, 4);
2372 printf("pid1 successfully read the range 130:4\n");
2375 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2376 if (!NT_STATUS_IS_OK(status
)) {
2377 printf("pid1 unable to write to the range 130:4, error was "
2378 "%s\n", nt_errstr(status
));
2379 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2380 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2384 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2388 cli_setpid(cli1
, 2);
2390 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2391 if (!NT_STATUS_IS_OK(status
)) {
2392 printf("pid2 unable to read the range 130:4, error was %s\n",
2395 } else if (nread
!= 4) {
2396 printf("pid2 unable to read the range 130:4, "
2397 "recv %ld req %d\n", (unsigned long)nread
, 4);
2400 printf("pid2 successfully read the range 130:4\n");
2403 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2404 if (!NT_STATUS_IS_OK(status
)) {
2405 printf("pid2 unable to write to the range 130:4, error was "
2406 "%s\n", nt_errstr(status
));
2407 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2408 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2412 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2416 cli_setpid(cli1
, 1);
2417 cli_unlock(cli1
, fnum1
, 130, 4);
2419 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2420 if (!NT_STATUS_IS_OK(status
)) {
2421 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2424 printf("pid1 successfully locked range 130:4 for WRITE\n");
2427 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2428 if (!NT_STATUS_IS_OK(status
)) {
2429 printf("pid1 unable to read the range 130:4, error was %s\n",
2432 } else if (nread
!= 4) {
2433 printf("pid1 unable to read the range 130:4, "
2434 "recv %ld req %d\n", (unsigned long)nread
, 4);
2437 printf("pid1 successfully read the range 130:4\n");
2440 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2441 if (!NT_STATUS_IS_OK(status
)) {
2442 printf("pid1 unable to write to the range 130:4, error was "
2443 "%s\n", nt_errstr(status
));
2446 printf("pid1 successfully wrote to the range 130:4\n");
2449 cli_setpid(cli1
, 2);
2451 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2452 if (!NT_STATUS_IS_OK(status
)) {
2453 printf("pid2 unable to read the range 130:4, error was "
2454 "%s\n", nt_errstr(status
));
2455 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2456 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2460 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2461 (unsigned long)nread
);
2465 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2466 if (!NT_STATUS_IS_OK(status
)) {
2467 printf("pid2 unable to write to the range 130:4, error was "
2468 "%s\n", nt_errstr(status
));
2469 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2470 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2474 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2478 cli_unlock(cli1
, fnum1
, 130, 0);
2482 cli_close(cli1
, fnum1
);
2483 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2484 torture_close_connection(cli1
);
2486 printf("finished locktest7\n");
2491 * This demonstrates a problem with our use of GPFS share modes: A file
2492 * descriptor sitting in the pending close queue holding a GPFS share mode
2493 * blocks opening a file another time. Happens with Word 2007 temp files.
2494 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2495 * open is denied with NT_STATUS_SHARING_VIOLATION.
2498 static bool run_locktest8(int dummy
)
2500 struct cli_state
*cli1
;
2501 const char *fname
= "\\lockt8.lck";
2502 uint16_t fnum1
, fnum2
;
2504 bool correct
= False
;
2507 if (!torture_open_connection(&cli1
, 0)) {
2511 cli_sockopt(cli1
, sockops
);
2513 printf("starting locktest8\n");
2515 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2517 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2519 if (!NT_STATUS_IS_OK(status
)) {
2520 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2524 memset(buf
, 0, sizeof(buf
));
2526 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2527 if (!NT_STATUS_IS_OK(status
)) {
2528 d_fprintf(stderr
, "cli_open second time returned %s\n",
2533 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2534 if (!NT_STATUS_IS_OK(status
)) {
2535 printf("Unable to apply read lock on range 1:1, error was "
2536 "%s\n", nt_errstr(status
));
2540 status
= cli_close(cli1
, fnum1
);
2541 if (!NT_STATUS_IS_OK(status
)) {
2542 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2546 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2547 if (!NT_STATUS_IS_OK(status
)) {
2548 d_fprintf(stderr
, "cli_open third time returned %s\n",
2556 cli_close(cli1
, fnum1
);
2557 cli_close(cli1
, fnum2
);
2558 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2559 torture_close_connection(cli1
);
2561 printf("finished locktest8\n");
2566 * This test is designed to be run in conjunction with
2567 * external NFS or POSIX locks taken in the filesystem.
2568 * It checks that the smbd server will block until the
2569 * lock is released and then acquire it. JRA.
2572 static bool got_alarm
;
2573 static struct cli_state
*alarm_cli
;
2575 static void alarm_handler(int dummy
)
2580 static void alarm_handler_parent(int dummy
)
2582 cli_state_disconnect(alarm_cli
);
2585 static void do_local_lock(int read_fd
, int write_fd
)
2590 const char *local_pathname
= NULL
;
2593 local_pathname
= talloc_asprintf(talloc_tos(),
2594 "%s/lockt9.lck", local_path
);
2595 if (!local_pathname
) {
2596 printf("child: alloc fail\n");
2600 unlink(local_pathname
);
2601 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2603 printf("child: open of %s failed %s.\n",
2604 local_pathname
, strerror(errno
));
2608 /* Now take a fcntl lock. */
2609 lock
.l_type
= F_WRLCK
;
2610 lock
.l_whence
= SEEK_SET
;
2613 lock
.l_pid
= getpid();
2615 ret
= fcntl(fd
,F_SETLK
,&lock
);
2617 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2618 local_pathname
, strerror(errno
));
2621 printf("child: got lock 0:4 on file %s.\n",
2626 CatchSignal(SIGALRM
, alarm_handler
);
2628 /* Signal the parent. */
2629 if (write(write_fd
, &c
, 1) != 1) {
2630 printf("child: start signal fail %s.\n",
2637 /* Wait for the parent to be ready. */
2638 if (read(read_fd
, &c
, 1) != 1) {
2639 printf("child: reply signal fail %s.\n",
2647 printf("child: released lock 0:4 on file %s.\n",
2653 static bool run_locktest9(int dummy
)
2655 struct cli_state
*cli1
;
2656 const char *fname
= "\\lockt9.lck";
2658 bool correct
= False
;
2659 int pipe_in
[2], pipe_out
[2];
2663 struct timeval start
;
2667 printf("starting locktest9\n");
2669 if (local_path
== NULL
) {
2670 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2674 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2679 if (child_pid
== -1) {
2683 if (child_pid
== 0) {
2685 do_local_lock(pipe_out
[0], pipe_in
[1]);
2695 ret
= read(pipe_in
[0], &c
, 1);
2697 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2702 if (!torture_open_connection(&cli1
, 0)) {
2706 cli_sockopt(cli1
, sockops
);
2708 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2710 if (!NT_STATUS_IS_OK(status
)) {
2711 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2715 /* Ensure the child has the lock. */
2716 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2717 if (NT_STATUS_IS_OK(status
)) {
2718 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2721 d_printf("Child has the lock.\n");
2724 /* Tell the child to wait 5 seconds then exit. */
2725 ret
= write(pipe_out
[1], &c
, 1);
2727 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2732 /* Wait 20 seconds for the lock. */
2734 CatchSignal(SIGALRM
, alarm_handler_parent
);
2737 start
= timeval_current();
2739 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2740 if (!NT_STATUS_IS_OK(status
)) {
2741 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2742 "%s\n", nt_errstr(status
));
2747 seconds
= timeval_elapsed(&start
);
2749 printf("Parent got the lock after %.2f seconds.\n",
2752 status
= cli_close(cli1
, fnum
);
2753 if (!NT_STATUS_IS_OK(status
)) {
2754 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2761 cli_close(cli1
, fnum
);
2762 torture_close_connection(cli1
);
2766 printf("finished locktest9\n");
2771 test whether fnums and tids open on one VC are available on another (a major
2774 static bool run_fdpasstest(int dummy
)
2776 struct cli_state
*cli1
, *cli2
;
2777 const char *fname
= "\\fdpass.tst";
2782 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2785 cli_sockopt(cli1
, sockops
);
2786 cli_sockopt(cli2
, sockops
);
2788 printf("starting fdpasstest\n");
2790 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2792 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2794 if (!NT_STATUS_IS_OK(status
)) {
2795 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2799 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2801 if (!NT_STATUS_IS_OK(status
)) {
2802 printf("write failed (%s)\n", nt_errstr(status
));
2806 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2807 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2808 cli_setpid(cli2
, cli_getpid(cli1
));
2810 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2811 printf("read succeeded! nasty security hole [%s]\n", buf
);
2815 cli_close(cli1
, fnum1
);
2816 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2818 torture_close_connection(cli1
);
2819 torture_close_connection(cli2
);
2821 printf("finished fdpasstest\n");
2825 static bool run_fdsesstest(int dummy
)
2827 struct cli_state
*cli
;
2832 const char *fname
= "\\fdsess.tst";
2833 const char *fname1
= "\\fdsess1.tst";
2840 if (!torture_open_connection(&cli
, 0))
2842 cli_sockopt(cli
, sockops
);
2844 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2847 saved_cnum
= cli_state_get_tid(cli
);
2848 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2850 new_cnum
= cli_state_get_tid(cli
);
2851 cli_state_set_tid(cli
, saved_cnum
);
2853 printf("starting fdsesstest\n");
2855 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2856 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2858 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2859 if (!NT_STATUS_IS_OK(status
)) {
2860 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2864 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2866 if (!NT_STATUS_IS_OK(status
)) {
2867 printf("write failed (%s)\n", nt_errstr(status
));
2871 saved_vuid
= cli_state_get_uid(cli
);
2872 cli_state_set_uid(cli
, new_vuid
);
2874 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2875 printf("read succeeded with different vuid! "
2876 "nasty security hole [%s]\n", buf
);
2879 /* Try to open a file with different vuid, samba cnum. */
2880 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2881 printf("create with different vuid, same cnum succeeded.\n");
2882 cli_close(cli
, fnum2
);
2883 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2885 printf("create with different vuid, same cnum failed.\n");
2886 printf("This will cause problems with service clients.\n");
2890 cli_state_set_uid(cli
, saved_vuid
);
2892 /* Try with same vuid, different cnum. */
2893 cli_state_set_tid(cli
, new_cnum
);
2895 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2896 printf("read succeeded with different cnum![%s]\n", buf
);
2900 cli_state_set_tid(cli
, saved_cnum
);
2901 cli_close(cli
, fnum1
);
2902 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2904 torture_close_connection(cli
);
2906 printf("finished fdsesstest\n");
2911 This test checks that
2913 1) the server does not allow an unlink on a file that is open
2915 static bool run_unlinktest(int dummy
)
2917 struct cli_state
*cli
;
2918 const char *fname
= "\\unlink.tst";
2920 bool correct
= True
;
2923 if (!torture_open_connection(&cli
, 0)) {
2927 cli_sockopt(cli
, sockops
);
2929 printf("starting unlink test\n");
2931 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2935 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2936 if (!NT_STATUS_IS_OK(status
)) {
2937 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2941 status
= cli_unlink(cli
, fname
,
2942 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2943 if (NT_STATUS_IS_OK(status
)) {
2944 printf("error: server allowed unlink on an open file\n");
2947 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2948 NT_STATUS_SHARING_VIOLATION
);
2951 cli_close(cli
, fnum
);
2952 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2954 if (!torture_close_connection(cli
)) {
2958 printf("unlink test finished\n");
2965 test how many open files this server supports on the one socket
2967 static bool run_maxfidtest(int dummy
)
2969 struct cli_state
*cli
;
2971 uint16_t fnums
[0x11000];
2974 bool correct
= True
;
2980 printf("failed to connect\n");
2984 cli_sockopt(cli
, sockops
);
2986 for (i
=0; i
<0x11000; i
++) {
2987 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2988 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2990 if (!NT_STATUS_IS_OK(status
)) {
2991 printf("open of %s failed (%s)\n",
2992 fname
, nt_errstr(status
));
2993 printf("maximum fnum is %d\n", i
);
3001 printf("cleaning up\n");
3003 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
3004 cli_close(cli
, fnums
[i
]);
3006 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3007 if (!NT_STATUS_IS_OK(status
)) {
3008 printf("unlink of %s failed (%s)\n",
3009 fname
, nt_errstr(status
));
3016 printf("maxfid test finished\n");
3017 if (!torture_close_connection(cli
)) {
3023 /* generate a random buffer */
3024 static void rand_buf(char *buf
, int len
)
3027 *buf
= (char)sys_random();
3032 /* send smb negprot commands, not reading the response */
3033 static bool run_negprot_nowait(int dummy
)
3035 struct tevent_context
*ev
;
3037 struct cli_state
*cli
;
3038 bool correct
= True
;
3040 printf("starting negprot nowait test\n");
3042 ev
= tevent_context_init(talloc_tos());
3047 if (!(cli
= open_nbt_connection())) {
3052 for (i
=0;i
<50000;i
++) {
3053 struct tevent_req
*req
;
3055 req
= cli_negprot_send(ev
, ev
, cli
, PROTOCOL_NT1
);
3060 if (!tevent_req_poll(req
, ev
)) {
3061 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3069 if (torture_close_connection(cli
)) {
3073 printf("finished negprot nowait test\n");
3078 /* send smb negprot commands, not reading the response */
3079 static bool run_bad_nbt_session(int dummy
)
3081 struct nmb_name called
, calling
;
3082 struct sockaddr_storage ss
;
3087 printf("starting bad nbt session test\n");
3089 make_nmb_name(&calling
, myname
, 0x0);
3090 make_nmb_name(&called
, host
, 0x20);
3092 if (!resolve_name(host
, &ss
, 0x20, true)) {
3093 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3097 status
= open_socket_out(&ss
, 139, 10000, &fd
);
3098 if (!NT_STATUS_IS_OK(status
)) {
3099 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3104 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3107 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3112 printf("finished bad nbt session test\n");
3116 /* send random IPC commands */
3117 static bool run_randomipc(int dummy
)
3119 char *rparam
= NULL
;
3121 unsigned int rdrcnt
,rprcnt
;
3123 int api
, param_len
, i
;
3124 struct cli_state
*cli
;
3125 bool correct
= True
;
3128 printf("starting random ipc test\n");
3130 if (!torture_open_connection(&cli
, 0)) {
3134 for (i
=0;i
<count
;i
++) {
3135 api
= sys_random() % 500;
3136 param_len
= (sys_random() % 64);
3138 rand_buf(param
, param_len
);
3143 param
, param_len
, 8,
3144 NULL
, 0, BUFFER_SIZE
,
3148 printf("%d/%d\r", i
,count
);
3151 printf("%d/%d\n", i
, count
);
3153 if (!torture_close_connection(cli
)) {
3157 printf("finished random ipc test\n");
3164 static void browse_callback(const char *sname
, uint32 stype
,
3165 const char *comment
, void *state
)
3167 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3173 This test checks the browse list code
3176 static bool run_browsetest(int dummy
)
3178 static struct cli_state
*cli
;
3179 bool correct
= True
;
3181 printf("starting browse test\n");
3183 if (!torture_open_connection(&cli
, 0)) {
3187 printf("domain list:\n");
3188 cli_NetServerEnum(cli
, cli
->server_domain
,
3189 SV_TYPE_DOMAIN_ENUM
,
3190 browse_callback
, NULL
);
3192 printf("machine list:\n");
3193 cli_NetServerEnum(cli
, cli
->server_domain
,
3195 browse_callback
, NULL
);
3197 if (!torture_close_connection(cli
)) {
3201 printf("browse test finished\n");
3209 This checks how the getatr calls works
3211 static bool run_attrtest(int dummy
)
3213 struct cli_state
*cli
;
3216 const char *fname
= "\\attrib123456789.tst";
3217 bool correct
= True
;
3220 printf("starting attrib test\n");
3222 if (!torture_open_connection(&cli
, 0)) {
3226 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3227 cli_open(cli
, fname
,
3228 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3229 cli_close(cli
, fnum
);
3231 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3232 if (!NT_STATUS_IS_OK(status
)) {
3233 printf("getatr failed (%s)\n", nt_errstr(status
));
3237 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3238 printf("ERROR: SMBgetatr bug. time is %s",
3244 t2
= t
-60*60*24; /* 1 day ago */
3246 status
= cli_setatr(cli
, fname
, 0, t2
);
3247 if (!NT_STATUS_IS_OK(status
)) {
3248 printf("setatr failed (%s)\n", nt_errstr(status
));
3252 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3253 if (!NT_STATUS_IS_OK(status
)) {
3254 printf("getatr failed (%s)\n", nt_errstr(status
));
3259 printf("ERROR: getatr/setatr bug. times are\n%s",
3261 printf("%s", ctime(&t2
));
3265 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3267 if (!torture_close_connection(cli
)) {
3271 printf("attrib test finished\n");
3278 This checks a couple of trans2 calls
3280 static bool run_trans2test(int dummy
)
3282 struct cli_state
*cli
;
3285 time_t c_time
, a_time
, m_time
;
3286 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3287 const char *fname
= "\\trans2.tst";
3288 const char *dname
= "\\trans2";
3289 const char *fname2
= "\\trans2\\trans2.tst";
3291 bool correct
= True
;
3295 printf("starting trans2 test\n");
3297 if (!torture_open_connection(&cli
, 0)) {
3301 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3302 if (!NT_STATUS_IS_OK(status
)) {
3303 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3308 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3309 cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3310 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3311 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3312 if (!NT_STATUS_IS_OK(status
)) {
3313 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3317 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3318 if (!NT_STATUS_IS_OK(status
)) {
3319 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3323 if (strcmp(pname
, fname
)) {
3324 printf("qfilename gave different name? [%s] [%s]\n",
3329 cli_close(cli
, fnum
);
3333 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3334 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3336 if (!NT_STATUS_IS_OK(status
)) {
3337 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3340 cli_close(cli
, fnum
);
3342 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3344 if (!NT_STATUS_IS_OK(status
)) {
3345 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3348 time_t t
= time(NULL
);
3350 if (c_time
!= m_time
) {
3351 printf("create time=%s", ctime(&c_time
));
3352 printf("modify time=%s", ctime(&m_time
));
3353 printf("This system appears to have sticky create times\n");
3355 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3356 printf("access time=%s", ctime(&a_time
));
3357 printf("This system appears to set a midnight access time\n");
3361 if (abs(m_time
- t
) > 60*60*24*7) {
3362 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3368 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3369 cli_open(cli
, fname
,
3370 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3371 cli_close(cli
, fnum
);
3372 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3373 &m_time_ts
, &size
, NULL
, NULL
);
3374 if (!NT_STATUS_IS_OK(status
)) {
3375 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3378 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3379 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3380 printf("This system appears to set a initial 0 write time\n");
3385 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3388 /* check if the server updates the directory modification time
3389 when creating a new file */
3390 status
= cli_mkdir(cli
, dname
);
3391 if (!NT_STATUS_IS_OK(status
)) {
3392 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3396 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3397 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3398 if (!NT_STATUS_IS_OK(status
)) {
3399 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3403 cli_open(cli
, fname2
,
3404 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3405 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3406 cli_close(cli
, fnum
);
3407 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3408 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3409 if (!NT_STATUS_IS_OK(status
)) {
3410 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3413 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3415 printf("This system does not update directory modification times\n");
3419 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3420 cli_rmdir(cli
, dname
);
3422 if (!torture_close_connection(cli
)) {
3426 printf("trans2 test finished\n");
3432 This checks new W2K calls.
3435 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3437 uint8_t *buf
= NULL
;
3441 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3442 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3443 if (!NT_STATUS_IS_OK(status
)) {
3444 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3447 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3448 dump_data(0, (uint8
*)buf
, len
);
3455 static bool run_w2ktest(int dummy
)
3457 struct cli_state
*cli
;
3459 const char *fname
= "\\w2ktest\\w2k.tst";
3461 bool correct
= True
;
3463 printf("starting w2k test\n");
3465 if (!torture_open_connection(&cli
, 0)) {
3469 cli_open(cli
, fname
,
3470 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3472 for (level
= 1004; level
< 1040; level
++) {
3473 new_trans(cli
, fnum
, level
);
3476 cli_close(cli
, fnum
);
3478 if (!torture_close_connection(cli
)) {
3482 printf("w2k test finished\n");
3489 this is a harness for some oplock tests
3491 static bool run_oplock1(int dummy
)
3493 struct cli_state
*cli1
;
3494 const char *fname
= "\\lockt1.lck";
3496 bool correct
= True
;
3499 printf("starting oplock test 1\n");
3501 if (!torture_open_connection(&cli1
, 0)) {
3505 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3507 cli_sockopt(cli1
, sockops
);
3509 cli1
->use_oplocks
= True
;
3511 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3513 if (!NT_STATUS_IS_OK(status
)) {
3514 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3518 cli1
->use_oplocks
= False
;
3520 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3521 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3523 status
= cli_close(cli1
, fnum1
);
3524 if (!NT_STATUS_IS_OK(status
)) {
3525 printf("close2 failed (%s)\n", nt_errstr(status
));
3529 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3530 if (!NT_STATUS_IS_OK(status
)) {
3531 printf("unlink failed (%s)\n", nt_errstr(status
));
3535 if (!torture_close_connection(cli1
)) {
3539 printf("finished oplock test 1\n");
3544 static bool run_oplock2(int dummy
)
3546 struct cli_state
*cli1
, *cli2
;
3547 const char *fname
= "\\lockt2.lck";
3548 uint16_t fnum1
, fnum2
;
3549 int saved_use_oplocks
= use_oplocks
;
3551 bool correct
= True
;
3552 volatile bool *shared_correct
;
3556 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3557 *shared_correct
= True
;
3559 use_level_II_oplocks
= True
;
3562 printf("starting oplock test 2\n");
3564 if (!torture_open_connection(&cli1
, 0)) {
3565 use_level_II_oplocks
= False
;
3566 use_oplocks
= saved_use_oplocks
;
3570 if (!torture_open_connection(&cli2
, 1)) {
3571 use_level_II_oplocks
= False
;
3572 use_oplocks
= saved_use_oplocks
;
3576 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3578 cli_sockopt(cli1
, sockops
);
3579 cli_sockopt(cli2
, sockops
);
3581 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3583 if (!NT_STATUS_IS_OK(status
)) {
3584 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3588 /* Don't need the globals any more. */
3589 use_level_II_oplocks
= False
;
3590 use_oplocks
= saved_use_oplocks
;
3594 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3595 if (!NT_STATUS_IS_OK(status
)) {
3596 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3597 *shared_correct
= False
;
3603 status
= cli_close(cli2
, fnum2
);
3604 if (!NT_STATUS_IS_OK(status
)) {
3605 printf("close2 failed (%s)\n", nt_errstr(status
));
3606 *shared_correct
= False
;
3614 /* Ensure cli1 processes the break. Empty file should always return 0
3616 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3617 if (!NT_STATUS_IS_OK(status
)) {
3618 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3620 } else if (nread
!= 0) {
3621 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3622 (unsigned long)nread
, 0);
3626 /* Should now be at level II. */
3627 /* Test if sending a write locks causes a break to none. */
3628 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3629 if (!NT_STATUS_IS_OK(status
)) {
3630 printf("lock failed (%s)\n", nt_errstr(status
));
3634 cli_unlock(cli1
, fnum1
, 0, 4);
3638 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3639 if (!NT_STATUS_IS_OK(status
)) {
3640 printf("lock failed (%s)\n", nt_errstr(status
));
3644 cli_unlock(cli1
, fnum1
, 0, 4);
3648 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3650 status
= cli_close(cli1
, fnum1
);
3651 if (!NT_STATUS_IS_OK(status
)) {
3652 printf("close1 failed (%s)\n", nt_errstr(status
));
3658 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3659 if (!NT_STATUS_IS_OK(status
)) {
3660 printf("unlink failed (%s)\n", nt_errstr(status
));
3664 if (!torture_close_connection(cli1
)) {
3668 if (!*shared_correct
) {
3672 printf("finished oplock test 2\n");
3677 struct oplock4_state
{
3678 struct tevent_context
*ev
;
3679 struct cli_state
*cli
;
3684 static void oplock4_got_break(struct tevent_req
*req
);
3685 static void oplock4_got_open(struct tevent_req
*req
);
3687 static bool run_oplock4(int dummy
)
3689 struct tevent_context
*ev
;
3690 struct cli_state
*cli1
, *cli2
;
3691 struct tevent_req
*oplock_req
, *open_req
;
3692 const char *fname
= "\\lockt4.lck";
3693 const char *fname_ln
= "\\lockt4_ln.lck";
3694 uint16_t fnum1
, fnum2
;
3695 int saved_use_oplocks
= use_oplocks
;
3697 bool correct
= true;
3701 struct oplock4_state
*state
;
3703 printf("starting oplock test 4\n");
3705 if (!torture_open_connection(&cli1
, 0)) {
3706 use_level_II_oplocks
= false;
3707 use_oplocks
= saved_use_oplocks
;
3711 if (!torture_open_connection(&cli2
, 1)) {
3712 use_level_II_oplocks
= false;
3713 use_oplocks
= saved_use_oplocks
;
3717 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3718 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3720 cli_sockopt(cli1
, sockops
);
3721 cli_sockopt(cli2
, sockops
);
3723 /* Create the file. */
3724 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3726 if (!NT_STATUS_IS_OK(status
)) {
3727 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3731 status
= cli_close(cli1
, fnum1
);
3732 if (!NT_STATUS_IS_OK(status
)) {
3733 printf("close1 failed (%s)\n", nt_errstr(status
));
3737 /* Now create a hardlink. */
3738 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3739 if (!NT_STATUS_IS_OK(status
)) {
3740 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3744 /* Prove that opening hardlinks cause deny modes to conflict. */
3745 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3746 if (!NT_STATUS_IS_OK(status
)) {
3747 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3751 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3752 if (NT_STATUS_IS_OK(status
)) {
3753 printf("open of %s succeeded - should fail with sharing violation.\n",
3758 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3759 printf("open of %s should fail with sharing violation. Got %s\n",
3760 fname_ln
, nt_errstr(status
));
3764 status
= cli_close(cli1
, fnum1
);
3765 if (!NT_STATUS_IS_OK(status
)) {
3766 printf("close1 failed (%s)\n", nt_errstr(status
));
3770 cli1
->use_oplocks
= true;
3771 cli2
->use_oplocks
= true;
3773 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3774 if (!NT_STATUS_IS_OK(status
)) {
3775 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3779 ev
= tevent_context_init(talloc_tos());
3781 printf("tevent_req_create failed\n");
3785 state
= talloc(ev
, struct oplock4_state
);
3786 if (state
== NULL
) {
3787 printf("talloc failed\n");
3792 state
->got_break
= &got_break
;
3793 state
->fnum2
= &fnum2
;
3795 oplock_req
= cli_smb_oplock_break_waiter_send(
3796 talloc_tos(), ev
, cli1
);
3797 if (oplock_req
== NULL
) {
3798 printf("cli_smb_oplock_break_waiter_send failed\n");
3801 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3803 open_req
= cli_open_send(
3804 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3805 if (oplock_req
== NULL
) {
3806 printf("cli_open_send failed\n");
3809 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3814 while (!got_break
|| fnum2
== 0xffff) {
3816 ret
= tevent_loop_once(ev
);
3818 printf("tevent_loop_once failed: %s\n",
3824 status
= cli_close(cli2
, fnum2
);
3825 if (!NT_STATUS_IS_OK(status
)) {
3826 printf("close2 failed (%s)\n", nt_errstr(status
));
3830 status
= cli_close(cli1
, fnum1
);
3831 if (!NT_STATUS_IS_OK(status
)) {
3832 printf("close1 failed (%s)\n", nt_errstr(status
));
3836 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3837 if (!NT_STATUS_IS_OK(status
)) {
3838 printf("unlink failed (%s)\n", nt_errstr(status
));
3842 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3843 if (!NT_STATUS_IS_OK(status
)) {
3844 printf("unlink failed (%s)\n", nt_errstr(status
));
3848 if (!torture_close_connection(cli1
)) {
3856 printf("finished oplock test 4\n");
3861 static void oplock4_got_break(struct tevent_req
*req
)
3863 struct oplock4_state
*state
= tevent_req_callback_data(
3864 req
, struct oplock4_state
);
3869 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3871 if (!NT_STATUS_IS_OK(status
)) {
3872 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3876 *state
->got_break
= true;
3878 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3881 printf("cli_oplock_ack_send failed\n");
3886 static void oplock4_got_open(struct tevent_req
*req
)
3888 struct oplock4_state
*state
= tevent_req_callback_data(
3889 req
, struct oplock4_state
);
3892 status
= cli_open_recv(req
, state
->fnum2
);
3893 if (!NT_STATUS_IS_OK(status
)) {
3894 printf("cli_open_recv returned %s\n", nt_errstr(status
));
3895 *state
->fnum2
= 0xffff;
3900 Test delete on close semantics.
3902 static bool run_deletetest(int dummy
)
3904 struct cli_state
*cli1
= NULL
;
3905 struct cli_state
*cli2
= NULL
;
3906 const char *fname
= "\\delete.file";
3907 uint16_t fnum1
= (uint16_t)-1;
3908 uint16_t fnum2
= (uint16_t)-1;
3909 bool correct
= True
;
3912 printf("starting delete test\n");
3914 if (!torture_open_connection(&cli1
, 0)) {
3918 cli_sockopt(cli1
, sockops
);
3920 /* Test 1 - this should delete the file on close. */
3922 cli_setatr(cli1
, fname
, 0, 0);
3923 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3925 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3926 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3927 FILE_DELETE_ON_CLOSE
, 0, &fnum1
);
3928 if (!NT_STATUS_IS_OK(status
)) {
3929 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3934 status
= cli_close(cli1
, fnum1
);
3935 if (!NT_STATUS_IS_OK(status
)) {
3936 printf("[1] close failed (%s)\n", nt_errstr(status
));
3941 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3942 printf("[1] open of %s succeeded (should fail)\n", fname
);
3947 printf("first delete on close test succeeded.\n");
3949 /* Test 2 - this should delete the file on close. */
3951 cli_setatr(cli1
, fname
, 0, 0);
3952 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3954 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3955 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3956 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3957 if (!NT_STATUS_IS_OK(status
)) {
3958 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3963 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3964 if (!NT_STATUS_IS_OK(status
)) {
3965 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3970 status
= cli_close(cli1
, fnum1
);
3971 if (!NT_STATUS_IS_OK(status
)) {
3972 printf("[2] close failed (%s)\n", nt_errstr(status
));
3977 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3978 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3979 status
= cli_close(cli1
, fnum1
);
3980 if (!NT_STATUS_IS_OK(status
)) {
3981 printf("[2] close failed (%s)\n", nt_errstr(status
));
3985 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3987 printf("second delete on close test succeeded.\n");
3990 cli_setatr(cli1
, fname
, 0, 0);
3991 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3993 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3994 FILE_ATTRIBUTE_NORMAL
,
3995 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3996 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3997 if (!NT_STATUS_IS_OK(status
)) {
3998 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4003 /* This should fail with a sharing violation - open for delete is only compatible
4004 with SHARE_DELETE. */
4006 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4007 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
4008 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4013 /* This should succeed. */
4014 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4015 FILE_ATTRIBUTE_NORMAL
,
4016 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4017 FILE_OPEN
, 0, 0, &fnum2
);
4018 if (!NT_STATUS_IS_OK(status
)) {
4019 printf("[3] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4024 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4025 if (!NT_STATUS_IS_OK(status
)) {
4026 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4031 status
= cli_close(cli1
, fnum1
);
4032 if (!NT_STATUS_IS_OK(status
)) {
4033 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
4038 status
= cli_close(cli1
, fnum2
);
4039 if (!NT_STATUS_IS_OK(status
)) {
4040 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
4045 /* This should fail - file should no longer be there. */
4047 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4048 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4049 status
= cli_close(cli1
, fnum1
);
4050 if (!NT_STATUS_IS_OK(status
)) {
4051 printf("[3] close failed (%s)\n", nt_errstr(status
));
4053 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4057 printf("third delete on close test succeeded.\n");
4060 cli_setatr(cli1
, fname
, 0, 0);
4061 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4063 status
= cli_ntcreate(cli1
, fname
, 0,
4064 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4065 FILE_ATTRIBUTE_NORMAL
,
4066 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4067 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4068 if (!NT_STATUS_IS_OK(status
)) {
4069 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4074 /* This should succeed. */
4075 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4076 FILE_ATTRIBUTE_NORMAL
,
4077 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4078 FILE_OPEN
, 0, 0, &fnum2
);
4079 if (!NT_STATUS_IS_OK(status
)) {
4080 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4085 status
= cli_close(cli1
, fnum2
);
4086 if (!NT_STATUS_IS_OK(status
)) {
4087 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4092 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4093 if (!NT_STATUS_IS_OK(status
)) {
4094 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4099 /* This should fail - no more opens once delete on close set. */
4100 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4101 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4102 FILE_OPEN
, 0, 0, &fnum2
))) {
4103 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4107 printf("fourth delete on close test succeeded.\n");
4109 status
= cli_close(cli1
, fnum1
);
4110 if (!NT_STATUS_IS_OK(status
)) {
4111 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4117 cli_setatr(cli1
, fname
, 0, 0);
4118 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4120 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4121 if (!NT_STATUS_IS_OK(status
)) {
4122 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4127 /* This should fail - only allowed on NT opens with DELETE access. */
4129 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4130 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4135 status
= cli_close(cli1
, fnum1
);
4136 if (!NT_STATUS_IS_OK(status
)) {
4137 printf("[5] close - 2 failed (%s)\n", nt_errstr(status
));
4142 printf("fifth delete on close test succeeded.\n");
4145 cli_setatr(cli1
, fname
, 0, 0);
4146 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4148 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4149 FILE_ATTRIBUTE_NORMAL
,
4150 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4151 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4152 if (!NT_STATUS_IS_OK(status
)) {
4153 printf("[6] open of %s failed (%s)\n", fname
,
4159 /* This should fail - only allowed on NT opens with DELETE access. */
4161 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4162 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4167 status
= cli_close(cli1
, fnum1
);
4168 if (!NT_STATUS_IS_OK(status
)) {
4169 printf("[6] close - 2 failed (%s)\n", nt_errstr(status
));
4174 printf("sixth delete on close test succeeded.\n");
4177 cli_setatr(cli1
, fname
, 0, 0);
4178 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4180 status
= cli_ntcreate(cli1
, fname
, 0,
4181 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4182 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4184 if (!NT_STATUS_IS_OK(status
)) {
4185 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4190 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4191 printf("[7] setting delete_on_close on file failed !\n");
4196 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
4197 printf("[7] unsetting delete_on_close on file failed !\n");
4202 status
= cli_close(cli1
, fnum1
);
4203 if (!NT_STATUS_IS_OK(status
)) {
4204 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4209 /* This next open should succeed - we reset the flag. */
4210 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4211 if (!NT_STATUS_IS_OK(status
)) {
4212 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4217 status
= cli_close(cli1
, fnum1
);
4218 if (!NT_STATUS_IS_OK(status
)) {
4219 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4224 printf("seventh delete on close test succeeded.\n");
4227 cli_setatr(cli1
, fname
, 0, 0);
4228 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4230 if (!torture_open_connection(&cli2
, 1)) {
4231 printf("[8] failed to open second connection.\n");
4236 cli_sockopt(cli1
, sockops
);
4238 status
= cli_ntcreate(cli1
, fname
, 0,
4239 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4240 FILE_ATTRIBUTE_NORMAL
,
4241 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4242 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4243 if (!NT_STATUS_IS_OK(status
)) {
4244 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4249 status
= cli_ntcreate(cli2
, fname
, 0,
4250 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4251 FILE_ATTRIBUTE_NORMAL
,
4252 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4253 FILE_OPEN
, 0, 0, &fnum2
);
4254 if (!NT_STATUS_IS_OK(status
)) {
4255 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4260 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4261 printf("[8] setting delete_on_close on file failed !\n");
4266 status
= cli_close(cli1
, fnum1
);
4267 if (!NT_STATUS_IS_OK(status
)) {
4268 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4273 status
= cli_close(cli2
, fnum2
);
4274 if (!NT_STATUS_IS_OK(status
)) {
4275 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4280 /* This should fail.. */
4281 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4282 if (NT_STATUS_IS_OK(status
)) {
4283 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4287 printf("eighth delete on close test succeeded.\n");
4289 /* This should fail - we need to set DELETE_ACCESS. */
4290 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
4291 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
4292 printf("[9] open of %s succeeded should have failed!\n", fname
);
4297 printf("ninth delete on close test succeeded.\n");
4299 status
= cli_ntcreate(cli1
, fname
, 0,
4300 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4301 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4302 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4304 if (!NT_STATUS_IS_OK(status
)) {
4305 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4310 /* This should delete the file. */
4311 status
= cli_close(cli1
, fnum1
);
4312 if (!NT_STATUS_IS_OK(status
)) {
4313 printf("[10] close failed (%s)\n", nt_errstr(status
));
4318 /* This should fail.. */
4319 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4320 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4324 printf("tenth delete on close test succeeded.\n");
4326 cli_setatr(cli1
, fname
, 0, 0);
4327 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4329 /* What error do we get when attempting to open a read-only file with
4332 /* Create a readonly file. */
4333 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4334 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4335 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4336 if (!NT_STATUS_IS_OK(status
)) {
4337 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4342 status
= cli_close(cli1
, fnum1
);
4343 if (!NT_STATUS_IS_OK(status
)) {
4344 printf("[11] close failed (%s)\n", nt_errstr(status
));
4349 /* Now try open for delete access. */
4350 status
= cli_ntcreate(cli1
, fname
, 0,
4351 FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4353 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4354 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4355 if (NT_STATUS_IS_OK(status
)) {
4356 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
4357 cli_close(cli1
, fnum1
);
4361 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
4362 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(status
));
4366 printf("eleventh delete on close test succeeded.\n");
4370 printf("finished delete test\n");
4373 /* FIXME: This will crash if we aborted before cli2 got
4374 * intialized, because these functions don't handle
4375 * uninitialized connections. */
4377 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4378 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4379 cli_setatr(cli1
, fname
, 0, 0);
4380 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4382 if (cli1
&& !torture_close_connection(cli1
)) {
4385 if (cli2
&& !torture_close_connection(cli2
)) {
4391 static bool run_deletetest_ln(int dummy
)
4393 struct cli_state
*cli
;
4394 const char *fname
= "\\delete1";
4395 const char *fname_ln
= "\\delete1_ln";
4399 bool correct
= true;
4402 printf("starting deletetest-ln\n");
4404 if (!torture_open_connection(&cli
, 0)) {
4408 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4409 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4411 cli_sockopt(cli
, sockops
);
4413 /* Create the file. */
4414 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4415 if (!NT_STATUS_IS_OK(status
)) {
4416 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4420 status
= cli_close(cli
, fnum
);
4421 if (!NT_STATUS_IS_OK(status
)) {
4422 printf("close1 failed (%s)\n", nt_errstr(status
));
4426 /* Now create a hardlink. */
4427 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4428 if (!NT_STATUS_IS_OK(status
)) {
4429 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4433 /* Open the original file. */
4434 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4435 FILE_ATTRIBUTE_NORMAL
,
4436 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4437 FILE_OPEN_IF
, 0, 0, &fnum
);
4438 if (!NT_STATUS_IS_OK(status
)) {
4439 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4443 /* Unlink the hard link path. */
4444 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4445 FILE_ATTRIBUTE_NORMAL
,
4446 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4447 FILE_OPEN_IF
, 0, 0, &fnum1
);
4448 if (!NT_STATUS_IS_OK(status
)) {
4449 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4452 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4453 if (!NT_STATUS_IS_OK(status
)) {
4454 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4455 __location__
, fname_ln
, nt_errstr(status
));
4459 status
= cli_close(cli
, fnum1
);
4460 if (!NT_STATUS_IS_OK(status
)) {
4461 printf("close %s failed (%s)\n",
4462 fname_ln
, nt_errstr(status
));
4466 status
= cli_close(cli
, fnum
);
4467 if (!NT_STATUS_IS_OK(status
)) {
4468 printf("close %s failed (%s)\n",
4469 fname
, nt_errstr(status
));
4473 /* Ensure the original file is still there. */
4474 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4475 if (!NT_STATUS_IS_OK(status
)) {
4476 printf("%s getatr on file %s failed (%s)\n",
4483 /* Ensure the link path is gone. */
4484 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4485 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4486 printf("%s, getatr for file %s returned wrong error code %s "
4487 "- should have been deleted\n",
4489 fname_ln
, nt_errstr(status
));
4493 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4494 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4496 if (!torture_close_connection(cli
)) {
4500 printf("finished deletetest-ln\n");
4506 print out server properties
4508 static bool run_properties(int dummy
)
4510 struct cli_state
*cli
;
4511 bool correct
= True
;
4513 printf("starting properties test\n");
4517 if (!torture_open_connection(&cli
, 0)) {
4521 cli_sockopt(cli
, sockops
);
4523 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli
));
4525 if (!torture_close_connection(cli
)) {
4534 /* FIRST_DESIRED_ACCESS 0xf019f */
4535 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4536 FILE_READ_EA| /* 0xf */ \
4537 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4538 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4539 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4540 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4541 /* SECOND_DESIRED_ACCESS 0xe0080 */
4542 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4543 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4544 WRITE_OWNER_ACCESS /* 0xe0000 */
4547 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4548 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4550 WRITE_OWNER_ACCESS /* */
4554 Test ntcreate calls made by xcopy
4556 static bool run_xcopy(int dummy
)
4558 static struct cli_state
*cli1
;
4559 const char *fname
= "\\test.txt";
4560 bool correct
= True
;
4561 uint16_t fnum1
, fnum2
;
4564 printf("starting xcopy test\n");
4566 if (!torture_open_connection(&cli1
, 0)) {
4570 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4571 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4572 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
);
4573 if (!NT_STATUS_IS_OK(status
)) {
4574 printf("First open failed - %s\n", nt_errstr(status
));
4578 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4579 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4580 FILE_OPEN
, 0x200000, 0, &fnum2
);
4581 if (!NT_STATUS_IS_OK(status
)) {
4582 printf("second open failed - %s\n", nt_errstr(status
));
4586 if (!torture_close_connection(cli1
)) {
4594 Test rename on files open with share delete and no share delete.
4596 static bool run_rename(int dummy
)
4598 static struct cli_state
*cli1
;
4599 const char *fname
= "\\test.txt";
4600 const char *fname1
= "\\test1.txt";
4601 bool correct
= True
;
4606 printf("starting rename test\n");
4608 if (!torture_open_connection(&cli1
, 0)) {
4612 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4613 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4615 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4616 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4617 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4618 if (!NT_STATUS_IS_OK(status
)) {
4619 printf("First open failed - %s\n", nt_errstr(status
));
4623 status
= cli_rename(cli1
, fname
, fname1
);
4624 if (!NT_STATUS_IS_OK(status
)) {
4625 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4627 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4631 status
= cli_close(cli1
, fnum1
);
4632 if (!NT_STATUS_IS_OK(status
)) {
4633 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4637 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4638 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4639 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4641 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4643 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4645 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4646 if (!NT_STATUS_IS_OK(status
)) {
4647 printf("Second open failed - %s\n", nt_errstr(status
));
4651 status
= cli_rename(cli1
, fname
, fname1
);
4652 if (!NT_STATUS_IS_OK(status
)) {
4653 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4656 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4659 status
= cli_close(cli1
, fnum1
);
4660 if (!NT_STATUS_IS_OK(status
)) {
4661 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4665 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4666 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4668 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4669 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4670 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4671 if (!NT_STATUS_IS_OK(status
)) {
4672 printf("Third open failed - %s\n", nt_errstr(status
));
4681 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4682 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4683 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4686 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4687 printf("[8] setting delete_on_close on file failed !\n");
4691 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4692 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4698 status
= cli_rename(cli1
, fname
, fname1
);
4699 if (!NT_STATUS_IS_OK(status
)) {
4700 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4703 printf("Third rename succeeded (SHARE_NONE)\n");
4706 status
= cli_close(cli1
, fnum1
);
4707 if (!NT_STATUS_IS_OK(status
)) {
4708 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4712 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4713 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4717 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4718 FILE_ATTRIBUTE_NORMAL
,
4719 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4720 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4721 if (!NT_STATUS_IS_OK(status
)) {
4722 printf("Fourth open failed - %s\n", nt_errstr(status
));
4726 status
= cli_rename(cli1
, fname
, fname1
);
4727 if (!NT_STATUS_IS_OK(status
)) {
4728 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4730 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4734 status
= cli_close(cli1
, fnum1
);
4735 if (!NT_STATUS_IS_OK(status
)) {
4736 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4740 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4741 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4745 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4746 FILE_ATTRIBUTE_NORMAL
,
4747 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4748 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4749 if (!NT_STATUS_IS_OK(status
)) {
4750 printf("Fifth open failed - %s\n", nt_errstr(status
));
4754 status
= cli_rename(cli1
, fname
, fname1
);
4755 if (!NT_STATUS_IS_OK(status
)) {
4756 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4759 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4763 * Now check if the first name still exists ...
4766 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4767 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4768 printf("Opening original file after rename of open file fails: %s\n",
4772 printf("Opening original file after rename of open file works ...\n");
4773 (void)cli_close(cli1, fnum2);
4777 status
= cli_close(cli1
, fnum1
);
4778 if (!NT_STATUS_IS_OK(status
)) {
4779 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4783 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4784 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4785 if (!NT_STATUS_IS_OK(status
)) {
4786 printf("getatr on file %s failed - %s ! \n",
4787 fname1
, nt_errstr(status
));
4790 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4791 printf("Renamed file %s has wrong attr 0x%x "
4792 "(should be 0x%x)\n",
4795 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4798 printf("Renamed file %s has archive bit set\n", fname1
);
4802 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4803 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4805 if (!torture_close_connection(cli1
)) {
4812 static bool run_pipe_number(int dummy
)
4814 struct cli_state
*cli1
;
4815 const char *pipe_name
= "\\SPOOLSS";
4820 printf("starting pipenumber test\n");
4821 if (!torture_open_connection(&cli1
, 0)) {
4825 cli_sockopt(cli1
, sockops
);
4827 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4828 FILE_ATTRIBUTE_NORMAL
,
4829 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4830 FILE_OPEN_IF
, 0, 0, &fnum
);
4831 if (!NT_STATUS_IS_OK(status
)) {
4832 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4836 printf("\r%6d", num_pipes
);
4839 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4840 torture_close_connection(cli1
);
4845 Test open mode returns on read-only files.
4847 static bool run_opentest(int dummy
)
4849 static struct cli_state
*cli1
;
4850 static struct cli_state
*cli2
;
4851 const char *fname
= "\\readonly.file";
4852 uint16_t fnum1
, fnum2
;
4855 bool correct
= True
;
4859 printf("starting open test\n");
4861 if (!torture_open_connection(&cli1
, 0)) {
4865 cli_setatr(cli1
, fname
, 0, 0);
4866 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4868 cli_sockopt(cli1
, sockops
);
4870 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4871 if (!NT_STATUS_IS_OK(status
)) {
4872 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4876 status
= cli_close(cli1
, fnum1
);
4877 if (!NT_STATUS_IS_OK(status
)) {
4878 printf("close2 failed (%s)\n", nt_errstr(status
));
4882 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4883 if (!NT_STATUS_IS_OK(status
)) {
4884 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4888 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4889 if (!NT_STATUS_IS_OK(status
)) {
4890 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4894 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4895 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4897 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
4898 NT_STATUS_ACCESS_DENIED
)) {
4899 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4902 printf("finished open test 1\n");
4904 cli_close(cli1
, fnum1
);
4906 /* Now try not readonly and ensure ERRbadshare is returned. */
4908 cli_setatr(cli1
, fname
, 0, 0);
4910 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4911 if (!NT_STATUS_IS_OK(status
)) {
4912 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4916 /* This will fail - but the error should be ERRshare. */
4917 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4919 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
4920 NT_STATUS_SHARING_VIOLATION
)) {
4921 printf("correct error code ERRDOS/ERRbadshare returned\n");
4924 status
= cli_close(cli1
, fnum1
);
4925 if (!NT_STATUS_IS_OK(status
)) {
4926 printf("close2 failed (%s)\n", nt_errstr(status
));
4930 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4932 printf("finished open test 2\n");
4934 /* Test truncate open disposition on file opened for read. */
4935 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4936 if (!NT_STATUS_IS_OK(status
)) {
4937 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
4941 /* write 20 bytes. */
4943 memset(buf
, '\0', 20);
4945 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4946 if (!NT_STATUS_IS_OK(status
)) {
4947 printf("write failed (%s)\n", nt_errstr(status
));
4951 status
= cli_close(cli1
, fnum1
);
4952 if (!NT_STATUS_IS_OK(status
)) {
4953 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
4957 /* Ensure size == 20. */
4958 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4959 if (!NT_STATUS_IS_OK(status
)) {
4960 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4965 printf("(3) file size != 20\n");
4969 /* Now test if we can truncate a file opened for readonly. */
4970 status
= cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
4971 if (!NT_STATUS_IS_OK(status
)) {
4972 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
4976 status
= cli_close(cli1
, fnum1
);
4977 if (!NT_STATUS_IS_OK(status
)) {
4978 printf("close2 failed (%s)\n", nt_errstr(status
));
4982 /* Ensure size == 0. */
4983 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4984 if (!NT_STATUS_IS_OK(status
)) {
4985 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4990 printf("(3) file size != 0\n");
4993 printf("finished open test 3\n");
4995 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4997 printf("Do ctemp tests\n");
4998 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
4999 if (!NT_STATUS_IS_OK(status
)) {
5000 printf("ctemp failed (%s)\n", nt_errstr(status
));
5004 printf("ctemp gave path %s\n", tmp_path
);
5005 status
= cli_close(cli1
, fnum1
);
5006 if (!NT_STATUS_IS_OK(status
)) {
5007 printf("close of temp failed (%s)\n", nt_errstr(status
));
5010 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5011 if (!NT_STATUS_IS_OK(status
)) {
5012 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5015 /* Test the non-io opens... */
5017 if (!torture_open_connection(&cli2
, 1)) {
5021 cli_setatr(cli2
, fname
, 0, 0);
5022 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5024 cli_sockopt(cli2
, sockops
);
5026 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5027 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5028 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5029 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5030 if (!NT_STATUS_IS_OK(status
)) {
5031 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5035 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5036 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5037 FILE_OPEN_IF
, 0, 0, &fnum2
);
5038 if (!NT_STATUS_IS_OK(status
)) {
5039 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5043 status
= cli_close(cli1
, fnum1
);
5044 if (!NT_STATUS_IS_OK(status
)) {
5045 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5049 status
= cli_close(cli2
, fnum2
);
5050 if (!NT_STATUS_IS_OK(status
)) {
5051 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5055 printf("non-io open test #1 passed.\n");
5057 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5059 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5061 status
= cli_ntcreate(cli1
, fname
, 0,
5062 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5063 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5064 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5065 if (!NT_STATUS_IS_OK(status
)) {
5066 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5070 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5071 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5072 FILE_OPEN_IF
, 0, 0, &fnum2
);
5073 if (!NT_STATUS_IS_OK(status
)) {
5074 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5078 status
= cli_close(cli1
, fnum1
);
5079 if (!NT_STATUS_IS_OK(status
)) {
5080 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5084 status
= cli_close(cli2
, fnum2
);
5085 if (!NT_STATUS_IS_OK(status
)) {
5086 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5090 printf("non-io open test #2 passed.\n");
5092 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5094 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5096 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5097 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5098 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5099 if (!NT_STATUS_IS_OK(status
)) {
5100 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5104 status
= cli_ntcreate(cli2
, fname
, 0,
5105 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5106 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5107 FILE_OPEN_IF
, 0, 0, &fnum2
);
5108 if (!NT_STATUS_IS_OK(status
)) {
5109 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5113 status
= cli_close(cli1
, fnum1
);
5114 if (!NT_STATUS_IS_OK(status
)) {
5115 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5119 status
= cli_close(cli2
, fnum2
);
5120 if (!NT_STATUS_IS_OK(status
)) {
5121 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5125 printf("non-io open test #3 passed.\n");
5127 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5129 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5131 status
= cli_ntcreate(cli1
, fname
, 0,
5132 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5133 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5134 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5135 if (!NT_STATUS_IS_OK(status
)) {
5136 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5140 status
= cli_ntcreate(cli2
, fname
, 0,
5141 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5142 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5143 FILE_OPEN_IF
, 0, 0, &fnum2
);
5144 if (NT_STATUS_IS_OK(status
)) {
5145 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5149 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5151 status
= cli_close(cli1
, fnum1
);
5152 if (!NT_STATUS_IS_OK(status
)) {
5153 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5157 printf("non-io open test #4 passed.\n");
5159 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5161 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5163 status
= cli_ntcreate(cli1
, fname
, 0,
5164 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5165 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5166 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5167 if (!NT_STATUS_IS_OK(status
)) {
5168 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5172 status
= cli_ntcreate(cli2
, fname
, 0,
5173 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5174 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5175 FILE_OPEN_IF
, 0, 0, &fnum2
);
5176 if (!NT_STATUS_IS_OK(status
)) {
5177 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5181 status
= cli_close(cli1
, fnum1
);
5182 if (!NT_STATUS_IS_OK(status
)) {
5183 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5187 status
= cli_close(cli2
, fnum2
);
5188 if (!NT_STATUS_IS_OK(status
)) {
5189 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5193 printf("non-io open test #5 passed.\n");
5195 printf("TEST #6 testing 1 non-io open, one io open\n");
5197 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5199 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5200 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5201 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5202 if (!NT_STATUS_IS_OK(status
)) {
5203 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5207 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5208 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5209 FILE_OPEN_IF
, 0, 0, &fnum2
);
5210 if (!NT_STATUS_IS_OK(status
)) {
5211 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5215 status
= cli_close(cli1
, fnum1
);
5216 if (!NT_STATUS_IS_OK(status
)) {
5217 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5221 status
= cli_close(cli2
, fnum2
);
5222 if (!NT_STATUS_IS_OK(status
)) {
5223 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5227 printf("non-io open test #6 passed.\n");
5229 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5231 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5233 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5234 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5235 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5236 if (!NT_STATUS_IS_OK(status
)) {
5237 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5241 status
= cli_ntcreate(cli2
, fname
, 0,
5242 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5243 FILE_ATTRIBUTE_NORMAL
,
5244 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5245 FILE_OPEN_IF
, 0, 0, &fnum2
);
5246 if (NT_STATUS_IS_OK(status
)) {
5247 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5251 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5253 status
= cli_close(cli1
, fnum1
);
5254 if (!NT_STATUS_IS_OK(status
)) {
5255 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5259 printf("non-io open test #7 passed.\n");
5261 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5263 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5264 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5265 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5266 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5267 if (!NT_STATUS_IS_OK(status
)) {
5268 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5273 /* Write to ensure we have to update the file time. */
5274 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5276 if (!NT_STATUS_IS_OK(status
)) {
5277 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5282 status
= cli_close(cli1
, fnum1
);
5283 if (!NT_STATUS_IS_OK(status
)) {
5284 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5290 if (!torture_close_connection(cli1
)) {
5293 if (!torture_close_connection(cli2
)) {
5300 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5302 uint16 major
, minor
;
5303 uint32 caplow
, caphigh
;
5306 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5307 printf("Server doesn't support UNIX CIFS extensions.\n");
5308 return NT_STATUS_NOT_SUPPORTED
;
5311 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5313 if (!NT_STATUS_IS_OK(status
)) {
5314 printf("Server didn't return UNIX CIFS extensions: %s\n",
5319 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5321 if (!NT_STATUS_IS_OK(status
)) {
5322 printf("Server doesn't support setting UNIX CIFS extensions: "
5323 "%s.\n", nt_errstr(status
));
5327 return NT_STATUS_OK
;
5331 Test POSIX open /mkdir calls.
5333 static bool run_simple_posix_open_test(int dummy
)
5335 static struct cli_state
*cli1
;
5336 const char *fname
= "posix:file";
5337 const char *hname
= "posix:hlink";
5338 const char *sname
= "posix:symlink";
5339 const char *dname
= "posix:dir";
5342 uint16_t fnum1
= (uint16_t)-1;
5343 SMB_STRUCT_STAT sbuf
;
5344 bool correct
= false;
5348 printf("Starting simple POSIX open test\n");
5350 if (!torture_open_connection(&cli1
, 0)) {
5354 cli_sockopt(cli1
, sockops
);
5356 status
= torture_setup_unix_extensions(cli1
);
5357 if (!NT_STATUS_IS_OK(status
)) {
5361 cli_setatr(cli1
, fname
, 0, 0);
5362 cli_posix_unlink(cli1
, fname
);
5363 cli_setatr(cli1
, dname
, 0, 0);
5364 cli_posix_rmdir(cli1
, dname
);
5365 cli_setatr(cli1
, hname
, 0, 0);
5366 cli_posix_unlink(cli1
, hname
);
5367 cli_setatr(cli1
, sname
, 0, 0);
5368 cli_posix_unlink(cli1
, sname
);
5370 /* Create a directory. */
5371 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5372 if (!NT_STATUS_IS_OK(status
)) {
5373 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5377 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5379 if (!NT_STATUS_IS_OK(status
)) {
5380 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5384 /* Test ftruncate - set file size. */
5385 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5386 if (!NT_STATUS_IS_OK(status
)) {
5387 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5391 /* Ensure st_size == 1000 */
5392 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5393 if (!NT_STATUS_IS_OK(status
)) {
5394 printf("stat failed (%s)\n", nt_errstr(status
));
5398 if (sbuf
.st_ex_size
!= 1000) {
5399 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5403 /* Test ftruncate - set file size back to zero. */
5404 status
= cli_ftruncate(cli1
, fnum1
, 0);
5405 if (!NT_STATUS_IS_OK(status
)) {
5406 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5410 status
= cli_close(cli1
, fnum1
);
5411 if (!NT_STATUS_IS_OK(status
)) {
5412 printf("close failed (%s)\n", nt_errstr(status
));
5416 /* Now open the file again for read only. */
5417 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5418 if (!NT_STATUS_IS_OK(status
)) {
5419 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5423 /* Now unlink while open. */
5424 status
= cli_posix_unlink(cli1
, fname
);
5425 if (!NT_STATUS_IS_OK(status
)) {
5426 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5430 status
= cli_close(cli1
, fnum1
);
5431 if (!NT_STATUS_IS_OK(status
)) {
5432 printf("close(2) failed (%s)\n", nt_errstr(status
));
5436 /* Ensure the file has gone. */
5437 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5438 if (NT_STATUS_IS_OK(status
)) {
5439 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5443 /* Create again to test open with O_TRUNC. */
5444 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5445 if (!NT_STATUS_IS_OK(status
)) {
5446 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5450 /* Test ftruncate - set file size. */
5451 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5452 if (!NT_STATUS_IS_OK(status
)) {
5453 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5457 /* Ensure st_size == 1000 */
5458 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5459 if (!NT_STATUS_IS_OK(status
)) {
5460 printf("stat failed (%s)\n", nt_errstr(status
));
5464 if (sbuf
.st_ex_size
!= 1000) {
5465 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5469 status
= cli_close(cli1
, fnum1
);
5470 if (!NT_STATUS_IS_OK(status
)) {
5471 printf("close(2) failed (%s)\n", nt_errstr(status
));
5475 /* Re-open with O_TRUNC. */
5476 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5477 if (!NT_STATUS_IS_OK(status
)) {
5478 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5482 /* Ensure st_size == 0 */
5483 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5484 if (!NT_STATUS_IS_OK(status
)) {
5485 printf("stat failed (%s)\n", nt_errstr(status
));
5489 if (sbuf
.st_ex_size
!= 0) {
5490 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5494 status
= cli_close(cli1
, fnum1
);
5495 if (!NT_STATUS_IS_OK(status
)) {
5496 printf("close failed (%s)\n", nt_errstr(status
));
5500 status
= cli_posix_unlink(cli1
, fname
);
5501 if (!NT_STATUS_IS_OK(status
)) {
5502 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5506 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5507 if (!NT_STATUS_IS_OK(status
)) {
5508 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5509 dname
, nt_errstr(status
));
5513 cli_close(cli1
, fnum1
);
5515 /* What happens when we try and POSIX open a directory for write ? */
5516 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5517 if (NT_STATUS_IS_OK(status
)) {
5518 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5521 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5522 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5527 /* Create the file. */
5528 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5530 if (!NT_STATUS_IS_OK(status
)) {
5531 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5535 /* Write some data into it. */
5536 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5538 if (!NT_STATUS_IS_OK(status
)) {
5539 printf("cli_write failed: %s\n", nt_errstr(status
));
5543 cli_close(cli1
, fnum1
);
5545 /* Now create a hardlink. */
5546 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5547 if (!NT_STATUS_IS_OK(status
)) {
5548 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5552 /* Now create a symlink. */
5553 status
= cli_posix_symlink(cli1
, fname
, sname
);
5554 if (!NT_STATUS_IS_OK(status
)) {
5555 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5559 /* Open the hardlink for read. */
5560 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5561 if (!NT_STATUS_IS_OK(status
)) {
5562 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5566 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5567 if (!NT_STATUS_IS_OK(status
)) {
5568 printf("POSIX read of %s failed (%s)\n", hname
,
5571 } else if (nread
!= 10) {
5572 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5573 hname
, (unsigned long)nread
, 10);
5577 if (memcmp(buf
, "TEST DATA\n", 10)) {
5578 printf("invalid data read from hardlink\n");
5582 /* Do a POSIX lock/unlock. */
5583 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5584 if (!NT_STATUS_IS_OK(status
)) {
5585 printf("POSIX lock failed %s\n", nt_errstr(status
));
5589 /* Punch a hole in the locked area. */
5590 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5591 if (!NT_STATUS_IS_OK(status
)) {
5592 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5596 cli_close(cli1
, fnum1
);
5598 /* Open the symlink for read - this should fail. A POSIX
5599 client should not be doing opens on a symlink. */
5600 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5601 if (NT_STATUS_IS_OK(status
)) {
5602 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5605 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5606 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5607 printf("POSIX open of %s should have failed "
5608 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5609 "failed with %s instead.\n",
5610 sname
, nt_errstr(status
));
5615 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5616 if (!NT_STATUS_IS_OK(status
)) {
5617 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5621 if (strcmp(namebuf
, fname
) != 0) {
5622 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5623 sname
, fname
, namebuf
);
5627 status
= cli_posix_rmdir(cli1
, dname
);
5628 if (!NT_STATUS_IS_OK(status
)) {
5629 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5633 printf("Simple POSIX open test passed\n");
5638 if (fnum1
!= (uint16_t)-1) {
5639 cli_close(cli1
, fnum1
);
5640 fnum1
= (uint16_t)-1;
5643 cli_setatr(cli1
, sname
, 0, 0);
5644 cli_posix_unlink(cli1
, sname
);
5645 cli_setatr(cli1
, hname
, 0, 0);
5646 cli_posix_unlink(cli1
, hname
);
5647 cli_setatr(cli1
, fname
, 0, 0);
5648 cli_posix_unlink(cli1
, fname
);
5649 cli_setatr(cli1
, dname
, 0, 0);
5650 cli_posix_rmdir(cli1
, dname
);
5652 if (!torture_close_connection(cli1
)) {
5660 static uint32 open_attrs_table
[] = {
5661 FILE_ATTRIBUTE_NORMAL
,
5662 FILE_ATTRIBUTE_ARCHIVE
,
5663 FILE_ATTRIBUTE_READONLY
,
5664 FILE_ATTRIBUTE_HIDDEN
,
5665 FILE_ATTRIBUTE_SYSTEM
,
5667 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5668 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5669 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5670 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5671 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5672 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5674 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5675 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5676 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5677 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5680 struct trunc_open_results
{
5687 static struct trunc_open_results attr_results
[] = {
5688 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5689 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5690 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5691 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5692 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5693 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5694 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5695 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5696 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5697 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5698 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5699 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5700 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5701 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5702 { 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
},
5703 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5704 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5705 { 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
},
5706 { 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
},
5707 { 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
},
5708 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5709 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5710 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5711 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5712 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5713 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5716 static bool run_openattrtest(int dummy
)
5718 static struct cli_state
*cli1
;
5719 const char *fname
= "\\openattr.file";
5721 bool correct
= True
;
5723 unsigned int i
, j
, k
, l
;
5726 printf("starting open attr test\n");
5728 if (!torture_open_connection(&cli1
, 0)) {
5732 cli_sockopt(cli1
, sockops
);
5734 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5735 cli_setatr(cli1
, fname
, 0, 0);
5736 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5738 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5739 open_attrs_table
[i
], FILE_SHARE_NONE
,
5740 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5741 if (!NT_STATUS_IS_OK(status
)) {
5742 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5746 status
= cli_close(cli1
, fnum1
);
5747 if (!NT_STATUS_IS_OK(status
)) {
5748 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5752 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5753 status
= cli_ntcreate(cli1
, fname
, 0,
5754 FILE_READ_DATA
|FILE_WRITE_DATA
,
5755 open_attrs_table
[j
],
5756 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5758 if (!NT_STATUS_IS_OK(status
)) {
5759 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5760 if (attr_results
[l
].num
== k
) {
5761 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5762 k
, open_attrs_table
[i
],
5763 open_attrs_table
[j
],
5764 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5769 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5770 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5771 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5776 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5782 status
= cli_close(cli1
, fnum1
);
5783 if (!NT_STATUS_IS_OK(status
)) {
5784 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5788 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5789 if (!NT_STATUS_IS_OK(status
)) {
5790 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5795 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5796 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5799 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5800 if (attr_results
[l
].num
== k
) {
5801 if (attr
!= attr_results
[l
].result_attr
||
5802 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5803 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5804 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5805 open_attrs_table
[i
],
5806 open_attrs_table
[j
],
5808 attr_results
[l
].result_attr
);
5818 cli_setatr(cli1
, fname
, 0, 0);
5819 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5821 printf("open attr test %s.\n", correct
? "passed" : "failed");
5823 if (!torture_close_connection(cli1
)) {
5829 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5830 const char *name
, void *state
)
5832 int *matched
= (int *)state
;
5833 if (matched
!= NULL
) {
5836 return NT_STATUS_OK
;
5840 test directory listing speed
5842 static bool run_dirtest(int dummy
)
5845 static struct cli_state
*cli
;
5847 struct timeval core_start
;
5848 bool correct
= True
;
5851 printf("starting directory test\n");
5853 if (!torture_open_connection(&cli
, 0)) {
5857 cli_sockopt(cli
, sockops
);
5860 for (i
=0;i
<torture_numops
;i
++) {
5862 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5863 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5864 fprintf(stderr
,"Failed to open %s\n", fname
);
5867 cli_close(cli
, fnum
);
5870 core_start
= timeval_current();
5873 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5874 printf("Matched %d\n", matched
);
5877 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5878 printf("Matched %d\n", matched
);
5881 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5882 printf("Matched %d\n", matched
);
5884 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5887 for (i
=0;i
<torture_numops
;i
++) {
5889 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5890 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5893 if (!torture_close_connection(cli
)) {
5897 printf("finished dirtest\n");
5902 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5905 struct cli_state
*pcli
= (struct cli_state
*)state
;
5907 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5909 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5910 return NT_STATUS_OK
;
5912 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
5913 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5914 printf("del_fn: failed to rmdir %s\n,", fname
);
5916 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
5917 printf("del_fn: failed to unlink %s\n,", fname
);
5919 return NT_STATUS_OK
;
5924 sees what IOCTLs are supported
5926 bool torture_ioctl_test(int dummy
)
5928 static struct cli_state
*cli
;
5929 uint16_t device
, function
;
5931 const char *fname
= "\\ioctl.dat";
5935 if (!torture_open_connection(&cli
, 0)) {
5939 printf("starting ioctl test\n");
5941 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5943 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5944 if (!NT_STATUS_IS_OK(status
)) {
5945 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5949 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5950 printf("ioctl device info: %s\n", nt_errstr(status
));
5952 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5953 printf("ioctl job info: %s\n", nt_errstr(status
));
5955 for (device
=0;device
<0x100;device
++) {
5956 printf("ioctl test with device = 0x%x\n", device
);
5957 for (function
=0;function
<0x100;function
++) {
5958 uint32 code
= (device
<<16) | function
;
5960 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5962 if (NT_STATUS_IS_OK(status
)) {
5963 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5965 data_blob_free(&blob
);
5970 if (!torture_close_connection(cli
)) {
5979 tries varients of chkpath
5981 bool torture_chkpath_test(int dummy
)
5983 static struct cli_state
*cli
;
5988 if (!torture_open_connection(&cli
, 0)) {
5992 printf("starting chkpath test\n");
5994 /* cleanup from an old run */
5995 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5996 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5997 cli_rmdir(cli
, "\\chkpath.dir");
5999 status
= cli_mkdir(cli
, "\\chkpath.dir");
6000 if (!NT_STATUS_IS_OK(status
)) {
6001 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6005 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6006 if (!NT_STATUS_IS_OK(status
)) {
6007 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6011 status
= cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6013 if (!NT_STATUS_IS_OK(status
)) {
6014 printf("open1 failed (%s)\n", nt_errstr(status
));
6017 cli_close(cli
, fnum
);
6019 status
= cli_chkpath(cli
, "\\chkpath.dir");
6020 if (!NT_STATUS_IS_OK(status
)) {
6021 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6025 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6026 if (!NT_STATUS_IS_OK(status
)) {
6027 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6031 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6032 if (!NT_STATUS_IS_OK(status
)) {
6033 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6034 NT_STATUS_NOT_A_DIRECTORY
);
6036 printf("* chkpath on a file should fail\n");
6040 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6041 if (!NT_STATUS_IS_OK(status
)) {
6042 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6043 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6045 printf("* chkpath on a non existant file should fail\n");
6049 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6050 if (!NT_STATUS_IS_OK(status
)) {
6051 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6052 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6054 printf("* chkpath on a non existent component should fail\n");
6058 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6059 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6060 cli_rmdir(cli
, "\\chkpath.dir");
6062 if (!torture_close_connection(cli
)) {
6069 static bool run_eatest(int dummy
)
6071 static struct cli_state
*cli
;
6072 const char *fname
= "\\eatest.txt";
6073 bool correct
= True
;
6077 struct ea_struct
*ea_list
= NULL
;
6078 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6081 printf("starting eatest\n");
6083 if (!torture_open_connection(&cli
, 0)) {
6084 talloc_destroy(mem_ctx
);
6088 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6090 status
= cli_ntcreate(cli
, fname
, 0,
6091 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6092 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6094 if (!NT_STATUS_IS_OK(status
)) {
6095 printf("open failed - %s\n", nt_errstr(status
));
6096 talloc_destroy(mem_ctx
);
6100 for (i
= 0; i
< 10; i
++) {
6101 fstring ea_name
, ea_val
;
6103 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6104 memset(ea_val
, (char)i
+1, i
+1);
6105 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6106 if (!NT_STATUS_IS_OK(status
)) {
6107 printf("ea_set of name %s failed - %s\n", ea_name
,
6109 talloc_destroy(mem_ctx
);
6114 cli_close(cli
, fnum
);
6115 for (i
= 0; i
< 10; i
++) {
6116 fstring ea_name
, ea_val
;
6118 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6119 memset(ea_val
, (char)i
+1, i
+1);
6120 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6121 if (!NT_STATUS_IS_OK(status
)) {
6122 printf("ea_set of name %s failed - %s\n", ea_name
,
6124 talloc_destroy(mem_ctx
);
6129 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6130 if (!NT_STATUS_IS_OK(status
)) {
6131 printf("ea_get list failed - %s\n", nt_errstr(status
));
6135 printf("num_eas = %d\n", (int)num_eas
);
6137 if (num_eas
!= 20) {
6138 printf("Should be 20 EA's stored... failing.\n");
6142 for (i
= 0; i
< num_eas
; i
++) {
6143 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6144 dump_data(0, ea_list
[i
].value
.data
,
6145 ea_list
[i
].value
.length
);
6148 /* Setting EA's to zero length deletes them. Test this */
6149 printf("Now deleting all EA's - case indepenent....\n");
6152 cli_set_ea_path(cli
, fname
, "", "", 0);
6154 for (i
= 0; i
< 20; i
++) {
6156 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6157 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6158 if (!NT_STATUS_IS_OK(status
)) {
6159 printf("ea_set of name %s failed - %s\n", ea_name
,
6161 talloc_destroy(mem_ctx
);
6167 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6168 if (!NT_STATUS_IS_OK(status
)) {
6169 printf("ea_get list failed - %s\n", nt_errstr(status
));
6173 printf("num_eas = %d\n", (int)num_eas
);
6174 for (i
= 0; i
< num_eas
; i
++) {
6175 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6176 dump_data(0, ea_list
[i
].value
.data
,
6177 ea_list
[i
].value
.length
);
6181 printf("deleting EA's failed.\n");
6185 /* Try and delete a non existant EA. */
6186 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6187 if (!NT_STATUS_IS_OK(status
)) {
6188 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6193 talloc_destroy(mem_ctx
);
6194 if (!torture_close_connection(cli
)) {
6201 static bool run_dirtest1(int dummy
)
6204 static struct cli_state
*cli
;
6207 bool correct
= True
;
6209 printf("starting directory test\n");
6211 if (!torture_open_connection(&cli
, 0)) {
6215 cli_sockopt(cli
, sockops
);
6217 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6218 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6219 cli_rmdir(cli
, "\\LISTDIR");
6220 cli_mkdir(cli
, "\\LISTDIR");
6222 /* Create 1000 files and 1000 directories. */
6223 for (i
=0;i
<1000;i
++) {
6225 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6226 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6227 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6228 fprintf(stderr
,"Failed to open %s\n", fname
);
6231 cli_close(cli
, fnum
);
6233 for (i
=0;i
<1000;i
++) {
6235 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6236 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6237 fprintf(stderr
,"Failed to open %s\n", fname
);
6242 /* Now ensure that doing an old list sees both files and directories. */
6244 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6245 printf("num_seen = %d\n", num_seen
);
6246 /* We should see 100 files + 1000 directories + . and .. */
6247 if (num_seen
!= 2002)
6250 /* Ensure if we have the "must have" bits we only see the
6254 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6255 printf("num_seen = %d\n", num_seen
);
6256 if (num_seen
!= 1002)
6260 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6261 printf("num_seen = %d\n", num_seen
);
6262 if (num_seen
!= 1000)
6265 /* Delete everything. */
6266 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6267 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6268 cli_rmdir(cli
, "\\LISTDIR");
6271 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6272 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6273 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6276 if (!torture_close_connection(cli
)) {
6280 printf("finished dirtest1\n");
6285 static bool run_error_map_extract(int dummy
) {
6287 static struct cli_state
*c_dos
;
6288 static struct cli_state
*c_nt
;
6300 /* NT-Error connection */
6302 disable_spnego
= true;
6303 if (!(c_nt
= open_nbt_connection())) {
6304 disable_spnego
= false;
6307 disable_spnego
= false;
6309 status
= cli_negprot(c_nt
, PROTOCOL_NT1
);
6311 if (!NT_STATUS_IS_OK(status
)) {
6312 printf("%s rejected the NT-error negprot (%s)\n", host
,
6318 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6319 if (!NT_STATUS_IS_OK(status
)) {
6320 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6324 /* DOS-Error connection */
6326 disable_spnego
= true;
6327 force_dos_errors
= true;
6328 if (!(c_dos
= open_nbt_connection())) {
6329 disable_spnego
= false;
6330 force_dos_errors
= false;
6333 disable_spnego
= false;
6334 force_dos_errors
= false;
6336 status
= cli_negprot(c_dos
, PROTOCOL_NT1
);
6337 if (!NT_STATUS_IS_OK(status
)) {
6338 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6340 cli_shutdown(c_dos
);
6344 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6345 if (!NT_STATUS_IS_OK(status
)) {
6346 printf("%s rejected the DOS-error initial session setup (%s)\n",
6347 host
, nt_errstr(status
));
6351 c_nt
->map_dos_errors
= false;
6352 c_dos
->map_dos_errors
= false;
6354 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6355 fstr_sprintf(user
, "%X", error
);
6357 status
= cli_session_setup(c_nt
, user
,
6358 password
, strlen(password
),
6359 password
, strlen(password
),
6361 if (NT_STATUS_IS_OK(status
)) {
6362 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6365 /* Case #1: 32-bit NT errors */
6366 if (!NT_STATUS_IS_DOS(status
)) {
6369 printf("/** Dos error on NT connection! (%s) */\n",
6371 nt_status
= NT_STATUS(0xc0000000);
6374 status
= cli_session_setup(c_dos
, user
,
6375 password
, strlen(password
),
6376 password
, strlen(password
),
6378 if (NT_STATUS_IS_OK(status
)) {
6379 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6382 /* Case #1: 32-bit NT errors */
6383 if (NT_STATUS_IS_DOS(status
)) {
6384 printf("/** NT error on DOS connection! (%s) */\n",
6386 errnum
= errclass
= 0;
6388 errclass
= NT_STATUS_DOS_CLASS(status
);
6389 errnum
= NT_STATUS_DOS_CODE(status
);
6392 if (NT_STATUS_V(nt_status
) != error
) {
6393 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6394 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6395 get_nt_error_c_code(talloc_tos(), nt_status
));
6398 printf("\t{%s,\t%s,\t%s},\n",
6399 smb_dos_err_class(errclass
),
6400 smb_dos_err_name(errclass
, errnum
),
6401 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6406 static bool run_sesssetup_bench(int dummy
)
6408 static struct cli_state
*c
;
6409 const char *fname
= "\\file.dat";
6414 if (!torture_open_connection(&c
, 0)) {
6418 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6419 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6420 FILE_DELETE_ON_CLOSE
, 0, &fnum
);
6421 if (!NT_STATUS_IS_OK(status
)) {
6422 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6426 for (i
=0; i
<torture_numops
; i
++) {
6427 status
= cli_session_setup(
6429 password
, strlen(password
),
6430 password
, strlen(password
),
6432 if (!NT_STATUS_IS_OK(status
)) {
6433 d_printf("(%s) cli_session_setup failed: %s\n",
6434 __location__
, nt_errstr(status
));
6438 d_printf("\r%d ", (int)cli_state_get_uid(c
));
6440 status
= cli_ulogoff(c
);
6441 if (!NT_STATUS_IS_OK(status
)) {
6442 d_printf("(%s) cli_ulogoff failed: %s\n",
6443 __location__
, nt_errstr(status
));
6451 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6452 uid_t uid
, gid_t gid
, const char *expected
)
6457 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
6459 if (strcmp(subst
, expected
) != 0) {
6460 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6461 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6470 static void chain1_open_completion(struct tevent_req
*req
)
6474 status
= cli_open_recv(req
, &fnum
);
6477 d_printf("cli_open_recv returned %s: %d\n",
6479 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6482 static void chain1_write_completion(struct tevent_req
*req
)
6486 status
= cli_write_andx_recv(req
, &written
);
6489 d_printf("cli_write_andx_recv returned %s: %d\n",
6491 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6494 static void chain1_close_completion(struct tevent_req
*req
)
6497 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6499 status
= cli_close_recv(req
);
6504 d_printf("cli_close returned %s\n", nt_errstr(status
));
6507 static bool run_chain1(int dummy
)
6509 struct cli_state
*cli1
;
6510 struct event_context
*evt
= event_context_init(NULL
);
6511 struct tevent_req
*reqs
[3], *smbreqs
[3];
6513 const char *str
= "foobar";
6516 printf("starting chain1 test\n");
6517 if (!torture_open_connection(&cli1
, 0)) {
6521 cli_sockopt(cli1
, sockops
);
6523 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
6524 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6525 if (reqs
[0] == NULL
) return false;
6526 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6529 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6530 (const uint8_t *)str
, 0, strlen(str
)+1,
6531 smbreqs
, 1, &smbreqs
[1]);
6532 if (reqs
[1] == NULL
) return false;
6533 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6535 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6536 if (reqs
[2] == NULL
) return false;
6537 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6539 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6540 if (!NT_STATUS_IS_OK(status
)) {
6545 tevent_loop_once(evt
);
6548 torture_close_connection(cli1
);
6552 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6555 status
= cli_session_setup_guest_recv(req
);
6556 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6559 static void chain2_tcon_completion(struct tevent_req
*req
)
6561 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6563 status
= cli_tcon_andx_recv(req
);
6564 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6568 static bool run_chain2(int dummy
)
6570 struct cli_state
*cli1
;
6571 struct event_context
*evt
= event_context_init(NULL
);
6572 struct tevent_req
*reqs
[2], *smbreqs
[2];
6576 printf("starting chain2 test\n");
6577 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6578 port_to_use
, SMB_SIGNING_DEFAULT
, 0);
6579 if (!NT_STATUS_IS_OK(status
)) {
6583 cli_sockopt(cli1
, sockops
);
6585 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6587 if (reqs
[0] == NULL
) return false;
6588 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6590 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6591 "?????", NULL
, 0, &smbreqs
[1]);
6592 if (reqs
[1] == NULL
) return false;
6593 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6595 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6596 if (!NT_STATUS_IS_OK(status
)) {
6601 tevent_loop_once(evt
);
6604 torture_close_connection(cli1
);
6609 struct torture_createdel_state
{
6610 struct tevent_context
*ev
;
6611 struct cli_state
*cli
;
6614 static void torture_createdel_created(struct tevent_req
*subreq
);
6615 static void torture_createdel_closed(struct tevent_req
*subreq
);
6617 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6618 struct tevent_context
*ev
,
6619 struct cli_state
*cli
,
6622 struct tevent_req
*req
, *subreq
;
6623 struct torture_createdel_state
*state
;
6625 req
= tevent_req_create(mem_ctx
, &state
,
6626 struct torture_createdel_state
);
6633 subreq
= cli_ntcreate_send(
6634 state
, ev
, cli
, name
, 0,
6635 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6636 FILE_ATTRIBUTE_NORMAL
,
6637 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6638 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6640 if (tevent_req_nomem(subreq
, req
)) {
6641 return tevent_req_post(req
, ev
);
6643 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6647 static void torture_createdel_created(struct tevent_req
*subreq
)
6649 struct tevent_req
*req
= tevent_req_callback_data(
6650 subreq
, struct tevent_req
);
6651 struct torture_createdel_state
*state
= tevent_req_data(
6652 req
, struct torture_createdel_state
);
6656 status
= cli_ntcreate_recv(subreq
, &fnum
);
6657 TALLOC_FREE(subreq
);
6658 if (!NT_STATUS_IS_OK(status
)) {
6659 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6660 nt_errstr(status
)));
6661 tevent_req_nterror(req
, status
);
6665 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6666 if (tevent_req_nomem(subreq
, req
)) {
6669 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6672 static void torture_createdel_closed(struct tevent_req
*subreq
)
6674 struct tevent_req
*req
= tevent_req_callback_data(
6675 subreq
, struct tevent_req
);
6678 status
= cli_close_recv(subreq
);
6679 if (!NT_STATUS_IS_OK(status
)) {
6680 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6681 tevent_req_nterror(req
, status
);
6684 tevent_req_done(req
);
6687 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6689 return tevent_req_simple_recv_ntstatus(req
);
6692 struct torture_createdels_state
{
6693 struct tevent_context
*ev
;
6694 struct cli_state
*cli
;
6695 const char *base_name
;
6699 struct tevent_req
**reqs
;
6702 static void torture_createdels_done(struct tevent_req
*subreq
);
6704 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6705 struct tevent_context
*ev
,
6706 struct cli_state
*cli
,
6707 const char *base_name
,
6711 struct tevent_req
*req
;
6712 struct torture_createdels_state
*state
;
6715 req
= tevent_req_create(mem_ctx
, &state
,
6716 struct torture_createdels_state
);
6722 state
->base_name
= talloc_strdup(state
, base_name
);
6723 if (tevent_req_nomem(state
->base_name
, req
)) {
6724 return tevent_req_post(req
, ev
);
6726 state
->num_files
= MAX(num_parallel
, num_files
);
6728 state
->received
= 0;
6730 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6731 if (tevent_req_nomem(state
->reqs
, req
)) {
6732 return tevent_req_post(req
, ev
);
6735 for (i
=0; i
<num_parallel
; i
++) {
6738 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6740 if (tevent_req_nomem(name
, req
)) {
6741 return tevent_req_post(req
, ev
);
6743 state
->reqs
[i
] = torture_createdel_send(
6744 state
->reqs
, state
->ev
, state
->cli
, name
);
6745 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6746 return tevent_req_post(req
, ev
);
6748 name
= talloc_move(state
->reqs
[i
], &name
);
6749 tevent_req_set_callback(state
->reqs
[i
],
6750 torture_createdels_done
, req
);
6756 static void torture_createdels_done(struct tevent_req
*subreq
)
6758 struct tevent_req
*req
= tevent_req_callback_data(
6759 subreq
, struct tevent_req
);
6760 struct torture_createdels_state
*state
= tevent_req_data(
6761 req
, struct torture_createdels_state
);
6762 size_t num_parallel
= talloc_array_length(state
->reqs
);
6767 status
= torture_createdel_recv(subreq
);
6768 if (!NT_STATUS_IS_OK(status
)){
6769 DEBUG(10, ("torture_createdel_recv returned %s\n",
6770 nt_errstr(status
)));
6771 TALLOC_FREE(subreq
);
6772 tevent_req_nterror(req
, status
);
6776 for (i
=0; i
<num_parallel
; i
++) {
6777 if (subreq
== state
->reqs
[i
]) {
6781 if (i
== num_parallel
) {
6782 DEBUG(10, ("received something we did not send\n"));
6783 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6786 TALLOC_FREE(state
->reqs
[i
]);
6788 if (state
->sent
>= state
->num_files
) {
6789 tevent_req_done(req
);
6793 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6795 if (tevent_req_nomem(name
, req
)) {
6798 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6800 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6803 name
= talloc_move(state
->reqs
[i
], &name
);
6804 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6808 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6810 return tevent_req_simple_recv_ntstatus(req
);
6813 struct swallow_notify_state
{
6814 struct tevent_context
*ev
;
6815 struct cli_state
*cli
;
6817 uint32_t completion_filter
;
6819 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6823 static void swallow_notify_done(struct tevent_req
*subreq
);
6825 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6826 struct tevent_context
*ev
,
6827 struct cli_state
*cli
,
6829 uint32_t completion_filter
,
6831 bool (*fn
)(uint32_t action
,
6836 struct tevent_req
*req
, *subreq
;
6837 struct swallow_notify_state
*state
;
6839 req
= tevent_req_create(mem_ctx
, &state
,
6840 struct swallow_notify_state
);
6847 state
->completion_filter
= completion_filter
;
6848 state
->recursive
= recursive
;
6852 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6853 0xffff, state
->completion_filter
,
6855 if (tevent_req_nomem(subreq
, req
)) {
6856 return tevent_req_post(req
, ev
);
6858 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6862 static void swallow_notify_done(struct tevent_req
*subreq
)
6864 struct tevent_req
*req
= tevent_req_callback_data(
6865 subreq
, struct tevent_req
);
6866 struct swallow_notify_state
*state
= tevent_req_data(
6867 req
, struct swallow_notify_state
);
6869 uint32_t i
, num_changes
;
6870 struct notify_change
*changes
;
6872 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6873 TALLOC_FREE(subreq
);
6874 if (!NT_STATUS_IS_OK(status
)) {
6875 DEBUG(10, ("cli_notify_recv returned %s\n",
6876 nt_errstr(status
)));
6877 tevent_req_nterror(req
, status
);
6881 for (i
=0; i
<num_changes
; i
++) {
6882 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6884 TALLOC_FREE(changes
);
6886 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6887 0xffff, state
->completion_filter
,
6889 if (tevent_req_nomem(subreq
, req
)) {
6892 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6895 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6897 if (DEBUGLEVEL
> 5) {
6898 d_printf("%d %s\n", (int)action
, name
);
6903 static void notify_bench_done(struct tevent_req
*req
)
6905 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6909 static bool run_notify_bench(int dummy
)
6911 const char *dname
= "\\notify-bench";
6912 struct tevent_context
*ev
;
6915 struct tevent_req
*req1
;
6916 struct tevent_req
*req2
= NULL
;
6917 int i
, num_unc_names
;
6918 int num_finished
= 0;
6920 printf("starting notify-bench test\n");
6922 if (use_multishare_conn
) {
6924 unc_list
= file_lines_load(multishare_conn_fname
,
6925 &num_unc_names
, 0, NULL
);
6926 if (!unc_list
|| num_unc_names
<= 0) {
6927 d_printf("Failed to load unc names list from '%s'\n",
6928 multishare_conn_fname
);
6931 TALLOC_FREE(unc_list
);
6936 ev
= tevent_context_init(talloc_tos());
6938 d_printf("tevent_context_init failed\n");
6942 for (i
=0; i
<num_unc_names
; i
++) {
6943 struct cli_state
*cli
;
6946 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6948 if (base_fname
== NULL
) {
6952 if (!torture_open_connection(&cli
, i
)) {
6956 status
= cli_ntcreate(cli
, dname
, 0,
6957 MAXIMUM_ALLOWED_ACCESS
,
6958 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6960 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6963 if (!NT_STATUS_IS_OK(status
)) {
6964 d_printf("Could not create %s: %s\n", dname
,
6969 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6970 FILE_NOTIFY_CHANGE_FILE_NAME
|
6971 FILE_NOTIFY_CHANGE_DIR_NAME
|
6972 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6973 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6974 false, print_notifies
, NULL
);
6976 d_printf("Could not create notify request\n");
6980 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6981 base_fname
, 10, torture_numops
);
6983 d_printf("Could not create createdels request\n");
6986 TALLOC_FREE(base_fname
);
6988 tevent_req_set_callback(req2
, notify_bench_done
,
6992 while (num_finished
< num_unc_names
) {
6994 ret
= tevent_loop_once(ev
);
6996 d_printf("tevent_loop_once failed\n");
7001 if (!tevent_req_poll(req2
, ev
)) {
7002 d_printf("tevent_req_poll failed\n");
7005 status
= torture_createdels_recv(req2
);
7006 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7011 static bool run_mangle1(int dummy
)
7013 struct cli_state
*cli
;
7014 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7018 time_t change_time
, access_time
, write_time
;
7022 printf("starting mangle1 test\n");
7023 if (!torture_open_connection(&cli
, 0)) {
7027 cli_sockopt(cli
, sockops
);
7029 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7030 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7032 if (!NT_STATUS_IS_OK(status
)) {
7033 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7036 cli_close(cli
, fnum
);
7038 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7039 if (!NT_STATUS_IS_OK(status
)) {
7040 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7044 d_printf("alt_name: %s\n", alt_name
);
7046 status
= cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7047 if (!NT_STATUS_IS_OK(status
)) {
7048 d_printf("cli_open(%s) failed: %s\n", alt_name
,
7052 cli_close(cli
, fnum
);
7054 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7055 &write_time
, &size
, &mode
);
7056 if (!NT_STATUS_IS_OK(status
)) {
7057 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7065 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7067 size_t *to_pull
= (size_t *)priv
;
7068 size_t thistime
= *to_pull
;
7070 thistime
= MIN(thistime
, n
);
7071 if (thistime
== 0) {
7075 memset(buf
, 0, thistime
);
7076 *to_pull
-= thistime
;
7080 static bool run_windows_write(int dummy
)
7082 struct cli_state
*cli1
;
7086 const char *fname
= "\\writetest.txt";
7087 struct timeval start_time
;
7092 printf("starting windows_write test\n");
7093 if (!torture_open_connection(&cli1
, 0)) {
7097 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7098 if (!NT_STATUS_IS_OK(status
)) {
7099 printf("open failed (%s)\n", nt_errstr(status
));
7103 cli_sockopt(cli1
, sockops
);
7105 start_time
= timeval_current();
7107 for (i
=0; i
<torture_numops
; i
++) {
7109 off_t start
= i
* torture_blocksize
;
7110 size_t to_pull
= torture_blocksize
- 1;
7112 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7113 start
+ torture_blocksize
- 1, 1, NULL
);
7114 if (!NT_STATUS_IS_OK(status
)) {
7115 printf("cli_write failed: %s\n", nt_errstr(status
));
7119 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7120 null_source
, &to_pull
);
7121 if (!NT_STATUS_IS_OK(status
)) {
7122 printf("cli_push returned: %s\n", nt_errstr(status
));
7127 seconds
= timeval_elapsed(&start_time
);
7128 kbytes
= (double)torture_blocksize
* torture_numops
;
7131 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7132 (double)seconds
, (int)(kbytes
/seconds
));
7136 cli_close(cli1
, fnum
);
7137 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7138 torture_close_connection(cli1
);
7142 static bool run_cli_echo(int dummy
)
7144 struct cli_state
*cli
;
7147 printf("starting cli_echo test\n");
7148 if (!torture_open_connection(&cli
, 0)) {
7151 cli_sockopt(cli
, sockops
);
7153 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7155 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7157 torture_close_connection(cli
);
7158 return NT_STATUS_IS_OK(status
);
7161 static bool run_uid_regression_test(int dummy
)
7163 static struct cli_state
*cli
;
7166 bool correct
= True
;
7169 printf("starting uid regression test\n");
7171 if (!torture_open_connection(&cli
, 0)) {
7175 cli_sockopt(cli
, sockops
);
7177 /* Ok - now save then logoff our current user. */
7178 old_vuid
= cli_state_get_uid(cli
);
7180 status
= cli_ulogoff(cli
);
7181 if (!NT_STATUS_IS_OK(status
)) {
7182 d_printf("(%s) cli_ulogoff failed: %s\n",
7183 __location__
, nt_errstr(status
));
7188 cli_state_set_uid(cli
, old_vuid
);
7190 /* Try an operation. */
7191 status
= cli_mkdir(cli
, "\\uid_reg_test");
7192 if (NT_STATUS_IS_OK(status
)) {
7193 d_printf("(%s) cli_mkdir succeeded\n",
7198 /* Should be bad uid. */
7199 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
7200 NT_STATUS_USER_SESSION_DELETED
)) {
7206 old_cnum
= cli_state_get_tid(cli
);
7208 /* Now try a SMBtdis with the invald vuid set to zero. */
7209 cli_state_set_uid(cli
, 0);
7211 /* This should succeed. */
7212 status
= cli_tdis(cli
);
7214 if (NT_STATUS_IS_OK(status
)) {
7215 d_printf("First tdis with invalid vuid should succeed.\n");
7217 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7222 cli_state_set_uid(cli
, old_vuid
);
7223 cli_state_set_tid(cli
, old_cnum
);
7225 /* This should fail. */
7226 status
= cli_tdis(cli
);
7227 if (NT_STATUS_IS_OK(status
)) {
7228 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7232 /* Should be bad tid. */
7233 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
7234 NT_STATUS_NETWORK_NAME_DELETED
)) {
7240 cli_rmdir(cli
, "\\uid_reg_test");
7249 static const char *illegal_chars
= "*\\/?<>|\":";
7250 static char force_shortname_chars
[] = " +,.[];=\177";
7252 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7253 const char *mask
, void *state
)
7255 struct cli_state
*pcli
= (struct cli_state
*)state
;
7257 NTSTATUS status
= NT_STATUS_OK
;
7259 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7261 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7262 return NT_STATUS_OK
;
7264 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7265 status
= cli_rmdir(pcli
, fname
);
7266 if (!NT_STATUS_IS_OK(status
)) {
7267 printf("del_fn: failed to rmdir %s\n,", fname
);
7270 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7271 if (!NT_STATUS_IS_OK(status
)) {
7272 printf("del_fn: failed to unlink %s\n,", fname
);
7284 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7285 const char *name
, void *state
)
7287 struct sn_state
*s
= (struct sn_state
*)state
;
7291 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7292 i
, finfo
->name
, finfo
->short_name
);
7295 if (strchr(force_shortname_chars
, i
)) {
7296 if (!finfo
->short_name
) {
7297 /* Shortname not created when it should be. */
7298 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7299 __location__
, finfo
->name
, i
);
7302 } else if (finfo
->short_name
){
7303 /* Shortname created when it should not be. */
7304 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7305 __location__
, finfo
->short_name
, finfo
->name
);
7309 return NT_STATUS_OK
;
7312 static bool run_shortname_test(int dummy
)
7314 static struct cli_state
*cli
;
7315 bool correct
= True
;
7321 printf("starting shortname test\n");
7323 if (!torture_open_connection(&cli
, 0)) {
7327 cli_sockopt(cli
, sockops
);
7329 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7330 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7331 cli_rmdir(cli
, "\\shortname");
7333 status
= cli_mkdir(cli
, "\\shortname");
7334 if (!NT_STATUS_IS_OK(status
)) {
7335 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7336 __location__
, nt_errstr(status
));
7341 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
7342 strlcat(fname
, "test .txt", sizeof(fname
));
7346 for (i
= 32; i
< 128; i
++) {
7347 uint16_t fnum
= (uint16_t)-1;
7351 if (strchr(illegal_chars
, i
)) {
7356 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7357 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
7358 if (!NT_STATUS_IS_OK(status
)) {
7359 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7360 __location__
, fname
, nt_errstr(status
));
7364 cli_close(cli
, fnum
);
7367 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7368 shortname_list_fn
, &s
);
7369 if (s
.matched
!= 1) {
7370 d_printf("(%s) failed to list %s: %s\n",
7371 __location__
, fname
, nt_errstr(status
));
7376 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7377 if (!NT_STATUS_IS_OK(status
)) {
7378 d_printf("(%s) failed to delete %s: %s\n",
7379 __location__
, fname
, nt_errstr(status
));
7392 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7393 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7394 cli_rmdir(cli
, "\\shortname");
7395 torture_close_connection(cli
);
7399 static void pagedsearch_cb(struct tevent_req
*req
)
7402 struct tldap_message
*msg
;
7405 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7406 if (rc
!= TLDAP_SUCCESS
) {
7407 d_printf("tldap_search_paged_recv failed: %s\n",
7408 tldap_err2string(rc
));
7411 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7415 if (!tldap_entry_dn(msg
, &dn
)) {
7416 d_printf("tldap_entry_dn failed\n");
7419 d_printf("%s\n", dn
);
7423 static bool run_tldap(int dummy
)
7425 struct tldap_context
*ld
;
7428 struct sockaddr_storage addr
;
7429 struct tevent_context
*ev
;
7430 struct tevent_req
*req
;
7434 if (!resolve_name(host
, &addr
, 0, false)) {
7435 d_printf("could not find host %s\n", host
);
7438 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7439 if (!NT_STATUS_IS_OK(status
)) {
7440 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7444 ld
= tldap_context_create(talloc_tos(), fd
);
7447 d_printf("tldap_context_create failed\n");
7451 rc
= tldap_fetch_rootdse(ld
);
7452 if (rc
!= TLDAP_SUCCESS
) {
7453 d_printf("tldap_fetch_rootdse failed: %s\n",
7454 tldap_errstr(talloc_tos(), ld
, rc
));
7458 basedn
= tldap_talloc_single_attribute(
7459 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7460 if (basedn
== NULL
) {
7461 d_printf("no defaultNamingContext\n");
7464 d_printf("defaultNamingContext: %s\n", basedn
);
7466 ev
= tevent_context_init(talloc_tos());
7468 d_printf("tevent_context_init failed\n");
7472 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7473 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7475 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7477 d_printf("tldap_search_paged_send failed\n");
7480 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7482 tevent_req_poll(req
, ev
);
7486 /* test search filters against rootDSE */
7487 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7488 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7490 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7491 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7492 talloc_tos(), NULL
, NULL
);
7493 if (rc
!= TLDAP_SUCCESS
) {
7494 d_printf("tldap_search with complex filter failed: %s\n",
7495 tldap_errstr(talloc_tos(), ld
, rc
));
7503 /* Torture test to ensure no regression of :
7504 https://bugzilla.samba.org/show_bug.cgi?id=7084
7507 static bool run_dir_createtime(int dummy
)
7509 struct cli_state
*cli
;
7510 const char *dname
= "\\testdir";
7511 const char *fname
= "\\testdir\\testfile";
7513 struct timespec create_time
;
7514 struct timespec create_time1
;
7518 if (!torture_open_connection(&cli
, 0)) {
7522 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7523 cli_rmdir(cli
, dname
);
7525 status
= cli_mkdir(cli
, dname
);
7526 if (!NT_STATUS_IS_OK(status
)) {
7527 printf("mkdir failed: %s\n", nt_errstr(status
));
7531 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7533 if (!NT_STATUS_IS_OK(status
)) {
7534 printf("cli_qpathinfo2 returned %s\n",
7539 /* Sleep 3 seconds, then create a file. */
7542 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7544 if (!NT_STATUS_IS_OK(status
)) {
7545 printf("cli_open failed: %s\n", nt_errstr(status
));
7549 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7551 if (!NT_STATUS_IS_OK(status
)) {
7552 printf("cli_qpathinfo2 (2) returned %s\n",
7557 if (timespec_compare(&create_time1
, &create_time
)) {
7558 printf("run_dir_createtime: create time was updated (error)\n");
7560 printf("run_dir_createtime: create time was not updated (correct)\n");
7566 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7567 cli_rmdir(cli
, dname
);
7568 if (!torture_close_connection(cli
)) {
7575 static bool run_streamerror(int dummy
)
7577 struct cli_state
*cli
;
7578 const char *dname
= "\\testdir";
7579 const char *streamname
=
7580 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7582 time_t change_time
, access_time
, write_time
;
7584 uint16_t mode
, fnum
;
7587 if (!torture_open_connection(&cli
, 0)) {
7591 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7592 cli_rmdir(cli
, dname
);
7594 status
= cli_mkdir(cli
, dname
);
7595 if (!NT_STATUS_IS_OK(status
)) {
7596 printf("mkdir failed: %s\n", nt_errstr(status
));
7600 status
= cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
,
7601 &write_time
, &size
, &mode
);
7602 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7603 printf("pathinfo returned %s, expected "
7604 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7609 status
= cli_ntcreate(cli
, streamname
, 0x16,
7610 FILE_READ_DATA
|FILE_READ_EA
|
7611 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7612 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7613 FILE_OPEN
, 0, 0, &fnum
);
7615 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7616 printf("ntcreate returned %s, expected "
7617 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7623 cli_rmdir(cli
, dname
);
7627 static bool run_local_substitute(int dummy
)
7631 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7632 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7633 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7634 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7635 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7636 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7637 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7638 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7640 /* Different captialization rules in sub_basic... */
7642 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7648 static bool run_local_base64(int dummy
)
7653 for (i
=1; i
<2000; i
++) {
7654 DATA_BLOB blob1
, blob2
;
7657 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7659 generate_random_buffer(blob1
.data
, blob1
.length
);
7661 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7663 d_fprintf(stderr
, "base64_encode_data_blob failed "
7664 "for %d bytes\n", i
);
7667 blob2
= base64_decode_data_blob(b64
);
7670 if (data_blob_cmp(&blob1
, &blob2
)) {
7671 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7675 TALLOC_FREE(blob1
.data
);
7676 data_blob_free(&blob2
);
7681 static bool run_local_gencache(int dummy
)
7687 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7688 d_printf("%s: gencache_set() failed\n", __location__
);
7692 if (!gencache_get("foo", NULL
, NULL
)) {
7693 d_printf("%s: gencache_get() failed\n", __location__
);
7697 if (!gencache_get("foo", &val
, &tm
)) {
7698 d_printf("%s: gencache_get() failed\n", __location__
);
7702 if (strcmp(val
, "bar") != 0) {
7703 d_printf("%s: gencache_get() returned %s, expected %s\n",
7704 __location__
, val
, "bar");
7711 if (!gencache_del("foo")) {
7712 d_printf("%s: gencache_del() failed\n", __location__
);
7715 if (gencache_del("foo")) {
7716 d_printf("%s: second gencache_del() succeeded\n",
7721 if (gencache_get("foo", &val
, &tm
)) {
7722 d_printf("%s: gencache_get() on deleted entry "
7723 "succeeded\n", __location__
);
7727 blob
= data_blob_string_const_null("bar");
7728 tm
= time(NULL
) + 60;
7730 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7731 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7735 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7736 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7740 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7741 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7742 __location__
, (const char *)blob
.data
, "bar");
7743 data_blob_free(&blob
);
7747 data_blob_free(&blob
);
7749 if (!gencache_del("foo")) {
7750 d_printf("%s: gencache_del() failed\n", __location__
);
7753 if (gencache_del("foo")) {
7754 d_printf("%s: second gencache_del() succeeded\n",
7759 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7760 d_printf("%s: gencache_get_data_blob() on deleted entry "
7761 "succeeded\n", __location__
);
7768 static bool rbt_testval(struct db_context
*db
, const char *key
,
7771 struct db_record
*rec
;
7772 TDB_DATA data
= string_tdb_data(value
);
7777 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7779 d_fprintf(stderr
, "fetch_locked failed\n");
7782 status
= dbwrap_record_store(rec
, data
, 0);
7783 if (!NT_STATUS_IS_OK(status
)) {
7784 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7789 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7791 d_fprintf(stderr
, "second fetch_locked failed\n");
7795 dbvalue
= dbwrap_record_get_value(rec
);
7796 if ((dbvalue
.dsize
!= data
.dsize
)
7797 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7798 d_fprintf(stderr
, "Got wrong data back\n");
7808 static bool run_local_rbtree(int dummy
)
7810 struct db_context
*db
;
7814 db
= db_open_rbt(NULL
);
7817 d_fprintf(stderr
, "db_open_rbt failed\n");
7821 for (i
=0; i
<1000; i
++) {
7824 if (asprintf(&key
, "key%ld", random()) == -1) {
7827 if (asprintf(&value
, "value%ld", random()) == -1) {
7832 if (!rbt_testval(db
, key
, value
)) {
7839 if (asprintf(&value
, "value%ld", random()) == -1) {
7844 if (!rbt_testval(db
, key
, value
)) {
7863 local test for character set functions
7865 This is a very simple test for the functionality in convert_string_error()
7867 static bool run_local_convert_string(int dummy
)
7869 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
7870 const char *test_strings
[2] = { "March", "M\303\244rz" };
7874 for (i
=0; i
<2; i
++) {
7875 const char *str
= test_strings
[i
];
7876 int len
= strlen(str
);
7877 size_t converted_size
;
7880 memset(dst
, 'X', sizeof(dst
));
7882 /* first try with real source length */
7883 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7888 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7892 if (converted_size
!= len
) {
7893 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7894 str
, len
, (int)converted_size
);
7898 if (strncmp(str
, dst
, converted_size
) != 0) {
7899 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7903 if (strlen(str
) != converted_size
) {
7904 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7905 (int)strlen(str
), (int)converted_size
);
7909 if (dst
[converted_size
] != 'X') {
7910 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7914 /* now with srclen==-1, this causes the nul to be
7916 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7921 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7925 if (converted_size
!= len
+1) {
7926 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7927 str
, len
, (int)converted_size
);
7931 if (strncmp(str
, dst
, converted_size
) != 0) {
7932 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7936 if (len
+1 != converted_size
) {
7937 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7938 len
+1, (int)converted_size
);
7942 if (dst
[converted_size
] != 'X') {
7943 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7950 TALLOC_FREE(tmp_ctx
);
7953 TALLOC_FREE(tmp_ctx
);
7958 struct talloc_dict_test
{
7962 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7964 int *count
= (int *)priv
;
7969 static bool run_local_talloc_dict(int dummy
)
7971 struct talloc_dict
*dict
;
7972 struct talloc_dict_test
*t
;
7975 dict
= talloc_dict_init(talloc_tos());
7980 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7987 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7992 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
8005 static bool run_local_string_to_sid(int dummy
) {
8008 if (string_to_sid(&sid
, "S--1-5-32-545")) {
8009 printf("allowing S--1-5-32-545\n");
8012 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
8013 printf("allowing S-1-5-32-+545\n");
8016 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")) {
8017 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8020 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
8021 printf("allowing S-1-5-32-545-abc\n");
8024 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
8025 printf("could not parse S-1-5-32-545\n");
8028 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
8029 printf("mis-parsed S-1-5-32-545 as %s\n",
8030 sid_string_tos(&sid
));
8036 static bool run_local_binary_to_sid(int dummy
) {
8037 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
8038 static const char good_binary_sid
[] = {
8039 0x1, /* revision number */
8041 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8042 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8043 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8044 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8045 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8046 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8047 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8048 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8049 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8050 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8051 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8052 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8053 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8054 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8055 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8056 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8059 static const char long_binary_sid
[] = {
8060 0x1, /* revision number */
8062 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8063 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8067 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8068 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8069 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8070 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8071 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8072 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8073 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8074 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8075 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8076 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8077 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8078 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8079 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8080 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8083 static const char long_binary_sid2
[] = {
8084 0x1, /* revision number */
8086 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8087 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8098 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8099 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8100 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8101 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8102 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8103 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8104 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8105 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8106 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8107 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8108 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8109 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8110 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8111 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8112 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8113 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8114 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8115 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8116 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8117 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8118 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8121 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8124 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8127 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8133 /* Split a path name into filename and stream name components. Canonicalise
8134 * such that an implicit $DATA token is always explicit.
8136 * The "specification" of this function can be found in the
8137 * run_local_stream_name() function in torture.c, I've tried those
8138 * combinations against a W2k3 server.
8141 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8142 char **pbase
, char **pstream
)
8145 char *stream
= NULL
;
8146 char *sname
; /* stream name */
8147 const char *stype
; /* stream type */
8149 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8151 sname
= strchr_m(fname
, ':');
8153 if (lp_posix_pathnames() || (sname
== NULL
)) {
8154 if (pbase
!= NULL
) {
8155 base
= talloc_strdup(mem_ctx
, fname
);
8156 NT_STATUS_HAVE_NO_MEMORY(base
);
8161 if (pbase
!= NULL
) {
8162 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8163 NT_STATUS_HAVE_NO_MEMORY(base
);
8168 stype
= strchr_m(sname
, ':');
8170 if (stype
== NULL
) {
8171 sname
= talloc_strdup(mem_ctx
, sname
);
8175 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8177 * If there is an explicit stream type, so far we only
8178 * allow $DATA. Is there anything else allowed? -- vl
8180 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8182 return NT_STATUS_OBJECT_NAME_INVALID
;
8184 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8188 if (sname
== NULL
) {
8190 return NT_STATUS_NO_MEMORY
;
8193 if (sname
[0] == '\0') {
8195 * no stream name, so no stream
8200 if (pstream
!= NULL
) {
8201 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8202 if (stream
== NULL
) {
8205 return NT_STATUS_NO_MEMORY
;
8208 * upper-case the type field
8210 strupper_m(strchr_m(stream
, ':')+1);
8214 if (pbase
!= NULL
) {
8217 if (pstream
!= NULL
) {
8220 return NT_STATUS_OK
;
8223 static bool test_stream_name(const char *fname
, const char *expected_base
,
8224 const char *expected_stream
,
8225 NTSTATUS expected_status
)
8229 char *stream
= NULL
;
8231 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8232 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8236 if (!NT_STATUS_IS_OK(status
)) {
8240 if (base
== NULL
) goto error
;
8242 if (strcmp(expected_base
, base
) != 0) goto error
;
8244 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8245 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8247 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8251 TALLOC_FREE(stream
);
8255 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8256 fname
, expected_base
? expected_base
: "<NULL>",
8257 expected_stream
? expected_stream
: "<NULL>",
8258 nt_errstr(expected_status
));
8259 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8260 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8263 TALLOC_FREE(stream
);
8267 static bool run_local_stream_name(int dummy
)
8271 ret
&= test_stream_name(
8272 "bla", "bla", NULL
, NT_STATUS_OK
);
8273 ret
&= test_stream_name(
8274 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8275 ret
&= test_stream_name(
8276 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8277 ret
&= test_stream_name(
8278 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8279 ret
&= test_stream_name(
8280 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8281 ret
&= test_stream_name(
8282 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8283 ret
&= test_stream_name(
8284 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8285 ret
&= test_stream_name(
8286 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8291 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8293 if (a
.length
!= b
.length
) {
8294 printf("a.length=%d != b.length=%d\n",
8295 (int)a
.length
, (int)b
.length
);
8298 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8299 printf("a.data and b.data differ\n");
8305 static bool run_local_memcache(int dummy
)
8307 struct memcache
*cache
;
8309 DATA_BLOB d1
, d2
, d3
;
8310 DATA_BLOB v1
, v2
, v3
;
8312 TALLOC_CTX
*mem_ctx
;
8314 size_t size1
, size2
;
8317 cache
= memcache_init(NULL
, 100);
8319 if (cache
== NULL
) {
8320 printf("memcache_init failed\n");
8324 d1
= data_blob_const("d1", 2);
8325 d2
= data_blob_const("d2", 2);
8326 d3
= data_blob_const("d3", 2);
8328 k1
= data_blob_const("d1", 2);
8329 k2
= data_blob_const("d2", 2);
8331 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8332 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8334 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8335 printf("could not find k1\n");
8338 if (!data_blob_equal(d1
, v1
)) {
8342 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8343 printf("could not find k2\n");
8346 if (!data_blob_equal(d2
, v2
)) {
8350 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8352 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8353 printf("could not find replaced k1\n");
8356 if (!data_blob_equal(d3
, v3
)) {
8360 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8362 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8363 printf("Did find k2, should have been purged\n");
8369 cache
= memcache_init(NULL
, 0);
8371 mem_ctx
= talloc_init("foo");
8373 str1
= talloc_strdup(mem_ctx
, "string1");
8374 str2
= talloc_strdup(mem_ctx
, "string2");
8376 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8377 data_blob_string_const("torture"), &str1
);
8378 size1
= talloc_total_size(cache
);
8380 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8381 data_blob_string_const("torture"), &str2
);
8382 size2
= talloc_total_size(cache
);
8384 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8386 if (size2
> size1
) {
8387 printf("memcache leaks memory!\n");
8397 static void wbclient_done(struct tevent_req
*req
)
8400 struct winbindd_response
*wb_resp
;
8401 int *i
= (int *)tevent_req_callback_data_void(req
);
8403 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8406 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8409 static bool run_local_wbclient(int dummy
)
8411 struct event_context
*ev
;
8412 struct wb_context
**wb_ctx
;
8413 struct winbindd_request wb_req
;
8414 bool result
= false;
8417 BlockSignals(True
, SIGPIPE
);
8419 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
8424 wb_ctx
= talloc_array(ev
, struct wb_context
*, nprocs
);
8425 if (wb_ctx
== NULL
) {
8429 ZERO_STRUCT(wb_req
);
8430 wb_req
.cmd
= WINBINDD_PING
;
8432 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
8434 for (i
=0; i
<nprocs
; i
++) {
8435 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8436 if (wb_ctx
[i
] == NULL
) {
8439 for (j
=0; j
<torture_numops
; j
++) {
8440 struct tevent_req
*req
;
8441 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8442 (j
% 2) == 0, &wb_req
);
8446 tevent_req_set_callback(req
, wbclient_done
, &i
);
8452 while (i
< nprocs
* torture_numops
) {
8453 tevent_loop_once(ev
);
8462 static void getaddrinfo_finished(struct tevent_req
*req
)
8464 char *name
= (char *)tevent_req_callback_data_void(req
);
8465 struct addrinfo
*ainfo
;
8468 res
= getaddrinfo_recv(req
, &ainfo
);
8470 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
8473 d_printf("gai(%s) succeeded\n", name
);
8474 freeaddrinfo(ainfo
);
8477 static bool run_getaddrinfo_send(int dummy
)
8479 TALLOC_CTX
*frame
= talloc_stackframe();
8480 struct fncall_context
*ctx
;
8481 struct tevent_context
*ev
;
8482 bool result
= false;
8483 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
8484 "www.slashdot.org", "heise.de" };
8485 struct tevent_req
*reqs
[4];
8488 ev
= event_context_init(frame
);
8493 ctx
= fncall_context_init(frame
, 4);
8495 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
8496 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
8498 if (reqs
[i
] == NULL
) {
8501 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
8502 discard_const_p(void, names
[i
]));
8505 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
8506 tevent_loop_once(ev
);
8515 static bool dbtrans_inc(struct db_context
*db
)
8517 struct db_record
*rec
;
8523 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8525 printf(__location__
"fetch_lock failed\n");
8529 value
= dbwrap_record_get_value(rec
);
8531 if (value
.dsize
!= sizeof(uint32_t)) {
8532 printf(__location__
"value.dsize = %d\n",
8537 val
= (uint32_t *)value
.dptr
;
8540 status
= dbwrap_record_store(rec
, make_tdb_data((uint8_t *)val
,
8543 if (!NT_STATUS_IS_OK(status
)) {
8544 printf(__location__
"store failed: %s\n",
8555 static bool run_local_dbtrans(int dummy
)
8557 struct db_context
*db
;
8558 struct db_record
*rec
;
8564 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
8565 O_RDWR
|O_CREAT
, 0600);
8567 printf("Could not open transtest.db\n");
8571 res
= dbwrap_transaction_start(db
);
8573 printf(__location__
"transaction_start failed\n");
8577 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8579 printf(__location__
"fetch_lock failed\n");
8583 value
= dbwrap_record_get_value(rec
);
8585 if (value
.dptr
== NULL
) {
8587 status
= dbwrap_record_store(
8588 rec
, make_tdb_data((uint8_t *)&initial
,
8591 if (!NT_STATUS_IS_OK(status
)) {
8592 printf(__location__
"store returned %s\n",
8600 res
= dbwrap_transaction_commit(db
);
8602 printf(__location__
"transaction_commit failed\n");
8610 res
= dbwrap_transaction_start(db
);
8612 printf(__location__
"transaction_start failed\n");
8616 status
= dbwrap_fetch_uint32(db
, "transtest", &val
);
8617 if (!NT_STATUS_IS_OK(status
)) {
8618 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8623 for (i
=0; i
<10; i
++) {
8624 if (!dbtrans_inc(db
)) {
8629 status
= dbwrap_fetch_uint32(db
, "transtest", &val2
);
8630 if (!NT_STATUS_IS_OK(status
)) {
8631 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8636 if (val2
!= val
+ 10) {
8637 printf(__location__
"val=%d, val2=%d\n",
8638 (int)val
, (int)val2
);
8642 printf("val2=%d\r", val2
);
8644 res
= dbwrap_transaction_commit(db
);
8646 printf(__location__
"transaction_commit failed\n");
8656 * Just a dummy test to be run under a debugger. There's no real way
8657 * to inspect the tevent_select specific function from outside of
8661 static bool run_local_tevent_select(int dummy
)
8663 struct tevent_context
*ev
;
8664 struct tevent_fd
*fd1
, *fd2
;
8665 bool result
= false;
8667 ev
= tevent_context_init_byname(NULL
, "select");
8669 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8673 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8675 d_fprintf(stderr
, "tevent_add_fd failed\n");
8678 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8680 d_fprintf(stderr
, "tevent_add_fd failed\n");
8685 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8687 d_fprintf(stderr
, "tevent_add_fd failed\n");
8697 static double create_procs(bool (*fn
)(int), bool *result
)
8700 volatile pid_t
*child_status
;
8701 volatile bool *child_status_out
;
8704 struct timeval start
;
8708 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
8709 if (!child_status
) {
8710 printf("Failed to setup shared memory\n");
8714 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
8715 if (!child_status_out
) {
8716 printf("Failed to setup result status shared memory\n");
8720 for (i
= 0; i
< nprocs
; i
++) {
8721 child_status
[i
] = 0;
8722 child_status_out
[i
] = True
;
8725 start
= timeval_current();
8727 for (i
=0;i
<nprocs
;i
++) {
8730 pid_t mypid
= getpid();
8731 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8733 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8736 if (torture_open_connection(¤t_cli
, i
)) break;
8738 printf("pid %d failed to start\n", (int)getpid());
8744 child_status
[i
] = getpid();
8746 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8748 child_status_out
[i
] = fn(i
);
8755 for (i
=0;i
<nprocs
;i
++) {
8756 if (child_status
[i
]) synccount
++;
8758 if (synccount
== nprocs
) break;
8760 } while (timeval_elapsed(&start
) < 30);
8762 if (synccount
!= nprocs
) {
8763 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8765 return timeval_elapsed(&start
);
8768 /* start the client load */
8769 start
= timeval_current();
8771 for (i
=0;i
<nprocs
;i
++) {
8772 child_status
[i
] = 0;
8775 printf("%d clients started\n", nprocs
);
8777 for (i
=0;i
<nprocs
;i
++) {
8778 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8783 for (i
=0;i
<nprocs
;i
++) {
8784 if (!child_status_out
[i
]) {
8788 return timeval_elapsed(&start
);
8791 #define FLAG_MULTIPROC 1
8798 {"FDPASS", run_fdpasstest
, 0},
8799 {"LOCK1", run_locktest1
, 0},
8800 {"LOCK2", run_locktest2
, 0},
8801 {"LOCK3", run_locktest3
, 0},
8802 {"LOCK4", run_locktest4
, 0},
8803 {"LOCK5", run_locktest5
, 0},
8804 {"LOCK6", run_locktest6
, 0},
8805 {"LOCK7", run_locktest7
, 0},
8806 {"LOCK8", run_locktest8
, 0},
8807 {"LOCK9", run_locktest9
, 0},
8808 {"UNLINK", run_unlinktest
, 0},
8809 {"BROWSE", run_browsetest
, 0},
8810 {"ATTR", run_attrtest
, 0},
8811 {"TRANS2", run_trans2test
, 0},
8812 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8813 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8814 {"RANDOMIPC", run_randomipc
, 0},
8815 {"NEGNOWAIT", run_negprot_nowait
, 0},
8816 {"NBENCH", run_nbench
, 0},
8817 {"NBENCH2", run_nbench2
, 0},
8818 {"OPLOCK1", run_oplock1
, 0},
8819 {"OPLOCK2", run_oplock2
, 0},
8820 {"OPLOCK4", run_oplock4
, 0},
8821 {"DIR", run_dirtest
, 0},
8822 {"DIR1", run_dirtest1
, 0},
8823 {"DIR-CREATETIME", run_dir_createtime
, 0},
8824 {"DENY1", torture_denytest1
, 0},
8825 {"DENY2", torture_denytest2
, 0},
8826 {"TCON", run_tcon_test
, 0},
8827 {"TCONDEV", run_tcon_devtype_test
, 0},
8828 {"RW1", run_readwritetest
, 0},
8829 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8830 {"RW3", run_readwritelarge
, 0},
8831 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8832 {"OPEN", run_opentest
, 0},
8833 {"POSIX", run_simple_posix_open_test
, 0},
8834 {"POSIX-APPEND", run_posix_append
, 0},
8835 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
8836 {"ASYNC-ECHO", run_async_echo
, 0},
8837 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8838 { "SHORTNAME-TEST", run_shortname_test
, 0},
8839 { "ADDRCHANGE", run_addrchange
, 0},
8841 {"OPENATTR", run_openattrtest
, 0},
8843 {"XCOPY", run_xcopy
, 0},
8844 {"RENAME", run_rename
, 0},
8845 {"DELETE", run_deletetest
, 0},
8846 {"DELETE-LN", run_deletetest_ln
, 0},
8847 {"PROPERTIES", run_properties
, 0},
8848 {"MANGLE", torture_mangle
, 0},
8849 {"MANGLE1", run_mangle1
, 0},
8850 {"W2K", run_w2ktest
, 0},
8851 {"TRANS2SCAN", torture_trans2_scan
, 0},
8852 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8853 {"UTABLE", torture_utable
, 0},
8854 {"CASETABLE", torture_casetable
, 0},
8855 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8856 {"PIPE_NUMBER", run_pipe_number
, 0},
8857 {"TCON2", run_tcon2_test
, 0},
8858 {"IOCTL", torture_ioctl_test
, 0},
8859 {"CHKPATH", torture_chkpath_test
, 0},
8860 {"FDSESS", run_fdsesstest
, 0},
8861 { "EATEST", run_eatest
, 0},
8862 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8863 { "CHAIN1", run_chain1
, 0},
8864 { "CHAIN2", run_chain2
, 0},
8865 { "WINDOWS-WRITE", run_windows_write
, 0},
8866 { "NTTRANS-CREATE", run_nttrans_create
, 0},
8867 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
8868 { "CLI_ECHO", run_cli_echo
, 0},
8869 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8870 { "TLDAP", run_tldap
},
8871 { "STREAMERROR", run_streamerror
},
8872 { "NOTIFY-BENCH", run_notify_bench
},
8873 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8874 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8875 { "NOTIFY-ONLINE", run_notify_online
},
8876 { "SMB2-BASIC", run_smb2_basic
},
8877 { "SMB2-NEGPROT", run_smb2_negprot
},
8878 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8879 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8880 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8881 { "LOCAL-BASE64", run_local_base64
, 0},
8882 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8883 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8884 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8885 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8886 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8887 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8888 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8889 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8890 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
8891 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
8892 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
8897 /****************************************************************************
8898 run a specified test or "ALL"
8899 ****************************************************************************/
8900 static bool run_test(const char *name
)
8907 if (strequal(name
,"ALL")) {
8908 for (i
=0;torture_ops
[i
].name
;i
++) {
8909 run_test(torture_ops
[i
].name
);
8914 for (i
=0;torture_ops
[i
].name
;i
++) {
8915 fstr_sprintf(randomfname
, "\\XX%x",
8916 (unsigned)random());
8918 if (strequal(name
, torture_ops
[i
].name
)) {
8920 printf("Running %s\n", name
);
8921 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8922 t
= create_procs(torture_ops
[i
].fn
, &result
);
8925 printf("TEST %s FAILED!\n", name
);
8928 struct timeval start
;
8929 start
= timeval_current();
8930 if (!torture_ops
[i
].fn(0)) {
8932 printf("TEST %s FAILED!\n", name
);
8934 t
= timeval_elapsed(&start
);
8936 printf("%s took %g secs\n\n", name
, t
);
8941 printf("Did not find a test named %s\n", name
);
8949 static void usage(void)
8953 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8954 printf("Please use samba4 torture.\n\n");
8956 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8958 printf("\t-d debuglevel\n");
8959 printf("\t-U user%%pass\n");
8960 printf("\t-k use kerberos\n");
8961 printf("\t-N numprocs\n");
8962 printf("\t-n my_netbios_name\n");
8963 printf("\t-W workgroup\n");
8964 printf("\t-o num_operations\n");
8965 printf("\t-O socket_options\n");
8966 printf("\t-m maximum protocol\n");
8967 printf("\t-L use oplocks\n");
8968 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8969 printf("\t-A showall\n");
8970 printf("\t-p port\n");
8971 printf("\t-s seed\n");
8972 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8973 printf("\t-f filename filename to test\n");
8976 printf("tests are:");
8977 for (i
=0;torture_ops
[i
].name
;i
++) {
8978 printf(" %s", torture_ops
[i
].name
);
8982 printf("default test is ALL\n");
8987 /****************************************************************************
8989 ****************************************************************************/
8990 int main(int argc
,char *argv
[])
8996 bool correct
= True
;
8997 TALLOC_CTX
*frame
= talloc_stackframe();
8998 int seed
= time(NULL
);
9000 #ifdef HAVE_SETBUFFER
9001 setbuffer(stdout
, NULL
, 0);
9004 setup_logging("smbtorture", DEBUG_STDOUT
);
9008 if (is_default_dyn_CONFIGFILE()) {
9009 if(getenv("SMB_CONF_PATH")) {
9010 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9013 lp_load_global(get_dyn_CONFIGFILE());
9020 for(p
= argv
[1]; *p
; p
++)
9024 if (strncmp(argv
[1], "//", 2)) {
9028 fstrcpy(host
, &argv
[1][2]);
9029 p
= strchr_m(&host
[2],'/');
9034 fstrcpy(share
, p
+1);
9036 fstrcpy(myname
, get_myname(talloc_tos()));
9038 fprintf(stderr
, "Failed to get my hostname.\n");
9042 if (*username
== 0 && getenv("LOGNAME")) {
9043 fstrcpy(username
,getenv("LOGNAME"));
9049 fstrcpy(workgroup
, lp_workgroup());
9051 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9055 port_to_use
= atoi(optarg
);
9058 seed
= atoi(optarg
);
9061 fstrcpy(workgroup
,optarg
);
9064 max_protocol
= interpret_protocol(optarg
, max_protocol
);
9067 nprocs
= atoi(optarg
);
9070 torture_numops
= atoi(optarg
);
9073 lp_set_cmdline("log level", optarg
);
9082 local_path
= optarg
;
9085 torture_showall
= True
;
9088 fstrcpy(myname
, optarg
);
9091 client_txt
= optarg
;
9098 use_kerberos
= True
;
9100 d_printf("No kerberos support compiled in\n");
9106 fstrcpy(username
,optarg
);
9107 p
= strchr_m(username
,'%');
9110 fstrcpy(password
, p
+1);
9115 fstrcpy(multishare_conn_fname
, optarg
);
9116 use_multishare_conn
= True
;
9119 torture_blocksize
= atoi(optarg
);
9122 test_filename
= SMB_STRDUP(optarg
);
9125 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
9130 d_printf("using seed %d\n", seed
);
9134 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9137 p
= getpass("Password:");
9139 fstrcpy(password
, p
);
9144 printf("host=%s share=%s user=%s myname=%s\n",
9145 host
, share
, username
, myname
);
9147 if (argc
== optind
) {
9148 correct
= run_test("ALL");
9150 for (i
=optind
;i
<argc
;i
++) {
9151 if (!run_test(argv
[i
])) {