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
= Undefined
;
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
= Required
;
1100 ret
= run_readwritelarge_internal();
1101 signing_state
= Undefined
;
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(cli_nt_error(cli
),
1560 printf("Returned unexpected error\n");
1569 checks for correct tconX support
1571 static bool run_tcon_devtype_test(int dummy
)
1573 static struct cli_state
*cli1
= NULL
;
1578 status
= cli_full_connection(&cli1
, myname
,
1579 host
, NULL
, port_to_use
,
1581 username
, workgroup
,
1582 password
, flags
, signing_state
);
1584 if (!NT_STATUS_IS_OK(status
)) {
1585 printf("could not open connection\n");
1589 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1592 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1595 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1598 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1601 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1604 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1607 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1610 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1613 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1616 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1622 printf("Passed tcondevtest\n");
1629 This test checks that
1631 1) the server supports multiple locking contexts on the one SMB
1632 connection, distinguished by PID.
1634 2) the server correctly fails overlapping locks made by the same PID (this
1635 goes against POSIX behaviour, which is why it is tricky to implement)
1637 3) the server denies unlock requests by an incorrect client PID
1639 static bool run_locktest2(int dummy
)
1641 static struct cli_state
*cli
;
1642 const char *fname
= "\\lockt2.lck";
1643 uint16_t fnum1
, fnum2
, fnum3
;
1644 bool correct
= True
;
1647 if (!torture_open_connection(&cli
, 0)) {
1651 cli_sockopt(cli
, sockops
);
1653 printf("starting locktest2\n");
1655 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1659 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1660 if (!NT_STATUS_IS_OK(status
)) {
1661 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1665 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1666 if (!NT_STATUS_IS_OK(status
)) {
1667 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1673 status
= cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1674 if (!NT_STATUS_IS_OK(status
)) {
1675 printf("open3 of %s failed (%s)\n", fname
, nt_errstr(status
));
1681 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1682 if (!NT_STATUS_IS_OK(status
)) {
1683 printf("lock1 failed (%s)\n", nt_errstr(status
));
1687 status
= cli_lock32(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
);
1688 if (NT_STATUS_IS_OK(status
)) {
1689 printf("WRITE lock1 succeeded! This is a locking bug\n");
1692 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1693 NT_STATUS_LOCK_NOT_GRANTED
)) {
1698 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1699 if (NT_STATUS_IS_OK(status
)) {
1700 printf("WRITE lock2 succeeded! This is a locking bug\n");
1703 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1704 NT_STATUS_LOCK_NOT_GRANTED
)) {
1709 status
= cli_lock32(cli
, fnum2
, 0, 4, 0, READ_LOCK
);
1710 if (NT_STATUS_IS_OK(status
)) {
1711 printf("READ lock2 succeeded! This is a locking bug\n");
1714 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1715 NT_STATUS_FILE_LOCK_CONFLICT
)) {
1720 status
= cli_lock32(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
);
1721 if (!NT_STATUS_IS_OK(status
)) {
1722 printf("lock at 100 failed (%s)\n", nt_errstr(status
));
1725 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1726 printf("unlock at 100 succeeded! This is a locking bug\n");
1730 status
= cli_unlock(cli
, fnum1
, 0, 4);
1731 if (NT_STATUS_IS_OK(status
)) {
1732 printf("unlock1 succeeded! This is a locking bug\n");
1735 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1736 NT_STATUS_RANGE_NOT_LOCKED
)) {
1741 status
= cli_unlock(cli
, fnum1
, 0, 8);
1742 if (NT_STATUS_IS_OK(status
)) {
1743 printf("unlock2 succeeded! This is a locking bug\n");
1746 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1747 NT_STATUS_RANGE_NOT_LOCKED
)) {
1752 status
= cli_lock32(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
);
1753 if (NT_STATUS_IS_OK(status
)) {
1754 printf("lock3 succeeded! This is a locking bug\n");
1757 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRlock
,
1758 NT_STATUS_LOCK_NOT_GRANTED
)) {
1765 status
= cli_close(cli
, fnum1
);
1766 if (!NT_STATUS_IS_OK(status
)) {
1767 printf("close1 failed (%s)\n", nt_errstr(status
));
1771 status
= cli_close(cli
, fnum2
);
1772 if (!NT_STATUS_IS_OK(status
)) {
1773 printf("close2 failed (%s)\n", nt_errstr(status
));
1777 status
= cli_close(cli
, fnum3
);
1778 if (!NT_STATUS_IS_OK(status
)) {
1779 printf("close3 failed (%s)\n", nt_errstr(status
));
1783 if (!torture_close_connection(cli
)) {
1787 printf("locktest2 finished\n");
1794 This test checks that
1796 1) the server supports the full offset range in lock requests
1798 static bool run_locktest3(int dummy
)
1800 static struct cli_state
*cli1
, *cli2
;
1801 const char *fname
= "\\lockt3.lck";
1802 uint16_t fnum1
, fnum2
;
1805 bool correct
= True
;
1808 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1810 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1813 cli_sockopt(cli1
, sockops
);
1814 cli_sockopt(cli2
, sockops
);
1816 printf("starting locktest3\n");
1818 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1820 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
1822 if (!NT_STATUS_IS_OK(status
)) {
1823 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
1827 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1828 if (!NT_STATUS_IS_OK(status
)) {
1829 printf("open2 of %s failed (%s)\n", fname
, nt_errstr(status
));
1833 for (offset
=i
=0;i
<torture_numops
;i
++) {
1836 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1837 if (!NT_STATUS_IS_OK(status
)) {
1838 printf("lock1 %d failed (%s)\n",
1844 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1845 if (!NT_STATUS_IS_OK(status
)) {
1846 printf("lock2 %d failed (%s)\n",
1853 for (offset
=i
=0;i
<torture_numops
;i
++) {
1856 status
= cli_lock32(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
);
1857 if (NT_STATUS_IS_OK(status
)) {
1858 printf("error: lock1 %d succeeded!\n", i
);
1862 status
= cli_lock32(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
);
1863 if (NT_STATUS_IS_OK(status
)) {
1864 printf("error: lock2 %d succeeded!\n", i
);
1868 status
= cli_lock32(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
);
1869 if (NT_STATUS_IS_OK(status
)) {
1870 printf("error: lock3 %d succeeded!\n", i
);
1874 status
= cli_lock32(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
);
1875 if (NT_STATUS_IS_OK(status
)) {
1876 printf("error: lock4 %d succeeded!\n", i
);
1881 for (offset
=i
=0;i
<torture_numops
;i
++) {
1884 status
= cli_unlock(cli1
, fnum1
, offset
-1, 1);
1885 if (!NT_STATUS_IS_OK(status
)) {
1886 printf("unlock1 %d failed (%s)\n",
1892 status
= cli_unlock(cli2
, fnum2
, offset
-2, 1);
1893 if (!NT_STATUS_IS_OK(status
)) {
1894 printf("unlock2 %d failed (%s)\n",
1901 status
= cli_close(cli1
, fnum1
);
1902 if (!NT_STATUS_IS_OK(status
)) {
1903 printf("close1 failed (%s)\n", nt_errstr(status
));
1907 status
= cli_close(cli2
, fnum2
);
1908 if (!NT_STATUS_IS_OK(status
)) {
1909 printf("close2 failed (%s)\n", nt_errstr(status
));
1913 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1914 if (!NT_STATUS_IS_OK(status
)) {
1915 printf("unlink failed (%s)\n", nt_errstr(status
));
1919 if (!torture_close_connection(cli1
)) {
1923 if (!torture_close_connection(cli2
)) {
1927 printf("finished locktest3\n");
1932 static bool test_cli_read(struct cli_state
*cli
, uint16_t fnum
,
1933 char *buf
, off_t offset
, size_t size
,
1934 size_t *nread
, size_t expect
)
1939 status
= cli_read(cli
, fnum
, buf
, offset
, size
, &l_nread
);
1941 if(!NT_STATUS_IS_OK(status
)) {
1943 } else if (l_nread
!= expect
) {
1954 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1955 printf("** "); correct = False; \
1959 looks at overlapping locks
1961 static bool run_locktest4(int dummy
)
1963 static struct cli_state
*cli1
, *cli2
;
1964 const char *fname
= "\\lockt4.lck";
1965 uint16_t fnum1
, fnum2
, f
;
1968 bool correct
= True
;
1971 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1975 cli_sockopt(cli1
, sockops
);
1976 cli_sockopt(cli2
, sockops
);
1978 printf("starting locktest4\n");
1980 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
1982 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1983 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1985 memset(buf
, 0, sizeof(buf
));
1987 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
1989 if (!NT_STATUS_IS_OK(status
)) {
1990 printf("Failed to create file: %s\n", nt_errstr(status
));
1995 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
1996 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
));
1997 EXPECTED(ret
, False
);
1998 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
2000 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 10, 4, 0, READ_LOCK
)) &&
2001 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 12, 4, 0, READ_LOCK
));
2002 EXPECTED(ret
, True
);
2003 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
2005 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
)) &&
2006 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
));
2007 EXPECTED(ret
, False
);
2008 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
2010 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 30, 4, 0, READ_LOCK
)) &&
2011 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 32, 4, 0, READ_LOCK
));
2012 EXPECTED(ret
, True
);
2013 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
2015 ret
= (cli_setpid(cli1
, 1),
2016 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
))) &&
2017 (cli_setpid(cli1
, 2),
2018 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
)));
2019 EXPECTED(ret
, False
);
2020 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
2022 ret
= (cli_setpid(cli1
, 1),
2023 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 50, 4, 0, READ_LOCK
))) &&
2024 (cli_setpid(cli1
, 2),
2025 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 52, 4, 0, READ_LOCK
)));
2026 EXPECTED(ret
, True
);
2027 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
2029 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
)) &&
2030 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 60, 4, 0, READ_LOCK
));
2031 EXPECTED(ret
, True
);
2032 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
2034 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
)) &&
2035 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
));
2036 EXPECTED(ret
, False
);
2037 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
2039 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, READ_LOCK
)) &&
2040 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
));
2041 EXPECTED(ret
, False
);
2042 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
2044 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
)) &&
2045 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 90, 4, 0, READ_LOCK
));
2046 EXPECTED(ret
, True
);
2047 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2049 ret
= (cli_setpid(cli1
, 1),
2050 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
))) &&
2051 (cli_setpid(cli1
, 2),
2052 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 100, 4, 0, READ_LOCK
)));
2053 EXPECTED(ret
, False
);
2054 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
2056 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 110, 4, 0, READ_LOCK
)) &&
2057 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 112, 4, 0, READ_LOCK
)) &&
2058 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
2059 EXPECTED(ret
, False
);
2060 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
2063 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
)) &&
2064 test_cli_read(cli2
, fnum2
, buf
, 120, 4, NULL
, 4);
2065 EXPECTED(ret
, False
);
2066 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
2068 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2069 ret
= NT_STATUS_IS_OK(status
);
2071 status
= cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
, 130, 4,
2073 ret
= NT_STATUS_IS_OK(status
);
2075 EXPECTED(ret
, False
);
2076 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
2079 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 140, 4, 0, READ_LOCK
)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
2082 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
2083 EXPECTED(ret
, True
);
2084 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
2087 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
)) &&
2088 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 150, 4, 0, READ_LOCK
)) &&
2089 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
2090 test_cli_read(cli2
, fnum2
, buf
, 150, 4, NULL
, 4) &&
2091 !(NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2093 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
2094 EXPECTED(ret
, True
);
2095 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
2097 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 160, 4, 0, READ_LOCK
)) &&
2098 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
2099 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2101 test_cli_read(cli2
, fnum2
, buf
, 160, 4, NULL
, 4);
2102 EXPECTED(ret
, True
);
2103 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
2105 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
)) &&
2106 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
2107 NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2109 test_cli_read(cli2
, fnum2
, buf
, 170, 4, NULL
, 4);
2110 EXPECTED(ret
, True
);
2111 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
2113 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
)) &&
2114 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 190, 4, 0, READ_LOCK
)) &&
2115 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
2116 !NT_STATUS_IS_OK(cli_writeall(cli2
, fnum2
, 0, (uint8_t *)buf
,
2118 test_cli_read(cli2
, fnum2
, buf
, 190, 4, NULL
, 4);
2119 EXPECTED(ret
, True
);
2120 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
2122 cli_close(cli1
, fnum1
);
2123 cli_close(cli2
, fnum2
);
2124 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2125 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
2126 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2127 NT_STATUS_IS_OK(cli_lock32(cli1
, f
, 0, 1, 0, READ_LOCK
)) &&
2128 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
2129 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
2130 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
));
2132 cli_close(cli1
, fnum1
);
2133 EXPECTED(ret
, True
);
2134 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
2137 cli_close(cli1
, fnum1
);
2138 cli_close(cli2
, fnum2
);
2139 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2140 torture_close_connection(cli1
);
2141 torture_close_connection(cli2
);
2143 printf("finished locktest4\n");
2148 looks at lock upgrade/downgrade.
2150 static bool run_locktest5(int dummy
)
2152 static struct cli_state
*cli1
, *cli2
;
2153 const char *fname
= "\\lockt5.lck";
2154 uint16_t fnum1
, fnum2
, fnum3
;
2157 bool correct
= True
;
2160 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2164 cli_sockopt(cli1
, sockops
);
2165 cli_sockopt(cli2
, sockops
);
2167 printf("starting locktest5\n");
2169 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2171 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2172 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
2173 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
2175 memset(buf
, 0, sizeof(buf
));
2177 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2179 if (!NT_STATUS_IS_OK(status
)) {
2180 printf("Failed to create file: %s\n", nt_errstr(status
));
2185 /* Check for NT bug... */
2186 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 8, 0, READ_LOCK
)) &&
2187 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum3
, 0, 1, 0, READ_LOCK
));
2188 cli_close(cli1
, fnum1
);
2189 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2190 status
= cli_lock32(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
2191 ret
= NT_STATUS_IS_OK(status
);
2192 EXPECTED(ret
, True
);
2193 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
2194 cli_close(cli1
, fnum1
);
2195 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2196 cli_unlock(cli1
, fnum3
, 0, 1);
2198 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) &&
2199 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 1, 1, 0, READ_LOCK
));
2200 EXPECTED(ret
, True
);
2201 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
2203 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
2204 ret
= NT_STATUS_IS_OK(status
);
2205 EXPECTED(ret
, False
);
2207 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
2209 /* Unlock the process 2 lock. */
2210 cli_unlock(cli2
, fnum2
, 0, 4);
2212 status
= cli_lock32(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
2213 ret
= NT_STATUS_IS_OK(status
);
2214 EXPECTED(ret
, False
);
2216 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
2218 /* Unlock the process 1 fnum3 lock. */
2219 cli_unlock(cli1
, fnum3
, 0, 4);
2221 /* Stack 2 more locks here. */
2222 ret
= NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) &&
2223 NT_STATUS_IS_OK(cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
));
2225 EXPECTED(ret
, True
);
2226 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
2228 /* Unlock the first process lock, then check this was the WRITE lock that was
2231 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2232 NT_STATUS_IS_OK(cli_lock32(cli2
, fnum2
, 0, 4, 0, READ_LOCK
));
2234 EXPECTED(ret
, True
);
2235 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
2237 /* Unlock the process 2 lock. */
2238 cli_unlock(cli2
, fnum2
, 0, 4);
2240 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2242 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
2243 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
2244 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2246 EXPECTED(ret
, True
);
2247 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
2249 /* Ensure the next unlock fails. */
2250 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
2251 EXPECTED(ret
, False
);
2252 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
2254 /* Ensure connection 2 can get a write lock. */
2255 status
= cli_lock32(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
2256 ret
= NT_STATUS_IS_OK(status
);
2257 EXPECTED(ret
, True
);
2259 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
2263 cli_close(cli1
, fnum1
);
2264 cli_close(cli2
, fnum2
);
2265 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2266 if (!torture_close_connection(cli1
)) {
2269 if (!torture_close_connection(cli2
)) {
2273 printf("finished locktest5\n");
2279 tries the unusual lockingX locktype bits
2281 static bool run_locktest6(int dummy
)
2283 static struct cli_state
*cli
;
2284 const char *fname
[1] = { "\\lock6.txt" };
2289 if (!torture_open_connection(&cli
, 0)) {
2293 cli_sockopt(cli
, sockops
);
2295 printf("starting locktest6\n");
2298 printf("Testing %s\n", fname
[i
]);
2300 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2302 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2303 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
2304 cli_close(cli
, fnum
);
2305 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
2307 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
2308 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
2309 cli_close(cli
, fnum
);
2310 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
2312 cli_unlink(cli
, fname
[i
], FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2315 torture_close_connection(cli
);
2317 printf("finished locktest6\n");
2321 static bool run_locktest7(int dummy
)
2323 struct cli_state
*cli1
;
2324 const char *fname
= "\\lockt7.lck";
2327 bool correct
= False
;
2331 if (!torture_open_connection(&cli1
, 0)) {
2335 cli_sockopt(cli1
, sockops
);
2337 printf("starting locktest7\n");
2339 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2341 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2343 memset(buf
, 0, sizeof(buf
));
2345 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, sizeof(buf
),
2347 if (!NT_STATUS_IS_OK(status
)) {
2348 printf("Failed to create file: %s\n", nt_errstr(status
));
2352 cli_setpid(cli1
, 1);
2354 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, READ_LOCK
);
2355 if (!NT_STATUS_IS_OK(status
)) {
2356 printf("Unable to apply read lock on range 130:4, "
2357 "error was %s\n", nt_errstr(status
));
2360 printf("pid1 successfully locked range 130:4 for READ\n");
2363 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2364 if (!NT_STATUS_IS_OK(status
)) {
2365 printf("pid1 unable to read the range 130:4, error was %s\n",
2368 } else if (nread
!= 4) {
2369 printf("pid1 unable to read the range 130:4, "
2370 "recv %ld req %d\n", (unsigned long)nread
, 4);
2373 printf("pid1 successfully read the range 130:4\n");
2376 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2377 if (!NT_STATUS_IS_OK(status
)) {
2378 printf("pid1 unable to write to the range 130:4, error was "
2379 "%s\n", nt_errstr(status
));
2380 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2381 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2385 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2389 cli_setpid(cli1
, 2);
2391 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2392 if (!NT_STATUS_IS_OK(status
)) {
2393 printf("pid2 unable to read the range 130:4, error was %s\n",
2396 } else if (nread
!= 4) {
2397 printf("pid2 unable to read the range 130:4, "
2398 "recv %ld req %d\n", (unsigned long)nread
, 4);
2401 printf("pid2 successfully read the range 130:4\n");
2404 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2405 if (!NT_STATUS_IS_OK(status
)) {
2406 printf("pid2 unable to write to the range 130:4, error was "
2407 "%s\n", nt_errstr(status
));
2408 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2409 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2413 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2417 cli_setpid(cli1
, 1);
2418 cli_unlock(cli1
, fnum1
, 130, 4);
2420 status
= cli_lock32(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
);
2421 if (!NT_STATUS_IS_OK(status
)) {
2422 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status
));
2425 printf("pid1 successfully locked range 130:4 for WRITE\n");
2428 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2429 if (!NT_STATUS_IS_OK(status
)) {
2430 printf("pid1 unable to read the range 130:4, error was %s\n",
2433 } else if (nread
!= 4) {
2434 printf("pid1 unable to read the range 130:4, "
2435 "recv %ld req %d\n", (unsigned long)nread
, 4);
2438 printf("pid1 successfully read the range 130:4\n");
2441 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2442 if (!NT_STATUS_IS_OK(status
)) {
2443 printf("pid1 unable to write to the range 130:4, error was "
2444 "%s\n", nt_errstr(status
));
2447 printf("pid1 successfully wrote to the range 130:4\n");
2450 cli_setpid(cli1
, 2);
2452 status
= cli_read(cli1
, fnum1
, buf
, 130, 4, &nread
);
2453 if (!NT_STATUS_IS_OK(status
)) {
2454 printf("pid2 unable to read the range 130:4, error was "
2455 "%s\n", nt_errstr(status
));
2456 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2457 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2461 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2462 (unsigned long)nread
);
2466 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 130, 4, NULL
);
2467 if (!NT_STATUS_IS_OK(status
)) {
2468 printf("pid2 unable to write to the range 130:4, error was "
2469 "%s\n", nt_errstr(status
));
2470 if (!NT_STATUS_EQUAL(status
, NT_STATUS_FILE_LOCK_CONFLICT
)) {
2471 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2475 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2479 cli_unlock(cli1
, fnum1
, 130, 0);
2483 cli_close(cli1
, fnum1
);
2484 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2485 torture_close_connection(cli1
);
2487 printf("finished locktest7\n");
2492 * This demonstrates a problem with our use of GPFS share modes: A file
2493 * descriptor sitting in the pending close queue holding a GPFS share mode
2494 * blocks opening a file another time. Happens with Word 2007 temp files.
2495 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2496 * open is denied with NT_STATUS_SHARING_VIOLATION.
2499 static bool run_locktest8(int dummy
)
2501 struct cli_state
*cli1
;
2502 const char *fname
= "\\lockt8.lck";
2503 uint16_t fnum1
, fnum2
;
2505 bool correct
= False
;
2508 if (!torture_open_connection(&cli1
, 0)) {
2512 cli_sockopt(cli1
, sockops
);
2514 printf("starting locktest8\n");
2516 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2518 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2520 if (!NT_STATUS_IS_OK(status
)) {
2521 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2525 memset(buf
, 0, sizeof(buf
));
2527 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2528 if (!NT_STATUS_IS_OK(status
)) {
2529 d_fprintf(stderr
, "cli_open second time returned %s\n",
2534 status
= cli_lock32(cli1
, fnum2
, 1, 1, 0, READ_LOCK
);
2535 if (!NT_STATUS_IS_OK(status
)) {
2536 printf("Unable to apply read lock on range 1:1, error was "
2537 "%s\n", nt_errstr(status
));
2541 status
= cli_close(cli1
, fnum1
);
2542 if (!NT_STATUS_IS_OK(status
)) {
2543 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2547 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2548 if (!NT_STATUS_IS_OK(status
)) {
2549 d_fprintf(stderr
, "cli_open third time returned %s\n",
2557 cli_close(cli1
, fnum1
);
2558 cli_close(cli1
, fnum2
);
2559 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2560 torture_close_connection(cli1
);
2562 printf("finished locktest8\n");
2567 * This test is designed to be run in conjunction with
2568 * external NFS or POSIX locks taken in the filesystem.
2569 * It checks that the smbd server will block until the
2570 * lock is released and then acquire it. JRA.
2573 static bool got_alarm
;
2574 static struct cli_state
*alarm_cli
;
2576 static void alarm_handler(int dummy
)
2581 static void alarm_handler_parent(int dummy
)
2583 cli_state_disconnect(alarm_cli
);
2586 static void do_local_lock(int read_fd
, int write_fd
)
2591 const char *local_pathname
= NULL
;
2594 local_pathname
= talloc_asprintf(talloc_tos(),
2595 "%s/lockt9.lck", local_path
);
2596 if (!local_pathname
) {
2597 printf("child: alloc fail\n");
2601 unlink(local_pathname
);
2602 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2604 printf("child: open of %s failed %s.\n",
2605 local_pathname
, strerror(errno
));
2609 /* Now take a fcntl lock. */
2610 lock
.l_type
= F_WRLCK
;
2611 lock
.l_whence
= SEEK_SET
;
2614 lock
.l_pid
= getpid();
2616 ret
= fcntl(fd
,F_SETLK
,&lock
);
2618 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2619 local_pathname
, strerror(errno
));
2622 printf("child: got lock 0:4 on file %s.\n",
2627 CatchSignal(SIGALRM
, alarm_handler
);
2629 /* Signal the parent. */
2630 if (write(write_fd
, &c
, 1) != 1) {
2631 printf("child: start signal fail %s.\n",
2638 /* Wait for the parent to be ready. */
2639 if (read(read_fd
, &c
, 1) != 1) {
2640 printf("child: reply signal fail %s.\n",
2648 printf("child: released lock 0:4 on file %s.\n",
2654 static bool run_locktest9(int dummy
)
2656 struct cli_state
*cli1
;
2657 const char *fname
= "\\lockt9.lck";
2659 bool correct
= False
;
2660 int pipe_in
[2], pipe_out
[2];
2664 struct timeval start
;
2668 printf("starting locktest9\n");
2670 if (local_path
== NULL
) {
2671 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2675 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2680 if (child_pid
== -1) {
2684 if (child_pid
== 0) {
2686 do_local_lock(pipe_out
[0], pipe_in
[1]);
2696 ret
= read(pipe_in
[0], &c
, 1);
2698 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2703 if (!torture_open_connection(&cli1
, 0)) {
2707 cli_sockopt(cli1
, sockops
);
2709 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2711 if (!NT_STATUS_IS_OK(status
)) {
2712 d_fprintf(stderr
, "cli_open returned %s\n", nt_errstr(status
));
2716 /* Ensure the child has the lock. */
2717 status
= cli_lock32(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
);
2718 if (NT_STATUS_IS_OK(status
)) {
2719 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2722 d_printf("Child has the lock.\n");
2725 /* Tell the child to wait 5 seconds then exit. */
2726 ret
= write(pipe_out
[1], &c
, 1);
2728 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2733 /* Wait 20 seconds for the lock. */
2735 CatchSignal(SIGALRM
, alarm_handler_parent
);
2738 start
= timeval_current();
2740 status
= cli_lock32(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
);
2741 if (!NT_STATUS_IS_OK(status
)) {
2742 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2743 "%s\n", nt_errstr(status
));
2748 seconds
= timeval_elapsed(&start
);
2750 printf("Parent got the lock after %.2f seconds.\n",
2753 status
= cli_close(cli1
, fnum
);
2754 if (!NT_STATUS_IS_OK(status
)) {
2755 d_fprintf(stderr
, "cli_close(fnum1) %s\n", nt_errstr(status
));
2762 cli_close(cli1
, fnum
);
2763 torture_close_connection(cli1
);
2767 printf("finished locktest9\n");
2772 test whether fnums and tids open on one VC are available on another (a major
2775 static bool run_fdpasstest(int dummy
)
2777 struct cli_state
*cli1
, *cli2
;
2778 const char *fname
= "\\fdpass.tst";
2783 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2786 cli_sockopt(cli1
, sockops
);
2787 cli_sockopt(cli2
, sockops
);
2789 printf("starting fdpasstest\n");
2791 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2793 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
2795 if (!NT_STATUS_IS_OK(status
)) {
2796 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2800 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"hello world\n", 0,
2802 if (!NT_STATUS_IS_OK(status
)) {
2803 printf("write failed (%s)\n", nt_errstr(status
));
2807 cli_state_set_uid(cli2
, cli_state_get_uid(cli1
));
2808 cli_state_set_tid(cli2
, cli_state_get_tid(cli1
));
2809 cli_setpid(cli2
, cli_getpid(cli1
));
2811 if (test_cli_read(cli2
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2812 printf("read succeeded! nasty security hole [%s]\n", buf
);
2816 cli_close(cli1
, fnum1
);
2817 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2819 torture_close_connection(cli1
);
2820 torture_close_connection(cli2
);
2822 printf("finished fdpasstest\n");
2826 static bool run_fdsesstest(int dummy
)
2828 struct cli_state
*cli
;
2833 const char *fname
= "\\fdsess.tst";
2834 const char *fname1
= "\\fdsess1.tst";
2841 if (!torture_open_connection(&cli
, 0))
2843 cli_sockopt(cli
, sockops
);
2845 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2848 saved_cnum
= cli_state_get_tid(cli
);
2849 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2851 new_cnum
= cli_state_get_tid(cli
);
2852 cli_state_set_tid(cli
, saved_cnum
);
2854 printf("starting fdsesstest\n");
2856 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2857 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2859 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
2860 if (!NT_STATUS_IS_OK(status
)) {
2861 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2865 status
= cli_writeall(cli
, fnum1
, 0, (const uint8_t *)"hello world\n", 0, 13,
2867 if (!NT_STATUS_IS_OK(status
)) {
2868 printf("write failed (%s)\n", nt_errstr(status
));
2872 saved_vuid
= cli_state_get_uid(cli
);
2873 cli_state_set_uid(cli
, new_vuid
);
2875 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2876 printf("read succeeded with different vuid! "
2877 "nasty security hole [%s]\n", buf
);
2880 /* Try to open a file with different vuid, samba cnum. */
2881 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2882 printf("create with different vuid, same cnum succeeded.\n");
2883 cli_close(cli
, fnum2
);
2884 cli_unlink(cli
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2886 printf("create with different vuid, same cnum failed.\n");
2887 printf("This will cause problems with service clients.\n");
2891 cli_state_set_uid(cli
, saved_vuid
);
2893 /* Try with same vuid, different cnum. */
2894 cli_state_set_tid(cli
, new_cnum
);
2896 if (test_cli_read(cli
, fnum1
, buf
, 0, 13, NULL
, 13)) {
2897 printf("read succeeded with different cnum![%s]\n", buf
);
2901 cli_state_set_tid(cli
, saved_cnum
);
2902 cli_close(cli
, fnum1
);
2903 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2905 torture_close_connection(cli
);
2907 printf("finished fdsesstest\n");
2912 This test checks that
2914 1) the server does not allow an unlink on a file that is open
2916 static bool run_unlinktest(int dummy
)
2918 struct cli_state
*cli
;
2919 const char *fname
= "\\unlink.tst";
2921 bool correct
= True
;
2924 if (!torture_open_connection(&cli
, 0)) {
2928 cli_sockopt(cli
, sockops
);
2930 printf("starting unlink test\n");
2932 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2936 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
2937 if (!NT_STATUS_IS_OK(status
)) {
2938 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
2942 status
= cli_unlink(cli
, fname
,
2943 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2944 if (NT_STATUS_IS_OK(status
)) {
2945 printf("error: server allowed unlink on an open file\n");
2948 correct
= check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
2949 NT_STATUS_SHARING_VIOLATION
);
2952 cli_close(cli
, fnum
);
2953 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
2955 if (!torture_close_connection(cli
)) {
2959 printf("unlink test finished\n");
2966 test how many open files this server supports on the one socket
2968 static bool run_maxfidtest(int dummy
)
2970 struct cli_state
*cli
;
2972 uint16_t fnums
[0x11000];
2975 bool correct
= True
;
2981 printf("failed to connect\n");
2985 cli_sockopt(cli
, sockops
);
2987 for (i
=0; i
<0x11000; i
++) {
2988 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
2989 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
,
2991 if (!NT_STATUS_IS_OK(status
)) {
2992 printf("open of %s failed (%s)\n",
2993 fname
, nt_errstr(status
));
2994 printf("maximum fnum is %d\n", i
);
3002 printf("cleaning up\n");
3004 slprintf(fname
,sizeof(fname
)-1,"\\maxfid.%d.%d", i
,(int)getpid());
3005 cli_close(cli
, fnums
[i
]);
3007 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3008 if (!NT_STATUS_IS_OK(status
)) {
3009 printf("unlink of %s failed (%s)\n",
3010 fname
, nt_errstr(status
));
3017 printf("maxfid test finished\n");
3018 if (!torture_close_connection(cli
)) {
3024 /* generate a random buffer */
3025 static void rand_buf(char *buf
, int len
)
3028 *buf
= (char)sys_random();
3033 /* send smb negprot commands, not reading the response */
3034 static bool run_negprot_nowait(int dummy
)
3036 struct tevent_context
*ev
;
3038 struct cli_state
*cli
;
3039 bool correct
= True
;
3041 printf("starting negprot nowait test\n");
3043 ev
= tevent_context_init(talloc_tos());
3048 if (!(cli
= open_nbt_connection())) {
3053 for (i
=0;i
<50000;i
++) {
3054 struct tevent_req
*req
;
3056 req
= cli_negprot_send(ev
, ev
, cli
, PROTOCOL_NT1
);
3061 if (!tevent_req_poll(req
, ev
)) {
3062 d_fprintf(stderr
, "tevent_req_poll failed: %s\n",
3070 if (torture_close_connection(cli
)) {
3074 printf("finished negprot nowait test\n");
3079 /* send smb negprot commands, not reading the response */
3080 static bool run_bad_nbt_session(int dummy
)
3082 struct nmb_name called
, calling
;
3083 struct sockaddr_storage ss
;
3088 printf("starting bad nbt session test\n");
3090 make_nmb_name(&calling
, myname
, 0x0);
3091 make_nmb_name(&called
, host
, 0x20);
3093 if (!resolve_name(host
, &ss
, 0x20, true)) {
3094 d_fprintf(stderr
, "Could not resolve name %s\n", host
);
3098 status
= open_socket_out(&ss
, 139, 10000, &fd
);
3099 if (!NT_STATUS_IS_OK(status
)) {
3100 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3105 ret
= cli_bad_session_request(fd
, &calling
, &called
);
3108 d_fprintf(stderr
, "open_socket_out failed: %s\n",
3113 printf("finished bad nbt session test\n");
3117 /* send random IPC commands */
3118 static bool run_randomipc(int dummy
)
3120 char *rparam
= NULL
;
3122 unsigned int rdrcnt
,rprcnt
;
3124 int api
, param_len
, i
;
3125 struct cli_state
*cli
;
3126 bool correct
= True
;
3129 printf("starting random ipc test\n");
3131 if (!torture_open_connection(&cli
, 0)) {
3135 for (i
=0;i
<count
;i
++) {
3136 api
= sys_random() % 500;
3137 param_len
= (sys_random() % 64);
3139 rand_buf(param
, param_len
);
3144 param
, param_len
, 8,
3145 NULL
, 0, BUFFER_SIZE
,
3149 printf("%d/%d\r", i
,count
);
3152 printf("%d/%d\n", i
, count
);
3154 if (!torture_close_connection(cli
)) {
3158 printf("finished random ipc test\n");
3165 static void browse_callback(const char *sname
, uint32 stype
,
3166 const char *comment
, void *state
)
3168 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3174 This test checks the browse list code
3177 static bool run_browsetest(int dummy
)
3179 static struct cli_state
*cli
;
3180 bool correct
= True
;
3182 printf("starting browse test\n");
3184 if (!torture_open_connection(&cli
, 0)) {
3188 printf("domain list:\n");
3189 cli_NetServerEnum(cli
, cli
->server_domain
,
3190 SV_TYPE_DOMAIN_ENUM
,
3191 browse_callback
, NULL
);
3193 printf("machine list:\n");
3194 cli_NetServerEnum(cli
, cli
->server_domain
,
3196 browse_callback
, NULL
);
3198 if (!torture_close_connection(cli
)) {
3202 printf("browse test finished\n");
3210 This checks how the getatr calls works
3212 static bool run_attrtest(int dummy
)
3214 struct cli_state
*cli
;
3217 const char *fname
= "\\attrib123456789.tst";
3218 bool correct
= True
;
3221 printf("starting attrib test\n");
3223 if (!torture_open_connection(&cli
, 0)) {
3227 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3228 cli_open(cli
, fname
,
3229 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3230 cli_close(cli
, fnum
);
3232 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3233 if (!NT_STATUS_IS_OK(status
)) {
3234 printf("getatr failed (%s)\n", nt_errstr(status
));
3238 if (abs(t
- time(NULL
)) > 60*60*24*10) {
3239 printf("ERROR: SMBgetatr bug. time is %s",
3245 t2
= t
-60*60*24; /* 1 day ago */
3247 status
= cli_setatr(cli
, fname
, 0, t2
);
3248 if (!NT_STATUS_IS_OK(status
)) {
3249 printf("setatr failed (%s)\n", nt_errstr(status
));
3253 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
3254 if (!NT_STATUS_IS_OK(status
)) {
3255 printf("getatr failed (%s)\n", nt_errstr(status
));
3260 printf("ERROR: getatr/setatr bug. times are\n%s",
3262 printf("%s", ctime(&t2
));
3266 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3268 if (!torture_close_connection(cli
)) {
3272 printf("attrib test finished\n");
3279 This checks a couple of trans2 calls
3281 static bool run_trans2test(int dummy
)
3283 struct cli_state
*cli
;
3286 time_t c_time
, a_time
, m_time
;
3287 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
3288 const char *fname
= "\\trans2.tst";
3289 const char *dname
= "\\trans2";
3290 const char *fname2
= "\\trans2\\trans2.tst";
3292 bool correct
= True
;
3296 printf("starting trans2 test\n");
3298 if (!torture_open_connection(&cli
, 0)) {
3302 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
3303 if (!NT_STATUS_IS_OK(status
)) {
3304 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3309 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3310 cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3311 status
= cli_qfileinfo_basic(cli
, fnum
, NULL
, &size
, &c_time_ts
,
3312 &a_time_ts
, &w_time_ts
, &m_time_ts
, NULL
);
3313 if (!NT_STATUS_IS_OK(status
)) {
3314 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status
));
3318 status
= cli_qfilename(cli
, fnum
, talloc_tos(), &pname
);
3319 if (!NT_STATUS_IS_OK(status
)) {
3320 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status
));
3324 if (strcmp(pname
, fname
)) {
3325 printf("qfilename gave different name? [%s] [%s]\n",
3330 cli_close(cli
, fnum
);
3334 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3335 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
,
3337 if (!NT_STATUS_IS_OK(status
)) {
3338 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3341 cli_close(cli
, fnum
);
3343 status
= cli_qpathinfo1(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
,
3345 if (!NT_STATUS_IS_OK(status
)) {
3346 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status
));
3349 time_t t
= time(NULL
);
3351 if (c_time
!= m_time
) {
3352 printf("create time=%s", ctime(&c_time
));
3353 printf("modify time=%s", ctime(&m_time
));
3354 printf("This system appears to have sticky create times\n");
3356 if ((abs(a_time
- t
) > 60) && (a_time
% (60*60) == 0)) {
3357 printf("access time=%s", ctime(&a_time
));
3358 printf("This system appears to set a midnight access time\n");
3362 if (abs(m_time
- t
) > 60*60*24*7) {
3363 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
3369 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3370 cli_open(cli
, fname
,
3371 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3372 cli_close(cli
, fnum
);
3373 status
= cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
3374 &m_time_ts
, &size
, NULL
, NULL
);
3375 if (!NT_STATUS_IS_OK(status
)) {
3376 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3379 if (w_time_ts
.tv_sec
< 60*60*24*2) {
3380 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
3381 printf("This system appears to set a initial 0 write time\n");
3386 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3389 /* check if the server updates the directory modification time
3390 when creating a new file */
3391 status
= cli_mkdir(cli
, dname
);
3392 if (!NT_STATUS_IS_OK(status
)) {
3393 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status
));
3397 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3398 &w_time_ts
, &m_time_ts
, &size
, NULL
, NULL
);
3399 if (!NT_STATUS_IS_OK(status
)) {
3400 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3404 cli_open(cli
, fname2
,
3405 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
3406 cli_writeall(cli
, fnum
, 0, (uint8_t *)&fnum
, 0, sizeof(fnum
), NULL
);
3407 cli_close(cli
, fnum
);
3408 status
= cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
,
3409 &w_time_ts
, &m_time2_ts
, &size
, NULL
, NULL
);
3410 if (!NT_STATUS_IS_OK(status
)) {
3411 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status
));
3414 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
3416 printf("This system does not update directory modification times\n");
3420 cli_unlink(cli
, fname2
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3421 cli_rmdir(cli
, dname
);
3423 if (!torture_close_connection(cli
)) {
3427 printf("trans2 test finished\n");
3433 This checks new W2K calls.
3436 static NTSTATUS
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3438 uint8_t *buf
= NULL
;
3442 status
= cli_qfileinfo(talloc_tos(), pcli
, fnum
, level
, 0,
3443 CLI_BUFFER_SIZE
, NULL
, &buf
, &len
);
3444 if (!NT_STATUS_IS_OK(status
)) {
3445 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
,
3448 printf("qfileinfo: level %d, len = %u\n", level
, len
);
3449 dump_data(0, (uint8
*)buf
, len
);
3456 static bool run_w2ktest(int dummy
)
3458 struct cli_state
*cli
;
3460 const char *fname
= "\\w2ktest\\w2k.tst";
3462 bool correct
= True
;
3464 printf("starting w2k test\n");
3466 if (!torture_open_connection(&cli
, 0)) {
3470 cli_open(cli
, fname
,
3471 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
3473 for (level
= 1004; level
< 1040; level
++) {
3474 new_trans(cli
, fnum
, level
);
3477 cli_close(cli
, fnum
);
3479 if (!torture_close_connection(cli
)) {
3483 printf("w2k test finished\n");
3490 this is a harness for some oplock tests
3492 static bool run_oplock1(int dummy
)
3494 struct cli_state
*cli1
;
3495 const char *fname
= "\\lockt1.lck";
3497 bool correct
= True
;
3500 printf("starting oplock test 1\n");
3502 if (!torture_open_connection(&cli1
, 0)) {
3506 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3508 cli_sockopt(cli1
, sockops
);
3510 cli1
->use_oplocks
= True
;
3512 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3514 if (!NT_STATUS_IS_OK(status
)) {
3515 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3519 cli1
->use_oplocks
= False
;
3521 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3522 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3524 status
= cli_close(cli1
, fnum1
);
3525 if (!NT_STATUS_IS_OK(status
)) {
3526 printf("close2 failed (%s)\n", nt_errstr(status
));
3530 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3531 if (!NT_STATUS_IS_OK(status
)) {
3532 printf("unlink failed (%s)\n", nt_errstr(status
));
3536 if (!torture_close_connection(cli1
)) {
3540 printf("finished oplock test 1\n");
3545 static bool run_oplock2(int dummy
)
3547 struct cli_state
*cli1
, *cli2
;
3548 const char *fname
= "\\lockt2.lck";
3549 uint16_t fnum1
, fnum2
;
3550 int saved_use_oplocks
= use_oplocks
;
3552 bool correct
= True
;
3553 volatile bool *shared_correct
;
3557 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3558 *shared_correct
= True
;
3560 use_level_II_oplocks
= True
;
3563 printf("starting oplock test 2\n");
3565 if (!torture_open_connection(&cli1
, 0)) {
3566 use_level_II_oplocks
= False
;
3567 use_oplocks
= saved_use_oplocks
;
3571 if (!torture_open_connection(&cli2
, 1)) {
3572 use_level_II_oplocks
= False
;
3573 use_oplocks
= saved_use_oplocks
;
3577 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3579 cli_sockopt(cli1
, sockops
);
3580 cli_sockopt(cli2
, sockops
);
3582 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3584 if (!NT_STATUS_IS_OK(status
)) {
3585 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3589 /* Don't need the globals any more. */
3590 use_level_II_oplocks
= False
;
3591 use_oplocks
= saved_use_oplocks
;
3595 status
= cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
3596 if (!NT_STATUS_IS_OK(status
)) {
3597 printf("second open of %s failed (%s)\n", fname
, nt_errstr(status
));
3598 *shared_correct
= False
;
3604 status
= cli_close(cli2
, fnum2
);
3605 if (!NT_STATUS_IS_OK(status
)) {
3606 printf("close2 failed (%s)\n", nt_errstr(status
));
3607 *shared_correct
= False
;
3615 /* Ensure cli1 processes the break. Empty file should always return 0
3617 status
= cli_read(cli1
, fnum1
, buf
, 0, 4, &nread
);
3618 if (!NT_STATUS_IS_OK(status
)) {
3619 printf("read on fnum1 failed (%s)\n", nt_errstr(status
));
3621 } else if (nread
!= 0) {
3622 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3623 (unsigned long)nread
, 0);
3627 /* Should now be at level II. */
3628 /* Test if sending a write locks causes a break to none. */
3629 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
3630 if (!NT_STATUS_IS_OK(status
)) {
3631 printf("lock failed (%s)\n", nt_errstr(status
));
3635 cli_unlock(cli1
, fnum1
, 0, 4);
3639 status
= cli_lock32(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
);
3640 if (!NT_STATUS_IS_OK(status
)) {
3641 printf("lock failed (%s)\n", nt_errstr(status
));
3645 cli_unlock(cli1
, fnum1
, 0, 4);
3649 cli_read(cli1
, fnum1
, buf
, 0, 4, NULL
);
3651 status
= cli_close(cli1
, fnum1
);
3652 if (!NT_STATUS_IS_OK(status
)) {
3653 printf("close1 failed (%s)\n", nt_errstr(status
));
3659 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3660 if (!NT_STATUS_IS_OK(status
)) {
3661 printf("unlink failed (%s)\n", nt_errstr(status
));
3665 if (!torture_close_connection(cli1
)) {
3669 if (!*shared_correct
) {
3673 printf("finished oplock test 2\n");
3678 struct oplock4_state
{
3679 struct tevent_context
*ev
;
3680 struct cli_state
*cli
;
3685 static void oplock4_got_break(struct tevent_req
*req
);
3686 static void oplock4_got_open(struct tevent_req
*req
);
3688 static bool run_oplock4(int dummy
)
3690 struct tevent_context
*ev
;
3691 struct cli_state
*cli1
, *cli2
;
3692 struct tevent_req
*oplock_req
, *open_req
;
3693 const char *fname
= "\\lockt4.lck";
3694 const char *fname_ln
= "\\lockt4_ln.lck";
3695 uint16_t fnum1
, fnum2
;
3696 int saved_use_oplocks
= use_oplocks
;
3698 bool correct
= true;
3702 struct oplock4_state
*state
;
3704 printf("starting oplock test 4\n");
3706 if (!torture_open_connection(&cli1
, 0)) {
3707 use_level_II_oplocks
= false;
3708 use_oplocks
= saved_use_oplocks
;
3712 if (!torture_open_connection(&cli2
, 1)) {
3713 use_level_II_oplocks
= false;
3714 use_oplocks
= saved_use_oplocks
;
3718 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3719 cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3721 cli_sockopt(cli1
, sockops
);
3722 cli_sockopt(cli2
, sockops
);
3724 /* Create the file. */
3725 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
,
3727 if (!NT_STATUS_IS_OK(status
)) {
3728 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3732 status
= cli_close(cli1
, fnum1
);
3733 if (!NT_STATUS_IS_OK(status
)) {
3734 printf("close1 failed (%s)\n", nt_errstr(status
));
3738 /* Now create a hardlink. */
3739 status
= cli_nt_hardlink(cli1
, fname
, fname_ln
);
3740 if (!NT_STATUS_IS_OK(status
)) {
3741 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
3745 /* Prove that opening hardlinks cause deny modes to conflict. */
3746 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum1
);
3747 if (!NT_STATUS_IS_OK(status
)) {
3748 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3752 status
= cli_open(cli1
, fname_ln
, O_RDWR
, DENY_NONE
, &fnum2
);
3753 if (NT_STATUS_IS_OK(status
)) {
3754 printf("open of %s succeeded - should fail with sharing violation.\n",
3759 if (!NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
3760 printf("open of %s should fail with sharing violation. Got %s\n",
3761 fname_ln
, nt_errstr(status
));
3765 status
= cli_close(cli1
, fnum1
);
3766 if (!NT_STATUS_IS_OK(status
)) {
3767 printf("close1 failed (%s)\n", nt_errstr(status
));
3771 cli1
->use_oplocks
= true;
3772 cli2
->use_oplocks
= true;
3774 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
3775 if (!NT_STATUS_IS_OK(status
)) {
3776 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
3780 ev
= tevent_context_init(talloc_tos());
3782 printf("tevent_req_create failed\n");
3786 state
= talloc(ev
, struct oplock4_state
);
3787 if (state
== NULL
) {
3788 printf("talloc failed\n");
3793 state
->got_break
= &got_break
;
3794 state
->fnum2
= &fnum2
;
3796 oplock_req
= cli_smb_oplock_break_waiter_send(
3797 talloc_tos(), ev
, cli1
);
3798 if (oplock_req
== NULL
) {
3799 printf("cli_smb_oplock_break_waiter_send failed\n");
3802 tevent_req_set_callback(oplock_req
, oplock4_got_break
, state
);
3804 open_req
= cli_open_send(
3805 talloc_tos(), ev
, cli2
, fname_ln
, O_RDWR
, DENY_NONE
);
3806 if (oplock_req
== NULL
) {
3807 printf("cli_open_send failed\n");
3810 tevent_req_set_callback(open_req
, oplock4_got_open
, state
);
3815 while (!got_break
|| fnum2
== 0xffff) {
3817 ret
= tevent_loop_once(ev
);
3819 printf("tevent_loop_once failed: %s\n",
3825 status
= cli_close(cli2
, fnum2
);
3826 if (!NT_STATUS_IS_OK(status
)) {
3827 printf("close2 failed (%s)\n", nt_errstr(status
));
3831 status
= cli_close(cli1
, fnum1
);
3832 if (!NT_STATUS_IS_OK(status
)) {
3833 printf("close1 failed (%s)\n", nt_errstr(status
));
3837 status
= cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3838 if (!NT_STATUS_IS_OK(status
)) {
3839 printf("unlink failed (%s)\n", nt_errstr(status
));
3843 status
= cli_unlink(cli1
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3844 if (!NT_STATUS_IS_OK(status
)) {
3845 printf("unlink failed (%s)\n", nt_errstr(status
));
3849 if (!torture_close_connection(cli1
)) {
3857 printf("finished oplock test 4\n");
3862 static void oplock4_got_break(struct tevent_req
*req
)
3864 struct oplock4_state
*state
= tevent_req_callback_data(
3865 req
, struct oplock4_state
);
3870 status
= cli_smb_oplock_break_waiter_recv(req
, &fnum
, &level
);
3872 if (!NT_STATUS_IS_OK(status
)) {
3873 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3877 *state
->got_break
= true;
3879 req
= cli_oplock_ack_send(state
, state
->ev
, state
->cli
, fnum
,
3882 printf("cli_oplock_ack_send failed\n");
3887 static void oplock4_got_open(struct tevent_req
*req
)
3889 struct oplock4_state
*state
= tevent_req_callback_data(
3890 req
, struct oplock4_state
);
3893 status
= cli_open_recv(req
, state
->fnum2
);
3894 if (!NT_STATUS_IS_OK(status
)) {
3895 printf("cli_open_recv returned %s\n", nt_errstr(status
));
3896 *state
->fnum2
= 0xffff;
3901 Test delete on close semantics.
3903 static bool run_deletetest(int dummy
)
3905 struct cli_state
*cli1
= NULL
;
3906 struct cli_state
*cli2
= NULL
;
3907 const char *fname
= "\\delete.file";
3908 uint16_t fnum1
= (uint16_t)-1;
3909 uint16_t fnum2
= (uint16_t)-1;
3910 bool correct
= True
;
3913 printf("starting delete test\n");
3915 if (!torture_open_connection(&cli1
, 0)) {
3919 cli_sockopt(cli1
, sockops
);
3921 /* Test 1 - this should delete the file on close. */
3923 cli_setatr(cli1
, fname
, 0, 0);
3924 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3926 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
3927 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
3928 FILE_DELETE_ON_CLOSE
, 0, &fnum1
);
3929 if (!NT_STATUS_IS_OK(status
)) {
3930 printf("[1] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3935 status
= cli_close(cli1
, fnum1
);
3936 if (!NT_STATUS_IS_OK(status
)) {
3937 printf("[1] close failed (%s)\n", nt_errstr(status
));
3942 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3943 printf("[1] open of %s succeeded (should fail)\n", fname
);
3948 printf("first delete on close test succeeded.\n");
3950 /* Test 2 - this should delete the file on close. */
3952 cli_setatr(cli1
, fname
, 0, 0);
3953 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3955 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3956 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3957 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3958 if (!NT_STATUS_IS_OK(status
)) {
3959 printf("[2] open of %s failed (%s)\n", fname
, nt_errstr(status
));
3964 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
3965 if (!NT_STATUS_IS_OK(status
)) {
3966 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status
));
3971 status
= cli_close(cli1
, fnum1
);
3972 if (!NT_STATUS_IS_OK(status
)) {
3973 printf("[2] close failed (%s)\n", nt_errstr(status
));
3978 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3979 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3980 status
= cli_close(cli1
, fnum1
);
3981 if (!NT_STATUS_IS_OK(status
)) {
3982 printf("[2] close failed (%s)\n", nt_errstr(status
));
3986 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3988 printf("second delete on close test succeeded.\n");
3991 cli_setatr(cli1
, fname
, 0, 0);
3992 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
3994 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3995 FILE_ATTRIBUTE_NORMAL
,
3996 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3997 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3998 if (!NT_STATUS_IS_OK(status
)) {
3999 printf("[3] open - 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4004 /* This should fail with a sharing violation - open for delete is only compatible
4005 with SHARE_DELETE. */
4007 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4008 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
4009 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4014 /* This should succeed. */
4015 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4016 FILE_ATTRIBUTE_NORMAL
,
4017 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4018 FILE_OPEN
, 0, 0, &fnum2
);
4019 if (!NT_STATUS_IS_OK(status
)) {
4020 printf("[3] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4025 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4026 if (!NT_STATUS_IS_OK(status
)) {
4027 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4032 status
= cli_close(cli1
, fnum1
);
4033 if (!NT_STATUS_IS_OK(status
)) {
4034 printf("[3] close 1 failed (%s)\n", nt_errstr(status
));
4039 status
= cli_close(cli1
, fnum2
);
4040 if (!NT_STATUS_IS_OK(status
)) {
4041 printf("[3] close 2 failed (%s)\n", nt_errstr(status
));
4046 /* This should fail - file should no longer be there. */
4048 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4049 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4050 status
= cli_close(cli1
, fnum1
);
4051 if (!NT_STATUS_IS_OK(status
)) {
4052 printf("[3] close failed (%s)\n", nt_errstr(status
));
4054 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4058 printf("third delete on close test succeeded.\n");
4061 cli_setatr(cli1
, fname
, 0, 0);
4062 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4064 status
= cli_ntcreate(cli1
, fname
, 0,
4065 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4066 FILE_ATTRIBUTE_NORMAL
,
4067 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4068 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4069 if (!NT_STATUS_IS_OK(status
)) {
4070 printf("[4] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4075 /* This should succeed. */
4076 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4077 FILE_ATTRIBUTE_NORMAL
,
4078 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4079 FILE_OPEN
, 0, 0, &fnum2
);
4080 if (!NT_STATUS_IS_OK(status
)) {
4081 printf("[4] open - 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4086 status
= cli_close(cli1
, fnum2
);
4087 if (!NT_STATUS_IS_OK(status
)) {
4088 printf("[4] close - 1 failed (%s)\n", nt_errstr(status
));
4093 status
= cli_nt_delete_on_close(cli1
, fnum1
, true);
4094 if (!NT_STATUS_IS_OK(status
)) {
4095 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status
));
4100 /* This should fail - no more opens once delete on close set. */
4101 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4102 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4103 FILE_OPEN
, 0, 0, &fnum2
))) {
4104 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4108 printf("fourth delete on close test succeeded.\n");
4110 status
= cli_close(cli1
, fnum1
);
4111 if (!NT_STATUS_IS_OK(status
)) {
4112 printf("[4] close - 2 failed (%s)\n", nt_errstr(status
));
4118 cli_setatr(cli1
, fname
, 0, 0);
4119 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4121 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
);
4122 if (!NT_STATUS_IS_OK(status
)) {
4123 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4128 /* This should fail - only allowed on NT opens with DELETE access. */
4130 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4131 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4136 status
= cli_close(cli1
, fnum1
);
4137 if (!NT_STATUS_IS_OK(status
)) {
4138 printf("[5] close - 2 failed (%s)\n", nt_errstr(status
));
4143 printf("fifth delete on close test succeeded.\n");
4146 cli_setatr(cli1
, fname
, 0, 0);
4147 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4149 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4150 FILE_ATTRIBUTE_NORMAL
,
4151 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4152 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4153 if (!NT_STATUS_IS_OK(status
)) {
4154 printf("[6] open of %s failed (%s)\n", fname
,
4160 /* This should fail - only allowed on NT opens with DELETE access. */
4162 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4163 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4168 status
= cli_close(cli1
, fnum1
);
4169 if (!NT_STATUS_IS_OK(status
)) {
4170 printf("[6] close - 2 failed (%s)\n", nt_errstr(status
));
4175 printf("sixth delete on close test succeeded.\n");
4178 cli_setatr(cli1
, fname
, 0, 0);
4179 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4181 status
= cli_ntcreate(cli1
, fname
, 0,
4182 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4183 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
4185 if (!NT_STATUS_IS_OK(status
)) {
4186 printf("[7] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4191 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4192 printf("[7] setting delete_on_close on file failed !\n");
4197 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
4198 printf("[7] unsetting delete_on_close on file failed !\n");
4203 status
= cli_close(cli1
, fnum1
);
4204 if (!NT_STATUS_IS_OK(status
)) {
4205 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4210 /* This next open should succeed - we reset the flag. */
4211 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4212 if (!NT_STATUS_IS_OK(status
)) {
4213 printf("[5] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4218 status
= cli_close(cli1
, fnum1
);
4219 if (!NT_STATUS_IS_OK(status
)) {
4220 printf("[7] close - 2 failed (%s)\n", nt_errstr(status
));
4225 printf("seventh delete on close test succeeded.\n");
4228 cli_setatr(cli1
, fname
, 0, 0);
4229 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4231 if (!torture_open_connection(&cli2
, 1)) {
4232 printf("[8] failed to open second connection.\n");
4237 cli_sockopt(cli1
, sockops
);
4239 status
= cli_ntcreate(cli1
, fname
, 0,
4240 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4241 FILE_ATTRIBUTE_NORMAL
,
4242 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4243 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4244 if (!NT_STATUS_IS_OK(status
)) {
4245 printf("[8] open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
4250 status
= cli_ntcreate(cli2
, fname
, 0,
4251 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4252 FILE_ATTRIBUTE_NORMAL
,
4253 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4254 FILE_OPEN
, 0, 0, &fnum2
);
4255 if (!NT_STATUS_IS_OK(status
)) {
4256 printf("[8] open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
4261 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
4262 printf("[8] setting delete_on_close on file failed !\n");
4267 status
= cli_close(cli1
, fnum1
);
4268 if (!NT_STATUS_IS_OK(status
)) {
4269 printf("[8] close - 1 failed (%s)\n", nt_errstr(status
));
4274 status
= cli_close(cli2
, fnum2
);
4275 if (!NT_STATUS_IS_OK(status
)) {
4276 printf("[8] close - 2 failed (%s)\n", nt_errstr(status
));
4281 /* This should fail.. */
4282 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
);
4283 if (NT_STATUS_IS_OK(status
)) {
4284 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4288 printf("eighth delete on close test succeeded.\n");
4290 /* This should fail - we need to set DELETE_ACCESS. */
4291 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
4292 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
4293 printf("[9] open of %s succeeded should have failed!\n", fname
);
4298 printf("ninth delete on close test succeeded.\n");
4300 status
= cli_ntcreate(cli1
, fname
, 0,
4301 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4302 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4303 FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
,
4305 if (!NT_STATUS_IS_OK(status
)) {
4306 printf("[10] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4311 /* This should delete the file. */
4312 status
= cli_close(cli1
, fnum1
);
4313 if (!NT_STATUS_IS_OK(status
)) {
4314 printf("[10] close failed (%s)\n", nt_errstr(status
));
4319 /* This should fail.. */
4320 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
4321 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
4325 printf("tenth delete on close test succeeded.\n");
4327 cli_setatr(cli1
, fname
, 0, 0);
4328 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4330 /* What error do we get when attempting to open a read-only file with
4333 /* Create a readonly file. */
4334 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
4335 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
,
4336 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4337 if (!NT_STATUS_IS_OK(status
)) {
4338 printf("[11] open of %s failed (%s)\n", fname
, nt_errstr(status
));
4343 status
= cli_close(cli1
, fnum1
);
4344 if (!NT_STATUS_IS_OK(status
)) {
4345 printf("[11] close failed (%s)\n", nt_errstr(status
));
4350 /* Now try open for delete access. */
4351 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
4352 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4353 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4354 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
4355 cli_close(cli1
, fnum1
);
4359 NTSTATUS nterr
= cli_nt_error(cli1
);
4360 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
4361 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
4365 printf("eleventh delete on close test succeeded.\n");
4369 printf("finished delete test\n");
4372 /* FIXME: This will crash if we aborted before cli2 got
4373 * intialized, because these functions don't handle
4374 * uninitialized connections. */
4376 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
4377 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
4378 cli_setatr(cli1
, fname
, 0, 0);
4379 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4381 if (cli1
&& !torture_close_connection(cli1
)) {
4384 if (cli2
&& !torture_close_connection(cli2
)) {
4390 static bool run_deletetest_ln(int dummy
)
4392 struct cli_state
*cli
;
4393 const char *fname
= "\\delete1";
4394 const char *fname_ln
= "\\delete1_ln";
4398 bool correct
= true;
4401 printf("starting deletetest-ln\n");
4403 if (!torture_open_connection(&cli
, 0)) {
4407 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4408 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4410 cli_sockopt(cli
, sockops
);
4412 /* Create the file. */
4413 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
4414 if (!NT_STATUS_IS_OK(status
)) {
4415 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4419 status
= cli_close(cli
, fnum
);
4420 if (!NT_STATUS_IS_OK(status
)) {
4421 printf("close1 failed (%s)\n", nt_errstr(status
));
4425 /* Now create a hardlink. */
4426 status
= cli_nt_hardlink(cli
, fname
, fname_ln
);
4427 if (!NT_STATUS_IS_OK(status
)) {
4428 printf("nt hardlink failed (%s)\n", nt_errstr(status
));
4432 /* Open the original file. */
4433 status
= cli_ntcreate(cli
, fname
, 0, FILE_READ_DATA
,
4434 FILE_ATTRIBUTE_NORMAL
,
4435 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4436 FILE_OPEN_IF
, 0, 0, &fnum
);
4437 if (!NT_STATUS_IS_OK(status
)) {
4438 printf("ntcreate of %s failed (%s)\n", fname
, nt_errstr(status
));
4442 /* Unlink the hard link path. */
4443 status
= cli_ntcreate(cli
, fname_ln
, 0, DELETE_ACCESS
,
4444 FILE_ATTRIBUTE_NORMAL
,
4445 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4446 FILE_OPEN_IF
, 0, 0, &fnum1
);
4447 if (!NT_STATUS_IS_OK(status
)) {
4448 printf("ntcreate of %s failed (%s)\n", fname_ln
, nt_errstr(status
));
4451 status
= cli_nt_delete_on_close(cli
, fnum1
, true);
4452 if (!NT_STATUS_IS_OK(status
)) {
4453 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4454 __location__
, fname_ln
, nt_errstr(status
));
4458 status
= cli_close(cli
, fnum1
);
4459 if (!NT_STATUS_IS_OK(status
)) {
4460 printf("close %s failed (%s)\n",
4461 fname_ln
, nt_errstr(status
));
4465 status
= cli_close(cli
, fnum
);
4466 if (!NT_STATUS_IS_OK(status
)) {
4467 printf("close %s failed (%s)\n",
4468 fname
, nt_errstr(status
));
4472 /* Ensure the original file is still there. */
4473 status
= cli_getatr(cli
, fname
, NULL
, NULL
, &t
);
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 printf("%s getatr on file %s failed (%s)\n",
4482 /* Ensure the link path is gone. */
4483 status
= cli_getatr(cli
, fname_ln
, NULL
, NULL
, &t
);
4484 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4485 printf("%s, getatr for file %s returned wrong error code %s "
4486 "- should have been deleted\n",
4488 fname_ln
, nt_errstr(status
));
4492 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4493 cli_unlink(cli
, fname_ln
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4495 if (!torture_close_connection(cli
)) {
4499 printf("finished deletetest-ln\n");
4505 print out server properties
4507 static bool run_properties(int dummy
)
4509 struct cli_state
*cli
;
4510 bool correct
= True
;
4512 printf("starting properties test\n");
4516 if (!torture_open_connection(&cli
, 0)) {
4520 cli_sockopt(cli
, sockops
);
4522 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli
));
4524 if (!torture_close_connection(cli
)) {
4533 /* FIRST_DESIRED_ACCESS 0xf019f */
4534 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4535 FILE_READ_EA| /* 0xf */ \
4536 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4537 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4538 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4539 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4540 /* SECOND_DESIRED_ACCESS 0xe0080 */
4541 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4542 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4543 WRITE_OWNER_ACCESS /* 0xe0000 */
4546 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4547 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4549 WRITE_OWNER_ACCESS /* */
4553 Test ntcreate calls made by xcopy
4555 static bool run_xcopy(int dummy
)
4557 static struct cli_state
*cli1
;
4558 const char *fname
= "\\test.txt";
4559 bool correct
= True
;
4560 uint16_t fnum1
, fnum2
;
4563 printf("starting xcopy test\n");
4565 if (!torture_open_connection(&cli1
, 0)) {
4569 status
= cli_ntcreate(cli1
, fname
, 0, FIRST_DESIRED_ACCESS
,
4570 FILE_ATTRIBUTE_ARCHIVE
, FILE_SHARE_NONE
,
4571 FILE_OVERWRITE_IF
, 0x4044, 0, &fnum1
);
4572 if (!NT_STATUS_IS_OK(status
)) {
4573 printf("First open failed - %s\n", nt_errstr(status
));
4577 status
= cli_ntcreate(cli1
, fname
, 0, SECOND_DESIRED_ACCESS
, 0,
4578 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4579 FILE_OPEN
, 0x200000, 0, &fnum2
);
4580 if (!NT_STATUS_IS_OK(status
)) {
4581 printf("second open failed - %s\n", nt_errstr(status
));
4585 if (!torture_close_connection(cli1
)) {
4593 Test rename on files open with share delete and no share delete.
4595 static bool run_rename(int dummy
)
4597 static struct cli_state
*cli1
;
4598 const char *fname
= "\\test.txt";
4599 const char *fname1
= "\\test1.txt";
4600 bool correct
= True
;
4605 printf("starting rename test\n");
4607 if (!torture_open_connection(&cli1
, 0)) {
4611 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4612 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4614 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4615 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
4616 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4617 if (!NT_STATUS_IS_OK(status
)) {
4618 printf("First open failed - %s\n", nt_errstr(status
));
4622 status
= cli_rename(cli1
, fname
, fname1
);
4623 if (!NT_STATUS_IS_OK(status
)) {
4624 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status
));
4626 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4630 status
= cli_close(cli1
, fnum1
);
4631 if (!NT_STATUS_IS_OK(status
)) {
4632 printf("close - 1 failed (%s)\n", nt_errstr(status
));
4636 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4637 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4638 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4640 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
4642 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
4644 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4645 if (!NT_STATUS_IS_OK(status
)) {
4646 printf("Second open failed - %s\n", nt_errstr(status
));
4650 status
= cli_rename(cli1
, fname
, fname1
);
4651 if (!NT_STATUS_IS_OK(status
)) {
4652 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status
));
4655 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4658 status
= cli_close(cli1
, fnum1
);
4659 if (!NT_STATUS_IS_OK(status
)) {
4660 printf("close - 2 failed (%s)\n", nt_errstr(status
));
4664 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4665 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4667 status
= cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
,
4668 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
4669 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4670 if (!NT_STATUS_IS_OK(status
)) {
4671 printf("Third open failed - %s\n", nt_errstr(status
));
4680 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4681 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
4682 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
4685 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
4686 printf("[8] setting delete_on_close on file failed !\n");
4690 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
4691 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
4697 status
= cli_rename(cli1
, fname
, fname1
);
4698 if (!NT_STATUS_IS_OK(status
)) {
4699 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status
));
4702 printf("Third rename succeeded (SHARE_NONE)\n");
4705 status
= cli_close(cli1
, fnum1
);
4706 if (!NT_STATUS_IS_OK(status
)) {
4707 printf("close - 3 failed (%s)\n", nt_errstr(status
));
4711 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4712 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4716 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4717 FILE_ATTRIBUTE_NORMAL
,
4718 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
4719 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4720 if (!NT_STATUS_IS_OK(status
)) {
4721 printf("Fourth open failed - %s\n", nt_errstr(status
));
4725 status
= cli_rename(cli1
, fname
, fname1
);
4726 if (!NT_STATUS_IS_OK(status
)) {
4727 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status
));
4729 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4733 status
= cli_close(cli1
, fnum1
);
4734 if (!NT_STATUS_IS_OK(status
)) {
4735 printf("close - 4 failed (%s)\n", nt_errstr(status
));
4739 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4740 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4744 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
4745 FILE_ATTRIBUTE_NORMAL
,
4746 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
4747 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
4748 if (!NT_STATUS_IS_OK(status
)) {
4749 printf("Fifth open failed - %s\n", nt_errstr(status
));
4753 status
= cli_rename(cli1
, fname
, fname1
);
4754 if (!NT_STATUS_IS_OK(status
)) {
4755 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status
));
4758 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status
));
4762 * Now check if the first name still exists ...
4765 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4766 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4767 printf("Opening original file after rename of open file fails: %s\n",
4771 printf("Opening original file after rename of open file works ...\n");
4772 (void)cli_close(cli1, fnum2);
4776 status
= cli_close(cli1
, fnum1
);
4777 if (!NT_STATUS_IS_OK(status
)) {
4778 printf("close - 5 failed (%s)\n", nt_errstr(status
));
4782 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4783 status
= cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
);
4784 if (!NT_STATUS_IS_OK(status
)) {
4785 printf("getatr on file %s failed - %s ! \n",
4786 fname1
, nt_errstr(status
));
4789 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
4790 printf("Renamed file %s has wrong attr 0x%x "
4791 "(should be 0x%x)\n",
4794 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
4797 printf("Renamed file %s has archive bit set\n", fname1
);
4801 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4802 cli_unlink(cli1
, fname1
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4804 if (!torture_close_connection(cli1
)) {
4811 static bool run_pipe_number(int dummy
)
4813 struct cli_state
*cli1
;
4814 const char *pipe_name
= "\\SPOOLSS";
4819 printf("starting pipenumber test\n");
4820 if (!torture_open_connection(&cli1
, 0)) {
4824 cli_sockopt(cli1
, sockops
);
4826 status
= cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
,
4827 FILE_ATTRIBUTE_NORMAL
,
4828 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4829 FILE_OPEN_IF
, 0, 0, &fnum
);
4830 if (!NT_STATUS_IS_OK(status
)) {
4831 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, nt_errstr(status
));
4835 printf("\r%6d", num_pipes
);
4838 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4839 torture_close_connection(cli1
);
4844 Test open mode returns on read-only files.
4846 static bool run_opentest(int dummy
)
4848 static struct cli_state
*cli1
;
4849 static struct cli_state
*cli2
;
4850 const char *fname
= "\\readonly.file";
4851 uint16_t fnum1
, fnum2
;
4854 bool correct
= True
;
4858 printf("starting open test\n");
4860 if (!torture_open_connection(&cli1
, 0)) {
4864 cli_setatr(cli1
, fname
, 0, 0);
4865 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4867 cli_sockopt(cli1
, sockops
);
4869 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4870 if (!NT_STATUS_IS_OK(status
)) {
4871 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4875 status
= cli_close(cli1
, fnum1
);
4876 if (!NT_STATUS_IS_OK(status
)) {
4877 printf("close2 failed (%s)\n", nt_errstr(status
));
4881 status
= cli_setatr(cli1
, fname
, FILE_ATTRIBUTE_READONLY
, 0);
4882 if (!NT_STATUS_IS_OK(status
)) {
4883 printf("cli_setatr failed (%s)\n", nt_errstr(status
));
4887 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4888 if (!NT_STATUS_IS_OK(status
)) {
4889 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4893 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4894 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4896 if (check_error(__LINE__
, status
, ERRDOS
, ERRnoaccess
,
4897 NT_STATUS_ACCESS_DENIED
)) {
4898 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4901 printf("finished open test 1\n");
4903 cli_close(cli1
, fnum1
);
4905 /* Now try not readonly and ensure ERRbadshare is returned. */
4907 cli_setatr(cli1
, fname
, 0, 0);
4909 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
);
4910 if (!NT_STATUS_IS_OK(status
)) {
4911 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
4915 /* This will fail - but the error should be ERRshare. */
4916 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4918 if (check_error(__LINE__
, status
, ERRDOS
, ERRbadshare
,
4919 NT_STATUS_SHARING_VIOLATION
)) {
4920 printf("correct error code ERRDOS/ERRbadshare returned\n");
4923 status
= cli_close(cli1
, fnum1
);
4924 if (!NT_STATUS_IS_OK(status
)) {
4925 printf("close2 failed (%s)\n", nt_errstr(status
));
4929 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4931 printf("finished open test 2\n");
4933 /* Test truncate open disposition on file opened for read. */
4934 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
4935 if (!NT_STATUS_IS_OK(status
)) {
4936 printf("(3) open (1) of %s failed (%s)\n", fname
, nt_errstr(status
));
4940 /* write 20 bytes. */
4942 memset(buf
, '\0', 20);
4944 status
= cli_writeall(cli1
, fnum1
, 0, (uint8_t *)buf
, 0, 20, NULL
);
4945 if (!NT_STATUS_IS_OK(status
)) {
4946 printf("write failed (%s)\n", nt_errstr(status
));
4950 status
= cli_close(cli1
, fnum1
);
4951 if (!NT_STATUS_IS_OK(status
)) {
4952 printf("(3) close1 failed (%s)\n", nt_errstr(status
));
4956 /* Ensure size == 20. */
4957 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4958 if (!NT_STATUS_IS_OK(status
)) {
4959 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4964 printf("(3) file size != 20\n");
4968 /* Now test if we can truncate a file opened for readonly. */
4969 status
= cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
);
4970 if (!NT_STATUS_IS_OK(status
)) {
4971 printf("(3) open (2) of %s failed (%s)\n", fname
, nt_errstr(status
));
4975 status
= cli_close(cli1
, fnum1
);
4976 if (!NT_STATUS_IS_OK(status
)) {
4977 printf("close2 failed (%s)\n", nt_errstr(status
));
4981 /* Ensure size == 0. */
4982 status
= cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
);
4983 if (!NT_STATUS_IS_OK(status
)) {
4984 printf("(3) getatr failed (%s)\n", nt_errstr(status
));
4989 printf("(3) file size != 0\n");
4992 printf("finished open test 3\n");
4994 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
4996 printf("Do ctemp tests\n");
4997 status
= cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
);
4998 if (!NT_STATUS_IS_OK(status
)) {
4999 printf("ctemp failed (%s)\n", nt_errstr(status
));
5003 printf("ctemp gave path %s\n", tmp_path
);
5004 status
= cli_close(cli1
, fnum1
);
5005 if (!NT_STATUS_IS_OK(status
)) {
5006 printf("close of temp failed (%s)\n", nt_errstr(status
));
5009 status
= cli_unlink(cli1
, tmp_path
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5010 if (!NT_STATUS_IS_OK(status
)) {
5011 printf("unlink of temp failed (%s)\n", nt_errstr(status
));
5014 /* Test the non-io opens... */
5016 if (!torture_open_connection(&cli2
, 1)) {
5020 cli_setatr(cli2
, fname
, 0, 0);
5021 cli_unlink(cli2
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5023 cli_sockopt(cli2
, sockops
);
5025 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5026 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5027 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5028 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5029 if (!NT_STATUS_IS_OK(status
)) {
5030 printf("TEST #1 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5034 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5035 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5036 FILE_OPEN_IF
, 0, 0, &fnum2
);
5037 if (!NT_STATUS_IS_OK(status
)) {
5038 printf("TEST #1 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5042 status
= cli_close(cli1
, fnum1
);
5043 if (!NT_STATUS_IS_OK(status
)) {
5044 printf("TEST #1 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5048 status
= cli_close(cli2
, fnum2
);
5049 if (!NT_STATUS_IS_OK(status
)) {
5050 printf("TEST #1 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5054 printf("non-io open test #1 passed.\n");
5056 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5058 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5060 status
= cli_ntcreate(cli1
, fname
, 0,
5061 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5062 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5063 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5064 if (!NT_STATUS_IS_OK(status
)) {
5065 printf("TEST #2 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5069 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5070 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5071 FILE_OPEN_IF
, 0, 0, &fnum2
);
5072 if (!NT_STATUS_IS_OK(status
)) {
5073 printf("TEST #2 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5077 status
= cli_close(cli1
, fnum1
);
5078 if (!NT_STATUS_IS_OK(status
)) {
5079 printf("TEST #2 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5083 status
= cli_close(cli2
, fnum2
);
5084 if (!NT_STATUS_IS_OK(status
)) {
5085 printf("TEST #2 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5089 printf("non-io open test #2 passed.\n");
5091 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5093 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5095 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
,
5096 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5097 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5098 if (!NT_STATUS_IS_OK(status
)) {
5099 printf("TEST #3 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5103 status
= cli_ntcreate(cli2
, fname
, 0,
5104 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5105 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5106 FILE_OPEN_IF
, 0, 0, &fnum2
);
5107 if (!NT_STATUS_IS_OK(status
)) {
5108 printf("TEST #3 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5112 status
= cli_close(cli1
, fnum1
);
5113 if (!NT_STATUS_IS_OK(status
)) {
5114 printf("TEST #3 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5118 status
= cli_close(cli2
, fnum2
);
5119 if (!NT_STATUS_IS_OK(status
)) {
5120 printf("TEST #3 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5124 printf("non-io open test #3 passed.\n");
5126 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5128 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5130 status
= cli_ntcreate(cli1
, fname
, 0,
5131 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5132 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5133 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5134 if (!NT_STATUS_IS_OK(status
)) {
5135 printf("TEST #4 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5139 status
= cli_ntcreate(cli2
, fname
, 0,
5140 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5141 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5142 FILE_OPEN_IF
, 0, 0, &fnum2
);
5143 if (NT_STATUS_IS_OK(status
)) {
5144 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5148 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5150 status
= cli_close(cli1
, fnum1
);
5151 if (!NT_STATUS_IS_OK(status
)) {
5152 printf("TEST #4 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5156 printf("non-io open test #4 passed.\n");
5158 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5160 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5162 status
= cli_ntcreate(cli1
, fname
, 0,
5163 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5164 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5165 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5166 if (!NT_STATUS_IS_OK(status
)) {
5167 printf("TEST #5 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5171 status
= cli_ntcreate(cli2
, fname
, 0,
5172 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5173 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_DELETE
,
5174 FILE_OPEN_IF
, 0, 0, &fnum2
);
5175 if (!NT_STATUS_IS_OK(status
)) {
5176 printf("TEST #5 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5180 status
= cli_close(cli1
, fnum1
);
5181 if (!NT_STATUS_IS_OK(status
)) {
5182 printf("TEST #5 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5186 status
= cli_close(cli2
, fnum2
);
5187 if (!NT_STATUS_IS_OK(status
)) {
5188 printf("TEST #5 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5192 printf("non-io open test #5 passed.\n");
5194 printf("TEST #6 testing 1 non-io open, one io open\n");
5196 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5198 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5199 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5200 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5201 if (!NT_STATUS_IS_OK(status
)) {
5202 printf("TEST #6 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5206 status
= cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
,
5207 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
5208 FILE_OPEN_IF
, 0, 0, &fnum2
);
5209 if (!NT_STATUS_IS_OK(status
)) {
5210 printf("TEST #6 open 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5214 status
= cli_close(cli1
, fnum1
);
5215 if (!NT_STATUS_IS_OK(status
)) {
5216 printf("TEST #6 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5220 status
= cli_close(cli2
, fnum2
);
5221 if (!NT_STATUS_IS_OK(status
)) {
5222 printf("TEST #6 close 2 of %s failed (%s)\n", fname
, nt_errstr(status
));
5226 printf("non-io open test #6 passed.\n");
5228 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5230 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5232 status
= cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
,
5233 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
5234 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5235 if (!NT_STATUS_IS_OK(status
)) {
5236 printf("TEST #7 open 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5240 status
= cli_ntcreate(cli2
, fname
, 0,
5241 DELETE_ACCESS
|FILE_READ_ATTRIBUTES
,
5242 FILE_ATTRIBUTE_NORMAL
,
5243 FILE_SHARE_READ
|FILE_SHARE_DELETE
,
5244 FILE_OPEN_IF
, 0, 0, &fnum2
);
5245 if (NT_STATUS_IS_OK(status
)) {
5246 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, nt_errstr(status
));
5250 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname
, nt_errstr(status
), "sharing violation");
5252 status
= cli_close(cli1
, fnum1
);
5253 if (!NT_STATUS_IS_OK(status
)) {
5254 printf("TEST #7 close 1 of %s failed (%s)\n", fname
, nt_errstr(status
));
5258 printf("non-io open test #7 passed.\n");
5260 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5262 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5263 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, FILE_ATTRIBUTE_NORMAL
,
5264 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5265 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5266 if (!NT_STATUS_IS_OK(status
)) {
5267 printf("TEST #8 open of %s failed (%s)\n", fname
, nt_errstr(status
));
5272 /* Write to ensure we have to update the file time. */
5273 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5275 if (!NT_STATUS_IS_OK(status
)) {
5276 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status
));
5281 status
= cli_close(cli1
, fnum1
);
5282 if (!NT_STATUS_IS_OK(status
)) {
5283 printf("TEST #8 close of %s failed (%s)\n", fname
, nt_errstr(status
));
5289 if (!torture_close_connection(cli1
)) {
5292 if (!torture_close_connection(cli2
)) {
5299 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
5301 uint16 major
, minor
;
5302 uint32 caplow
, caphigh
;
5305 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
5306 printf("Server doesn't support UNIX CIFS extensions.\n");
5307 return NT_STATUS_NOT_SUPPORTED
;
5310 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
5312 if (!NT_STATUS_IS_OK(status
)) {
5313 printf("Server didn't return UNIX CIFS extensions: %s\n",
5318 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
5320 if (!NT_STATUS_IS_OK(status
)) {
5321 printf("Server doesn't support setting UNIX CIFS extensions: "
5322 "%s.\n", nt_errstr(status
));
5326 return NT_STATUS_OK
;
5330 Test POSIX open /mkdir calls.
5332 static bool run_simple_posix_open_test(int dummy
)
5334 static struct cli_state
*cli1
;
5335 const char *fname
= "posix:file";
5336 const char *hname
= "posix:hlink";
5337 const char *sname
= "posix:symlink";
5338 const char *dname
= "posix:dir";
5341 uint16_t fnum1
= (uint16_t)-1;
5342 SMB_STRUCT_STAT sbuf
;
5343 bool correct
= false;
5347 printf("Starting simple POSIX open test\n");
5349 if (!torture_open_connection(&cli1
, 0)) {
5353 cli_sockopt(cli1
, sockops
);
5355 status
= torture_setup_unix_extensions(cli1
);
5356 if (!NT_STATUS_IS_OK(status
)) {
5360 cli_setatr(cli1
, fname
, 0, 0);
5361 cli_posix_unlink(cli1
, fname
);
5362 cli_setatr(cli1
, dname
, 0, 0);
5363 cli_posix_rmdir(cli1
, dname
);
5364 cli_setatr(cli1
, hname
, 0, 0);
5365 cli_posix_unlink(cli1
, hname
);
5366 cli_setatr(cli1
, sname
, 0, 0);
5367 cli_posix_unlink(cli1
, sname
);
5369 /* Create a directory. */
5370 status
= cli_posix_mkdir(cli1
, dname
, 0777);
5371 if (!NT_STATUS_IS_OK(status
)) {
5372 printf("POSIX mkdir of %s failed (%s)\n", dname
, nt_errstr(status
));
5376 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5378 if (!NT_STATUS_IS_OK(status
)) {
5379 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5383 /* Test ftruncate - set file size. */
5384 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5385 if (!NT_STATUS_IS_OK(status
)) {
5386 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5390 /* Ensure st_size == 1000 */
5391 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5392 if (!NT_STATUS_IS_OK(status
)) {
5393 printf("stat failed (%s)\n", nt_errstr(status
));
5397 if (sbuf
.st_ex_size
!= 1000) {
5398 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5402 /* Test ftruncate - set file size back to zero. */
5403 status
= cli_ftruncate(cli1
, fnum1
, 0);
5404 if (!NT_STATUS_IS_OK(status
)) {
5405 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5409 status
= cli_close(cli1
, fnum1
);
5410 if (!NT_STATUS_IS_OK(status
)) {
5411 printf("close failed (%s)\n", nt_errstr(status
));
5415 /* Now open the file again for read only. */
5416 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5417 if (!NT_STATUS_IS_OK(status
)) {
5418 printf("POSIX open of %s failed (%s)\n", fname
, nt_errstr(status
));
5422 /* Now unlink while open. */
5423 status
= cli_posix_unlink(cli1
, fname
);
5424 if (!NT_STATUS_IS_OK(status
)) {
5425 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5429 status
= cli_close(cli1
, fnum1
);
5430 if (!NT_STATUS_IS_OK(status
)) {
5431 printf("close(2) failed (%s)\n", nt_errstr(status
));
5435 /* Ensure the file has gone. */
5436 status
= cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
);
5437 if (NT_STATUS_IS_OK(status
)) {
5438 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
5442 /* Create again to test open with O_TRUNC. */
5443 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
);
5444 if (!NT_STATUS_IS_OK(status
)) {
5445 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5449 /* Test ftruncate - set file size. */
5450 status
= cli_ftruncate(cli1
, fnum1
, 1000);
5451 if (!NT_STATUS_IS_OK(status
)) {
5452 printf("ftruncate failed (%s)\n", nt_errstr(status
));
5456 /* Ensure st_size == 1000 */
5457 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5458 if (!NT_STATUS_IS_OK(status
)) {
5459 printf("stat failed (%s)\n", nt_errstr(status
));
5463 if (sbuf
.st_ex_size
!= 1000) {
5464 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
5468 status
= cli_close(cli1
, fnum1
);
5469 if (!NT_STATUS_IS_OK(status
)) {
5470 printf("close(2) failed (%s)\n", nt_errstr(status
));
5474 /* Re-open with O_TRUNC. */
5475 status
= cli_posix_open(cli1
, fname
, O_WRONLY
|O_TRUNC
, 0600, &fnum1
);
5476 if (!NT_STATUS_IS_OK(status
)) {
5477 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5481 /* Ensure st_size == 0 */
5482 status
= cli_posix_stat(cli1
, fname
, &sbuf
);
5483 if (!NT_STATUS_IS_OK(status
)) {
5484 printf("stat failed (%s)\n", nt_errstr(status
));
5488 if (sbuf
.st_ex_size
!= 0) {
5489 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf
.st_ex_size
);
5493 status
= cli_close(cli1
, fnum1
);
5494 if (!NT_STATUS_IS_OK(status
)) {
5495 printf("close failed (%s)\n", nt_errstr(status
));
5499 status
= cli_posix_unlink(cli1
, fname
);
5500 if (!NT_STATUS_IS_OK(status
)) {
5501 printf("POSIX unlink of %s failed (%s)\n", fname
, nt_errstr(status
));
5505 status
= cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
);
5506 if (!NT_STATUS_IS_OK(status
)) {
5507 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5508 dname
, nt_errstr(status
));
5512 cli_close(cli1
, fnum1
);
5514 /* What happens when we try and POSIX open a directory for write ? */
5515 status
= cli_posix_open(cli1
, dname
, O_RDWR
, 0, &fnum1
);
5516 if (NT_STATUS_IS_OK(status
)) {
5517 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
5520 if (!check_both_error(__LINE__
, status
, ERRDOS
, EISDIR
,
5521 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5526 /* Create the file. */
5527 status
= cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
,
5529 if (!NT_STATUS_IS_OK(status
)) {
5530 printf("POSIX create of %s failed (%s)\n", fname
, nt_errstr(status
));
5534 /* Write some data into it. */
5535 status
= cli_writeall(cli1
, fnum1
, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5537 if (!NT_STATUS_IS_OK(status
)) {
5538 printf("cli_write failed: %s\n", nt_errstr(status
));
5542 cli_close(cli1
, fnum1
);
5544 /* Now create a hardlink. */
5545 status
= cli_posix_hardlink(cli1
, fname
, hname
);
5546 if (!NT_STATUS_IS_OK(status
)) {
5547 printf("POSIX hardlink of %s failed (%s)\n", hname
, nt_errstr(status
));
5551 /* Now create a symlink. */
5552 status
= cli_posix_symlink(cli1
, fname
, sname
);
5553 if (!NT_STATUS_IS_OK(status
)) {
5554 printf("POSIX symlink of %s failed (%s)\n", sname
, nt_errstr(status
));
5558 /* Open the hardlink for read. */
5559 status
= cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
);
5560 if (!NT_STATUS_IS_OK(status
)) {
5561 printf("POSIX open of %s failed (%s)\n", hname
, nt_errstr(status
));
5565 status
= cli_read(cli1
, fnum1
, buf
, 0, 10, &nread
);
5566 if (!NT_STATUS_IS_OK(status
)) {
5567 printf("POSIX read of %s failed (%s)\n", hname
,
5570 } else if (nread
!= 10) {
5571 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5572 hname
, (unsigned long)nread
, 10);
5576 if (memcmp(buf
, "TEST DATA\n", 10)) {
5577 printf("invalid data read from hardlink\n");
5581 /* Do a POSIX lock/unlock. */
5582 status
= cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
);
5583 if (!NT_STATUS_IS_OK(status
)) {
5584 printf("POSIX lock failed %s\n", nt_errstr(status
));
5588 /* Punch a hole in the locked area. */
5589 status
= cli_posix_unlock(cli1
, fnum1
, 10, 80);
5590 if (!NT_STATUS_IS_OK(status
)) {
5591 printf("POSIX unlock failed %s\n", nt_errstr(status
));
5595 cli_close(cli1
, fnum1
);
5597 /* Open the symlink for read - this should fail. A POSIX
5598 client should not be doing opens on a symlink. */
5599 status
= cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
);
5600 if (NT_STATUS_IS_OK(status
)) {
5601 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
5604 if (!check_both_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
5605 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
5606 printf("POSIX open of %s should have failed "
5607 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5608 "failed with %s instead.\n",
5609 sname
, nt_errstr(status
));
5614 status
= cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
));
5615 if (!NT_STATUS_IS_OK(status
)) {
5616 printf("POSIX readlink on %s failed (%s)\n", sname
, nt_errstr(status
));
5620 if (strcmp(namebuf
, fname
) != 0) {
5621 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5622 sname
, fname
, namebuf
);
5626 status
= cli_posix_rmdir(cli1
, dname
);
5627 if (!NT_STATUS_IS_OK(status
)) {
5628 printf("POSIX rmdir failed (%s)\n", nt_errstr(status
));
5632 printf("Simple POSIX open test passed\n");
5637 if (fnum1
!= (uint16_t)-1) {
5638 cli_close(cli1
, fnum1
);
5639 fnum1
= (uint16_t)-1;
5642 cli_setatr(cli1
, sname
, 0, 0);
5643 cli_posix_unlink(cli1
, sname
);
5644 cli_setatr(cli1
, hname
, 0, 0);
5645 cli_posix_unlink(cli1
, hname
);
5646 cli_setatr(cli1
, fname
, 0, 0);
5647 cli_posix_unlink(cli1
, fname
);
5648 cli_setatr(cli1
, dname
, 0, 0);
5649 cli_posix_rmdir(cli1
, dname
);
5651 if (!torture_close_connection(cli1
)) {
5659 static uint32 open_attrs_table
[] = {
5660 FILE_ATTRIBUTE_NORMAL
,
5661 FILE_ATTRIBUTE_ARCHIVE
,
5662 FILE_ATTRIBUTE_READONLY
,
5663 FILE_ATTRIBUTE_HIDDEN
,
5664 FILE_ATTRIBUTE_SYSTEM
,
5666 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
5667 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
5668 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
5669 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5670 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5671 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5673 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
5674 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
5675 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
5676 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
5679 struct trunc_open_results
{
5686 static struct trunc_open_results attr_results
[] = {
5687 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5688 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5689 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5690 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
5691 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
5692 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
5693 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5694 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5695 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5696 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5697 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5698 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
5699 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5700 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5701 { 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
},
5702 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5703 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5704 { 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
},
5705 { 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
},
5706 { 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
},
5707 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5708 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
5709 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
5710 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5711 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
5712 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
5715 static bool run_openattrtest(int dummy
)
5717 static struct cli_state
*cli1
;
5718 const char *fname
= "\\openattr.file";
5720 bool correct
= True
;
5722 unsigned int i
, j
, k
, l
;
5725 printf("starting open attr test\n");
5727 if (!torture_open_connection(&cli1
, 0)) {
5731 cli_sockopt(cli1
, sockops
);
5733 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
5734 cli_setatr(cli1
, fname
, 0, 0);
5735 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5737 status
= cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
,
5738 open_attrs_table
[i
], FILE_SHARE_NONE
,
5739 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
5740 if (!NT_STATUS_IS_OK(status
)) {
5741 printf("open %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5745 status
= cli_close(cli1
, fnum1
);
5746 if (!NT_STATUS_IS_OK(status
)) {
5747 printf("close %d (1) of %s failed (%s)\n", i
, fname
, nt_errstr(status
));
5751 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
5752 status
= cli_ntcreate(cli1
, fname
, 0,
5753 FILE_READ_DATA
|FILE_WRITE_DATA
,
5754 open_attrs_table
[j
],
5755 FILE_SHARE_NONE
, FILE_OVERWRITE
,
5757 if (!NT_STATUS_IS_OK(status
)) {
5758 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5759 if (attr_results
[l
].num
== k
) {
5760 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5761 k
, open_attrs_table
[i
],
5762 open_attrs_table
[j
],
5763 fname
, NT_STATUS_V(status
), nt_errstr(status
));
5768 if (!NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
5769 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5770 k
, open_attrs_table
[i
], open_attrs_table
[j
],
5775 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
5781 status
= cli_close(cli1
, fnum1
);
5782 if (!NT_STATUS_IS_OK(status
)) {
5783 printf("close %d (2) of %s failed (%s)\n", j
, fname
, nt_errstr(status
));
5787 status
= cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
);
5788 if (!NT_STATUS_IS_OK(status
)) {
5789 printf("getatr(2) failed (%s)\n", nt_errstr(status
));
5794 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5795 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
5798 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
5799 if (attr_results
[l
].num
== k
) {
5800 if (attr
!= attr_results
[l
].result_attr
||
5801 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
5802 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
5803 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5804 open_attrs_table
[i
],
5805 open_attrs_table
[j
],
5807 attr_results
[l
].result_attr
);
5817 cli_setatr(cli1
, fname
, 0, 0);
5818 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5820 printf("open attr test %s.\n", correct
? "passed" : "failed");
5822 if (!torture_close_connection(cli1
)) {
5828 static NTSTATUS
list_fn(const char *mnt
, struct file_info
*finfo
,
5829 const char *name
, void *state
)
5831 int *matched
= (int *)state
;
5832 if (matched
!= NULL
) {
5835 return NT_STATUS_OK
;
5839 test directory listing speed
5841 static bool run_dirtest(int dummy
)
5844 static struct cli_state
*cli
;
5846 struct timeval core_start
;
5847 bool correct
= True
;
5850 printf("starting directory test\n");
5852 if (!torture_open_connection(&cli
, 0)) {
5856 cli_sockopt(cli
, sockops
);
5859 for (i
=0;i
<torture_numops
;i
++) {
5861 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5862 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
5863 fprintf(stderr
,"Failed to open %s\n", fname
);
5866 cli_close(cli
, fnum
);
5869 core_start
= timeval_current();
5872 cli_list(cli
, "a*.*", 0, list_fn
, &matched
);
5873 printf("Matched %d\n", matched
);
5876 cli_list(cli
, "b*.*", 0, list_fn
, &matched
);
5877 printf("Matched %d\n", matched
);
5880 cli_list(cli
, "xyzabc", 0, list_fn
, &matched
);
5881 printf("Matched %d\n", matched
);
5883 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
5886 for (i
=0;i
<torture_numops
;i
++) {
5888 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
5889 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5892 if (!torture_close_connection(cli
)) {
5896 printf("finished dirtest\n");
5901 static NTSTATUS
del_fn(const char *mnt
, struct file_info
*finfo
, const char *mask
,
5904 struct cli_state
*pcli
= (struct cli_state
*)state
;
5906 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
5908 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
5909 return NT_STATUS_OK
;
5911 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
5912 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
5913 printf("del_fn: failed to rmdir %s\n,", fname
);
5915 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
)))
5916 printf("del_fn: failed to unlink %s\n,", fname
);
5918 return NT_STATUS_OK
;
5923 sees what IOCTLs are supported
5925 bool torture_ioctl_test(int dummy
)
5927 static struct cli_state
*cli
;
5928 uint16_t device
, function
;
5930 const char *fname
= "\\ioctl.dat";
5934 if (!torture_open_connection(&cli
, 0)) {
5938 printf("starting ioctl test\n");
5940 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5942 status
= cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
5943 if (!NT_STATUS_IS_OK(status
)) {
5944 printf("open of %s failed (%s)\n", fname
, nt_errstr(status
));
5948 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
5949 printf("ioctl device info: %s\n", nt_errstr(status
));
5951 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
5952 printf("ioctl job info: %s\n", nt_errstr(status
));
5954 for (device
=0;device
<0x100;device
++) {
5955 printf("ioctl test with device = 0x%x\n", device
);
5956 for (function
=0;function
<0x100;function
++) {
5957 uint32 code
= (device
<<16) | function
;
5959 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
5961 if (NT_STATUS_IS_OK(status
)) {
5962 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
5964 data_blob_free(&blob
);
5969 if (!torture_close_connection(cli
)) {
5978 tries varients of chkpath
5980 bool torture_chkpath_test(int dummy
)
5982 static struct cli_state
*cli
;
5987 if (!torture_open_connection(&cli
, 0)) {
5991 printf("starting chkpath test\n");
5993 /* cleanup from an old run */
5994 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
5995 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
5996 cli_rmdir(cli
, "\\chkpath.dir");
5998 status
= cli_mkdir(cli
, "\\chkpath.dir");
5999 if (!NT_STATUS_IS_OK(status
)) {
6000 printf("mkdir1 failed : %s\n", nt_errstr(status
));
6004 status
= cli_mkdir(cli
, "\\chkpath.dir\\dir2");
6005 if (!NT_STATUS_IS_OK(status
)) {
6006 printf("mkdir2 failed : %s\n", nt_errstr(status
));
6010 status
= cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
,
6012 if (!NT_STATUS_IS_OK(status
)) {
6013 printf("open1 failed (%s)\n", nt_errstr(status
));
6016 cli_close(cli
, fnum
);
6018 status
= cli_chkpath(cli
, "\\chkpath.dir");
6019 if (!NT_STATUS_IS_OK(status
)) {
6020 printf("chkpath1 failed: %s\n", nt_errstr(status
));
6024 status
= cli_chkpath(cli
, "\\chkpath.dir\\dir2");
6025 if (!NT_STATUS_IS_OK(status
)) {
6026 printf("chkpath2 failed: %s\n", nt_errstr(status
));
6030 status
= cli_chkpath(cli
, "\\chkpath.dir\\foo.txt");
6031 if (!NT_STATUS_IS_OK(status
)) {
6032 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6033 NT_STATUS_NOT_A_DIRECTORY
);
6035 printf("* chkpath on a file should fail\n");
6039 status
= cli_chkpath(cli
, "\\chkpath.dir\\bar.txt");
6040 if (!NT_STATUS_IS_OK(status
)) {
6041 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadfile
,
6042 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
6044 printf("* chkpath on a non existant file should fail\n");
6048 status
= cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt");
6049 if (!NT_STATUS_IS_OK(status
)) {
6050 ret
= check_error(__LINE__
, status
, ERRDOS
, ERRbadpath
,
6051 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
6053 printf("* chkpath on a non existent component should fail\n");
6057 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
6058 cli_unlink(cli
, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6059 cli_rmdir(cli
, "\\chkpath.dir");
6061 if (!torture_close_connection(cli
)) {
6068 static bool run_eatest(int dummy
)
6070 static struct cli_state
*cli
;
6071 const char *fname
= "\\eatest.txt";
6072 bool correct
= True
;
6076 struct ea_struct
*ea_list
= NULL
;
6077 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
6080 printf("starting eatest\n");
6082 if (!torture_open_connection(&cli
, 0)) {
6083 talloc_destroy(mem_ctx
);
6087 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
6089 status
= cli_ntcreate(cli
, fname
, 0,
6090 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6091 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
6093 if (!NT_STATUS_IS_OK(status
)) {
6094 printf("open failed - %s\n", nt_errstr(status
));
6095 talloc_destroy(mem_ctx
);
6099 for (i
= 0; i
< 10; i
++) {
6100 fstring ea_name
, ea_val
;
6102 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
6103 memset(ea_val
, (char)i
+1, i
+1);
6104 status
= cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1);
6105 if (!NT_STATUS_IS_OK(status
)) {
6106 printf("ea_set of name %s failed - %s\n", ea_name
,
6108 talloc_destroy(mem_ctx
);
6113 cli_close(cli
, fnum
);
6114 for (i
= 0; i
< 10; i
++) {
6115 fstring ea_name
, ea_val
;
6117 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
6118 memset(ea_val
, (char)i
+1, i
+1);
6119 status
= cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1);
6120 if (!NT_STATUS_IS_OK(status
)) {
6121 printf("ea_set of name %s failed - %s\n", ea_name
,
6123 talloc_destroy(mem_ctx
);
6128 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6129 if (!NT_STATUS_IS_OK(status
)) {
6130 printf("ea_get list failed - %s\n", nt_errstr(status
));
6134 printf("num_eas = %d\n", (int)num_eas
);
6136 if (num_eas
!= 20) {
6137 printf("Should be 20 EA's stored... failing.\n");
6141 for (i
= 0; i
< num_eas
; i
++) {
6142 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6143 dump_data(0, ea_list
[i
].value
.data
,
6144 ea_list
[i
].value
.length
);
6147 /* Setting EA's to zero length deletes them. Test this */
6148 printf("Now deleting all EA's - case indepenent....\n");
6151 cli_set_ea_path(cli
, fname
, "", "", 0);
6153 for (i
= 0; i
< 20; i
++) {
6155 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
6156 status
= cli_set_ea_path(cli
, fname
, ea_name
, "", 0);
6157 if (!NT_STATUS_IS_OK(status
)) {
6158 printf("ea_set of name %s failed - %s\n", ea_name
,
6160 talloc_destroy(mem_ctx
);
6166 status
= cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
);
6167 if (!NT_STATUS_IS_OK(status
)) {
6168 printf("ea_get list failed - %s\n", nt_errstr(status
));
6172 printf("num_eas = %d\n", (int)num_eas
);
6173 for (i
= 0; i
< num_eas
; i
++) {
6174 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
6175 dump_data(0, ea_list
[i
].value
.data
,
6176 ea_list
[i
].value
.length
);
6180 printf("deleting EA's failed.\n");
6184 /* Try and delete a non existant EA. */
6185 status
= cli_set_ea_path(cli
, fname
, "foo", "", 0);
6186 if (!NT_STATUS_IS_OK(status
)) {
6187 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6192 talloc_destroy(mem_ctx
);
6193 if (!torture_close_connection(cli
)) {
6200 static bool run_dirtest1(int dummy
)
6203 static struct cli_state
*cli
;
6206 bool correct
= True
;
6208 printf("starting directory test\n");
6210 if (!torture_open_connection(&cli
, 0)) {
6214 cli_sockopt(cli
, sockops
);
6216 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6217 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6218 cli_rmdir(cli
, "\\LISTDIR");
6219 cli_mkdir(cli
, "\\LISTDIR");
6221 /* Create 1000 files and 1000 directories. */
6222 for (i
=0;i
<1000;i
++) {
6224 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
6225 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
6226 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
6227 fprintf(stderr
,"Failed to open %s\n", fname
);
6230 cli_close(cli
, fnum
);
6232 for (i
=0;i
<1000;i
++) {
6234 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
6235 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
6236 fprintf(stderr
,"Failed to open %s\n", fname
);
6241 /* Now ensure that doing an old list sees both files and directories. */
6243 cli_list_old(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6244 printf("num_seen = %d\n", num_seen
);
6245 /* We should see 100 files + 1000 directories + . and .. */
6246 if (num_seen
!= 2002)
6249 /* Ensure if we have the "must have" bits we only see the
6253 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6254 printf("num_seen = %d\n", num_seen
);
6255 if (num_seen
!= 1002)
6259 cli_list_old(cli
, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE
<<8)|FILE_ATTRIBUTE_DIRECTORY
, list_fn
, &num_seen
);
6260 printf("num_seen = %d\n", num_seen
);
6261 if (num_seen
!= 1000)
6264 /* Delete everything. */
6265 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
6266 cli_list(cli
, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY
, del_fn
, cli
);
6267 cli_rmdir(cli
, "\\LISTDIR");
6270 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
6271 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
6272 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
6275 if (!torture_close_connection(cli
)) {
6279 printf("finished dirtest1\n");
6284 static bool run_error_map_extract(int dummy
) {
6286 static struct cli_state
*c_dos
;
6287 static struct cli_state
*c_nt
;
6299 /* NT-Error connection */
6301 disable_spnego
= true;
6302 if (!(c_nt
= open_nbt_connection())) {
6303 disable_spnego
= false;
6306 disable_spnego
= false;
6308 status
= cli_negprot(c_nt
, PROTOCOL_NT1
);
6310 if (!NT_STATUS_IS_OK(status
)) {
6311 printf("%s rejected the NT-error negprot (%s)\n", host
,
6317 status
= cli_session_setup(c_nt
, "", "", 0, "", 0, workgroup
);
6318 if (!NT_STATUS_IS_OK(status
)) {
6319 printf("%s rejected the NT-error initial session setup (%s)\n",host
, nt_errstr(status
));
6323 /* DOS-Error connection */
6325 disable_spnego
= true;
6326 force_dos_errors
= true;
6327 if (!(c_dos
= open_nbt_connection())) {
6328 disable_spnego
= false;
6329 force_dos_errors
= false;
6332 disable_spnego
= false;
6333 force_dos_errors
= false;
6335 status
= cli_negprot(c_dos
, PROTOCOL_NT1
);
6336 if (!NT_STATUS_IS_OK(status
)) {
6337 printf("%s rejected the DOS-error negprot (%s)\n", host
,
6339 cli_shutdown(c_dos
);
6343 status
= cli_session_setup(c_dos
, "", "", 0, "", 0, workgroup
);
6344 if (!NT_STATUS_IS_OK(status
)) {
6345 printf("%s rejected the DOS-error initial session setup (%s)\n",
6346 host
, nt_errstr(status
));
6350 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
6351 fstr_sprintf(user
, "%X", error
);
6353 status
= cli_session_setup(c_nt
, user
,
6354 password
, strlen(password
),
6355 password
, strlen(password
),
6357 if (NT_STATUS_IS_OK(status
)) {
6358 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6361 /* Case #1: 32-bit NT errors */
6362 if (cli_is_nt_error(c_nt
)) {
6363 nt_status
= cli_nt_error(c_nt
);
6365 printf("/** Dos error on NT connection! (%s) */\n",
6367 nt_status
= NT_STATUS(0xc0000000);
6370 status
= cli_session_setup(c_dos
, user
,
6371 password
, strlen(password
),
6372 password
, strlen(password
),
6374 if (NT_STATUS_IS_OK(status
)) {
6375 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6378 /* Case #1: 32-bit NT errors */
6379 if (!cli_is_dos_error(c_dos
)) {
6380 printf("/** NT error on DOS connection! (%s) */\n",
6382 errnum
= errclass
= 0;
6384 cli_dos_error(c_dos
, &errclass
, &errnum
);
6387 if (NT_STATUS_V(nt_status
) != error
) {
6388 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6389 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)),
6390 get_nt_error_c_code(talloc_tos(), nt_status
));
6393 printf("\t{%s,\t%s,\t%s},\n",
6394 smb_dos_err_class(errclass
),
6395 smb_dos_err_name(errclass
, errnum
),
6396 get_nt_error_c_code(talloc_tos(), NT_STATUS(error
)));
6401 static bool run_sesssetup_bench(int dummy
)
6403 static struct cli_state
*c
;
6404 const char *fname
= "\\file.dat";
6409 if (!torture_open_connection(&c
, 0)) {
6413 status
= cli_ntcreate(c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
6414 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
6415 FILE_DELETE_ON_CLOSE
, 0, &fnum
);
6416 if (!NT_STATUS_IS_OK(status
)) {
6417 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
6421 for (i
=0; i
<torture_numops
; i
++) {
6422 status
= cli_session_setup(
6424 password
, strlen(password
),
6425 password
, strlen(password
),
6427 if (!NT_STATUS_IS_OK(status
)) {
6428 d_printf("(%s) cli_session_setup failed: %s\n",
6429 __location__
, nt_errstr(status
));
6433 d_printf("\r%d ", (int)cli_state_get_uid(c
));
6435 status
= cli_ulogoff(c
);
6436 if (!NT_STATUS_IS_OK(status
)) {
6437 d_printf("(%s) cli_ulogoff failed: %s\n",
6438 __location__
, nt_errstr(status
));
6446 static bool subst_test(const char *str
, const char *user
, const char *domain
,
6447 uid_t uid
, gid_t gid
, const char *expected
)
6452 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
6454 if (strcmp(subst
, expected
) != 0) {
6455 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6456 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
6465 static void chain1_open_completion(struct tevent_req
*req
)
6469 status
= cli_open_recv(req
, &fnum
);
6472 d_printf("cli_open_recv returned %s: %d\n",
6474 NT_STATUS_IS_OK(status
) ? fnum
: -1);
6477 static void chain1_write_completion(struct tevent_req
*req
)
6481 status
= cli_write_andx_recv(req
, &written
);
6484 d_printf("cli_write_andx_recv returned %s: %d\n",
6486 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
6489 static void chain1_close_completion(struct tevent_req
*req
)
6492 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6494 status
= cli_close_recv(req
);
6499 d_printf("cli_close returned %s\n", nt_errstr(status
));
6502 static bool run_chain1(int dummy
)
6504 struct cli_state
*cli1
;
6505 struct event_context
*evt
= event_context_init(NULL
);
6506 struct tevent_req
*reqs
[3], *smbreqs
[3];
6508 const char *str
= "foobar";
6511 printf("starting chain1 test\n");
6512 if (!torture_open_connection(&cli1
, 0)) {
6516 cli_sockopt(cli1
, sockops
);
6518 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
6519 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
6520 if (reqs
[0] == NULL
) return false;
6521 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
6524 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
6525 (const uint8_t *)str
, 0, strlen(str
)+1,
6526 smbreqs
, 1, &smbreqs
[1]);
6527 if (reqs
[1] == NULL
) return false;
6528 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
6530 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
6531 if (reqs
[2] == NULL
) return false;
6532 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
6534 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6535 if (!NT_STATUS_IS_OK(status
)) {
6540 tevent_loop_once(evt
);
6543 torture_close_connection(cli1
);
6547 static void chain2_sesssetup_completion(struct tevent_req
*req
)
6550 status
= cli_session_setup_guest_recv(req
);
6551 d_printf("sesssetup returned %s\n", nt_errstr(status
));
6554 static void chain2_tcon_completion(struct tevent_req
*req
)
6556 bool *done
= (bool *)tevent_req_callback_data_void(req
);
6558 status
= cli_tcon_andx_recv(req
);
6559 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
6563 static bool run_chain2(int dummy
)
6565 struct cli_state
*cli1
;
6566 struct event_context
*evt
= event_context_init(NULL
);
6567 struct tevent_req
*reqs
[2], *smbreqs
[2];
6571 printf("starting chain2 test\n");
6572 status
= cli_start_connection(&cli1
, lp_netbios_name(), host
, NULL
,
6573 port_to_use
, Undefined
, 0);
6574 if (!NT_STATUS_IS_OK(status
)) {
6578 cli_sockopt(cli1
, sockops
);
6580 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
6582 if (reqs
[0] == NULL
) return false;
6583 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
6585 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
6586 "?????", NULL
, 0, &smbreqs
[1]);
6587 if (reqs
[1] == NULL
) return false;
6588 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
6590 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
6591 if (!NT_STATUS_IS_OK(status
)) {
6596 tevent_loop_once(evt
);
6599 torture_close_connection(cli1
);
6604 struct torture_createdel_state
{
6605 struct tevent_context
*ev
;
6606 struct cli_state
*cli
;
6609 static void torture_createdel_created(struct tevent_req
*subreq
);
6610 static void torture_createdel_closed(struct tevent_req
*subreq
);
6612 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
6613 struct tevent_context
*ev
,
6614 struct cli_state
*cli
,
6617 struct tevent_req
*req
, *subreq
;
6618 struct torture_createdel_state
*state
;
6620 req
= tevent_req_create(mem_ctx
, &state
,
6621 struct torture_createdel_state
);
6628 subreq
= cli_ntcreate_send(
6629 state
, ev
, cli
, name
, 0,
6630 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
6631 FILE_ATTRIBUTE_NORMAL
,
6632 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
6633 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
6635 if (tevent_req_nomem(subreq
, req
)) {
6636 return tevent_req_post(req
, ev
);
6638 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
6642 static void torture_createdel_created(struct tevent_req
*subreq
)
6644 struct tevent_req
*req
= tevent_req_callback_data(
6645 subreq
, struct tevent_req
);
6646 struct torture_createdel_state
*state
= tevent_req_data(
6647 req
, struct torture_createdel_state
);
6651 status
= cli_ntcreate_recv(subreq
, &fnum
);
6652 TALLOC_FREE(subreq
);
6653 if (!NT_STATUS_IS_OK(status
)) {
6654 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6655 nt_errstr(status
)));
6656 tevent_req_nterror(req
, status
);
6660 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
6661 if (tevent_req_nomem(subreq
, req
)) {
6664 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
6667 static void torture_createdel_closed(struct tevent_req
*subreq
)
6669 struct tevent_req
*req
= tevent_req_callback_data(
6670 subreq
, struct tevent_req
);
6673 status
= cli_close_recv(subreq
);
6674 if (!NT_STATUS_IS_OK(status
)) {
6675 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
6676 tevent_req_nterror(req
, status
);
6679 tevent_req_done(req
);
6682 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
6684 return tevent_req_simple_recv_ntstatus(req
);
6687 struct torture_createdels_state
{
6688 struct tevent_context
*ev
;
6689 struct cli_state
*cli
;
6690 const char *base_name
;
6694 struct tevent_req
**reqs
;
6697 static void torture_createdels_done(struct tevent_req
*subreq
);
6699 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
6700 struct tevent_context
*ev
,
6701 struct cli_state
*cli
,
6702 const char *base_name
,
6706 struct tevent_req
*req
;
6707 struct torture_createdels_state
*state
;
6710 req
= tevent_req_create(mem_ctx
, &state
,
6711 struct torture_createdels_state
);
6717 state
->base_name
= talloc_strdup(state
, base_name
);
6718 if (tevent_req_nomem(state
->base_name
, req
)) {
6719 return tevent_req_post(req
, ev
);
6721 state
->num_files
= MAX(num_parallel
, num_files
);
6723 state
->received
= 0;
6725 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
6726 if (tevent_req_nomem(state
->reqs
, req
)) {
6727 return tevent_req_post(req
, ev
);
6730 for (i
=0; i
<num_parallel
; i
++) {
6733 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6735 if (tevent_req_nomem(name
, req
)) {
6736 return tevent_req_post(req
, ev
);
6738 state
->reqs
[i
] = torture_createdel_send(
6739 state
->reqs
, state
->ev
, state
->cli
, name
);
6740 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6741 return tevent_req_post(req
, ev
);
6743 name
= talloc_move(state
->reqs
[i
], &name
);
6744 tevent_req_set_callback(state
->reqs
[i
],
6745 torture_createdels_done
, req
);
6751 static void torture_createdels_done(struct tevent_req
*subreq
)
6753 struct tevent_req
*req
= tevent_req_callback_data(
6754 subreq
, struct tevent_req
);
6755 struct torture_createdels_state
*state
= tevent_req_data(
6756 req
, struct torture_createdels_state
);
6757 size_t num_parallel
= talloc_array_length(state
->reqs
);
6762 status
= torture_createdel_recv(subreq
);
6763 if (!NT_STATUS_IS_OK(status
)){
6764 DEBUG(10, ("torture_createdel_recv returned %s\n",
6765 nt_errstr(status
)));
6766 TALLOC_FREE(subreq
);
6767 tevent_req_nterror(req
, status
);
6771 for (i
=0; i
<num_parallel
; i
++) {
6772 if (subreq
== state
->reqs
[i
]) {
6776 if (i
== num_parallel
) {
6777 DEBUG(10, ("received something we did not send\n"));
6778 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
6781 TALLOC_FREE(state
->reqs
[i
]);
6783 if (state
->sent
>= state
->num_files
) {
6784 tevent_req_done(req
);
6788 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
6790 if (tevent_req_nomem(name
, req
)) {
6793 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
6795 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
6798 name
= talloc_move(state
->reqs
[i
], &name
);
6799 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
6803 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
6805 return tevent_req_simple_recv_ntstatus(req
);
6808 struct swallow_notify_state
{
6809 struct tevent_context
*ev
;
6810 struct cli_state
*cli
;
6812 uint32_t completion_filter
;
6814 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
6818 static void swallow_notify_done(struct tevent_req
*subreq
);
6820 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
6821 struct tevent_context
*ev
,
6822 struct cli_state
*cli
,
6824 uint32_t completion_filter
,
6826 bool (*fn
)(uint32_t action
,
6831 struct tevent_req
*req
, *subreq
;
6832 struct swallow_notify_state
*state
;
6834 req
= tevent_req_create(mem_ctx
, &state
,
6835 struct swallow_notify_state
);
6842 state
->completion_filter
= completion_filter
;
6843 state
->recursive
= recursive
;
6847 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6848 0xffff, state
->completion_filter
,
6850 if (tevent_req_nomem(subreq
, req
)) {
6851 return tevent_req_post(req
, ev
);
6853 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6857 static void swallow_notify_done(struct tevent_req
*subreq
)
6859 struct tevent_req
*req
= tevent_req_callback_data(
6860 subreq
, struct tevent_req
);
6861 struct swallow_notify_state
*state
= tevent_req_data(
6862 req
, struct swallow_notify_state
);
6864 uint32_t i
, num_changes
;
6865 struct notify_change
*changes
;
6867 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
6868 TALLOC_FREE(subreq
);
6869 if (!NT_STATUS_IS_OK(status
)) {
6870 DEBUG(10, ("cli_notify_recv returned %s\n",
6871 nt_errstr(status
)));
6872 tevent_req_nterror(req
, status
);
6876 for (i
=0; i
<num_changes
; i
++) {
6877 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
6879 TALLOC_FREE(changes
);
6881 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
6882 0xffff, state
->completion_filter
,
6884 if (tevent_req_nomem(subreq
, req
)) {
6887 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
6890 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
6892 if (DEBUGLEVEL
> 5) {
6893 d_printf("%d %s\n", (int)action
, name
);
6898 static void notify_bench_done(struct tevent_req
*req
)
6900 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
6904 static bool run_notify_bench(int dummy
)
6906 const char *dname
= "\\notify-bench";
6907 struct tevent_context
*ev
;
6910 struct tevent_req
*req1
;
6911 struct tevent_req
*req2
= NULL
;
6912 int i
, num_unc_names
;
6913 int num_finished
= 0;
6915 printf("starting notify-bench test\n");
6917 if (use_multishare_conn
) {
6919 unc_list
= file_lines_load(multishare_conn_fname
,
6920 &num_unc_names
, 0, NULL
);
6921 if (!unc_list
|| num_unc_names
<= 0) {
6922 d_printf("Failed to load unc names list from '%s'\n",
6923 multishare_conn_fname
);
6926 TALLOC_FREE(unc_list
);
6931 ev
= tevent_context_init(talloc_tos());
6933 d_printf("tevent_context_init failed\n");
6937 for (i
=0; i
<num_unc_names
; i
++) {
6938 struct cli_state
*cli
;
6941 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6943 if (base_fname
== NULL
) {
6947 if (!torture_open_connection(&cli
, i
)) {
6951 status
= cli_ntcreate(cli
, dname
, 0,
6952 MAXIMUM_ALLOWED_ACCESS
,
6953 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
6955 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
6958 if (!NT_STATUS_IS_OK(status
)) {
6959 d_printf("Could not create %s: %s\n", dname
,
6964 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
6965 FILE_NOTIFY_CHANGE_FILE_NAME
|
6966 FILE_NOTIFY_CHANGE_DIR_NAME
|
6967 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
6968 FILE_NOTIFY_CHANGE_LAST_WRITE
,
6969 false, print_notifies
, NULL
);
6971 d_printf("Could not create notify request\n");
6975 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
6976 base_fname
, 10, torture_numops
);
6978 d_printf("Could not create createdels request\n");
6981 TALLOC_FREE(base_fname
);
6983 tevent_req_set_callback(req2
, notify_bench_done
,
6987 while (num_finished
< num_unc_names
) {
6989 ret
= tevent_loop_once(ev
);
6991 d_printf("tevent_loop_once failed\n");
6996 if (!tevent_req_poll(req2
, ev
)) {
6997 d_printf("tevent_req_poll failed\n");
7000 status
= torture_createdels_recv(req2
);
7001 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
7006 static bool run_mangle1(int dummy
)
7008 struct cli_state
*cli
;
7009 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
7013 time_t change_time
, access_time
, write_time
;
7017 printf("starting mangle1 test\n");
7018 if (!torture_open_connection(&cli
, 0)) {
7022 cli_sockopt(cli
, sockops
);
7024 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
7025 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
7027 if (!NT_STATUS_IS_OK(status
)) {
7028 d_printf("open %s failed: %s\n", fname
, nt_errstr(status
));
7031 cli_close(cli
, fnum
);
7033 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
7034 if (!NT_STATUS_IS_OK(status
)) {
7035 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7039 d_printf("alt_name: %s\n", alt_name
);
7041 status
= cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
);
7042 if (!NT_STATUS_IS_OK(status
)) {
7043 d_printf("cli_open(%s) failed: %s\n", alt_name
,
7047 cli_close(cli
, fnum
);
7049 status
= cli_qpathinfo1(cli
, alt_name
, &change_time
, &access_time
,
7050 &write_time
, &size
, &mode
);
7051 if (!NT_STATUS_IS_OK(status
)) {
7052 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name
,
7060 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
7062 size_t *to_pull
= (size_t *)priv
;
7063 size_t thistime
= *to_pull
;
7065 thistime
= MIN(thistime
, n
);
7066 if (thistime
== 0) {
7070 memset(buf
, 0, thistime
);
7071 *to_pull
-= thistime
;
7075 static bool run_windows_write(int dummy
)
7077 struct cli_state
*cli1
;
7081 const char *fname
= "\\writetest.txt";
7082 struct timeval start_time
;
7087 printf("starting windows_write test\n");
7088 if (!torture_open_connection(&cli1
, 0)) {
7092 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
7093 if (!NT_STATUS_IS_OK(status
)) {
7094 printf("open failed (%s)\n", nt_errstr(status
));
7098 cli_sockopt(cli1
, sockops
);
7100 start_time
= timeval_current();
7102 for (i
=0; i
<torture_numops
; i
++) {
7104 off_t start
= i
* torture_blocksize
;
7105 size_t to_pull
= torture_blocksize
- 1;
7107 status
= cli_writeall(cli1
, fnum
, 0, &c
,
7108 start
+ torture_blocksize
- 1, 1, NULL
);
7109 if (!NT_STATUS_IS_OK(status
)) {
7110 printf("cli_write failed: %s\n", nt_errstr(status
));
7114 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
7115 null_source
, &to_pull
);
7116 if (!NT_STATUS_IS_OK(status
)) {
7117 printf("cli_push returned: %s\n", nt_errstr(status
));
7122 seconds
= timeval_elapsed(&start_time
);
7123 kbytes
= (double)torture_blocksize
* torture_numops
;
7126 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
7127 (double)seconds
, (int)(kbytes
/seconds
));
7131 cli_close(cli1
, fnum
);
7132 cli_unlink(cli1
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7133 torture_close_connection(cli1
);
7137 static bool run_cli_echo(int dummy
)
7139 struct cli_state
*cli
;
7142 printf("starting cli_echo test\n");
7143 if (!torture_open_connection(&cli
, 0)) {
7146 cli_sockopt(cli
, sockops
);
7148 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
7150 d_printf("cli_echo returned %s\n", nt_errstr(status
));
7152 torture_close_connection(cli
);
7153 return NT_STATUS_IS_OK(status
);
7156 static bool run_uid_regression_test(int dummy
)
7158 static struct cli_state
*cli
;
7161 bool correct
= True
;
7164 printf("starting uid regression test\n");
7166 if (!torture_open_connection(&cli
, 0)) {
7170 cli_sockopt(cli
, sockops
);
7172 /* Ok - now save then logoff our current user. */
7173 old_vuid
= cli_state_get_uid(cli
);
7175 status
= cli_ulogoff(cli
);
7176 if (!NT_STATUS_IS_OK(status
)) {
7177 d_printf("(%s) cli_ulogoff failed: %s\n",
7178 __location__
, nt_errstr(status
));
7183 cli_state_set_uid(cli
, old_vuid
);
7185 /* Try an operation. */
7186 status
= cli_mkdir(cli
, "\\uid_reg_test");
7187 if (NT_STATUS_IS_OK(status
)) {
7188 d_printf("(%s) cli_mkdir succeeded\n",
7193 /* Should be bad uid. */
7194 if (!check_error(__LINE__
, status
, ERRSRV
, ERRbaduid
,
7195 NT_STATUS_USER_SESSION_DELETED
)) {
7201 old_cnum
= cli_state_get_tid(cli
);
7203 /* Now try a SMBtdis with the invald vuid set to zero. */
7204 cli_state_set_uid(cli
, 0);
7206 /* This should succeed. */
7207 status
= cli_tdis(cli
);
7209 if (NT_STATUS_IS_OK(status
)) {
7210 d_printf("First tdis with invalid vuid should succeed.\n");
7212 d_printf("First tdis failed (%s)\n", nt_errstr(status
));
7217 cli_state_set_uid(cli
, old_vuid
);
7218 cli_state_set_tid(cli
, old_cnum
);
7220 /* This should fail. */
7221 status
= cli_tdis(cli
);
7222 if (NT_STATUS_IS_OK(status
)) {
7223 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7227 /* Should be bad tid. */
7228 if (!check_error(__LINE__
, status
, ERRSRV
, ERRinvnid
,
7229 NT_STATUS_NETWORK_NAME_DELETED
)) {
7235 cli_rmdir(cli
, "\\uid_reg_test");
7244 static const char *illegal_chars
= "*\\/?<>|\":";
7245 static char force_shortname_chars
[] = " +,.[];=\177";
7247 static NTSTATUS
shortname_del_fn(const char *mnt
, struct file_info
*finfo
,
7248 const char *mask
, void *state
)
7250 struct cli_state
*pcli
= (struct cli_state
*)state
;
7252 NTSTATUS status
= NT_STATUS_OK
;
7254 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
7256 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
7257 return NT_STATUS_OK
;
7259 if (finfo
->mode
& FILE_ATTRIBUTE_DIRECTORY
) {
7260 status
= cli_rmdir(pcli
, fname
);
7261 if (!NT_STATUS_IS_OK(status
)) {
7262 printf("del_fn: failed to rmdir %s\n,", fname
);
7265 status
= cli_unlink(pcli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7266 if (!NT_STATUS_IS_OK(status
)) {
7267 printf("del_fn: failed to unlink %s\n,", fname
);
7279 static NTSTATUS
shortname_list_fn(const char *mnt
, struct file_info
*finfo
,
7280 const char *name
, void *state
)
7282 struct sn_state
*s
= (struct sn_state
*)state
;
7286 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7287 i
, finfo
->name
, finfo
->short_name
);
7290 if (strchr(force_shortname_chars
, i
)) {
7291 if (!finfo
->short_name
) {
7292 /* Shortname not created when it should be. */
7293 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7294 __location__
, finfo
->name
, i
);
7297 } else if (finfo
->short_name
){
7298 /* Shortname created when it should not be. */
7299 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7300 __location__
, finfo
->short_name
, finfo
->name
);
7304 return NT_STATUS_OK
;
7307 static bool run_shortname_test(int dummy
)
7309 static struct cli_state
*cli
;
7310 bool correct
= True
;
7316 printf("starting shortname test\n");
7318 if (!torture_open_connection(&cli
, 0)) {
7322 cli_sockopt(cli
, sockops
);
7324 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7325 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7326 cli_rmdir(cli
, "\\shortname");
7328 status
= cli_mkdir(cli
, "\\shortname");
7329 if (!NT_STATUS_IS_OK(status
)) {
7330 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7331 __location__
, nt_errstr(status
));
7336 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
7337 strlcat(fname
, "test .txt", sizeof(fname
));
7341 for (i
= 32; i
< 128; i
++) {
7342 uint16_t fnum
= (uint16_t)-1;
7346 if (strchr(illegal_chars
, i
)) {
7351 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
7352 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
7353 if (!NT_STATUS_IS_OK(status
)) {
7354 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7355 __location__
, fname
, nt_errstr(status
));
7359 cli_close(cli
, fnum
);
7362 status
= cli_list(cli
, "\\shortname\\test*.*", 0,
7363 shortname_list_fn
, &s
);
7364 if (s
.matched
!= 1) {
7365 d_printf("(%s) failed to list %s: %s\n",
7366 __location__
, fname
, nt_errstr(status
));
7371 status
= cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7372 if (!NT_STATUS_IS_OK(status
)) {
7373 d_printf("(%s) failed to delete %s: %s\n",
7374 __location__
, fname
, nt_errstr(status
));
7387 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
7388 cli_list(cli
, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY
, shortname_del_fn
, cli
);
7389 cli_rmdir(cli
, "\\shortname");
7390 torture_close_connection(cli
);
7394 static void pagedsearch_cb(struct tevent_req
*req
)
7397 struct tldap_message
*msg
;
7400 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
7401 if (rc
!= TLDAP_SUCCESS
) {
7402 d_printf("tldap_search_paged_recv failed: %s\n",
7403 tldap_err2string(rc
));
7406 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
7410 if (!tldap_entry_dn(msg
, &dn
)) {
7411 d_printf("tldap_entry_dn failed\n");
7414 d_printf("%s\n", dn
);
7418 static bool run_tldap(int dummy
)
7420 struct tldap_context
*ld
;
7423 struct sockaddr_storage addr
;
7424 struct tevent_context
*ev
;
7425 struct tevent_req
*req
;
7429 if (!resolve_name(host
, &addr
, 0, false)) {
7430 d_printf("could not find host %s\n", host
);
7433 status
= open_socket_out(&addr
, 389, 9999, &fd
);
7434 if (!NT_STATUS_IS_OK(status
)) {
7435 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
7439 ld
= tldap_context_create(talloc_tos(), fd
);
7442 d_printf("tldap_context_create failed\n");
7446 rc
= tldap_fetch_rootdse(ld
);
7447 if (rc
!= TLDAP_SUCCESS
) {
7448 d_printf("tldap_fetch_rootdse failed: %s\n",
7449 tldap_errstr(talloc_tos(), ld
, rc
));
7453 basedn
= tldap_talloc_single_attribute(
7454 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
7455 if (basedn
== NULL
) {
7456 d_printf("no defaultNamingContext\n");
7459 d_printf("defaultNamingContext: %s\n", basedn
);
7461 ev
= tevent_context_init(talloc_tos());
7463 d_printf("tevent_context_init failed\n");
7467 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
7468 TLDAP_SCOPE_SUB
, "(objectclass=*)",
7470 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
7472 d_printf("tldap_search_paged_send failed\n");
7475 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
7477 tevent_req_poll(req
, ev
);
7481 /* test search filters against rootDSE */
7482 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7483 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7485 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
7486 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
7487 talloc_tos(), NULL
, NULL
);
7488 if (rc
!= TLDAP_SUCCESS
) {
7489 d_printf("tldap_search with complex filter failed: %s\n",
7490 tldap_errstr(talloc_tos(), ld
, rc
));
7498 /* Torture test to ensure no regression of :
7499 https://bugzilla.samba.org/show_bug.cgi?id=7084
7502 static bool run_dir_createtime(int dummy
)
7504 struct cli_state
*cli
;
7505 const char *dname
= "\\testdir";
7506 const char *fname
= "\\testdir\\testfile";
7508 struct timespec create_time
;
7509 struct timespec create_time1
;
7513 if (!torture_open_connection(&cli
, 0)) {
7517 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7518 cli_rmdir(cli
, dname
);
7520 status
= cli_mkdir(cli
, dname
);
7521 if (!NT_STATUS_IS_OK(status
)) {
7522 printf("mkdir failed: %s\n", nt_errstr(status
));
7526 status
= cli_qpathinfo2(cli
, dname
, &create_time
, NULL
, NULL
, NULL
,
7528 if (!NT_STATUS_IS_OK(status
)) {
7529 printf("cli_qpathinfo2 returned %s\n",
7534 /* Sleep 3 seconds, then create a file. */
7537 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
7539 if (!NT_STATUS_IS_OK(status
)) {
7540 printf("cli_open failed: %s\n", nt_errstr(status
));
7544 status
= cli_qpathinfo2(cli
, dname
, &create_time1
, NULL
, NULL
, NULL
,
7546 if (!NT_STATUS_IS_OK(status
)) {
7547 printf("cli_qpathinfo2 (2) returned %s\n",
7552 if (timespec_compare(&create_time1
, &create_time
)) {
7553 printf("run_dir_createtime: create time was updated (error)\n");
7555 printf("run_dir_createtime: create time was not updated (correct)\n");
7561 cli_unlink(cli
, fname
, FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7562 cli_rmdir(cli
, dname
);
7563 if (!torture_close_connection(cli
)) {
7570 static bool run_streamerror(int dummy
)
7572 struct cli_state
*cli
;
7573 const char *dname
= "\\testdir";
7574 const char *streamname
=
7575 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7577 time_t change_time
, access_time
, write_time
;
7579 uint16_t mode
, fnum
;
7582 if (!torture_open_connection(&cli
, 0)) {
7586 cli_unlink(cli
, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
);
7587 cli_rmdir(cli
, dname
);
7589 status
= cli_mkdir(cli
, dname
);
7590 if (!NT_STATUS_IS_OK(status
)) {
7591 printf("mkdir failed: %s\n", nt_errstr(status
));
7595 cli_qpathinfo1(cli
, streamname
, &change_time
, &access_time
, &write_time
,
7597 status
= cli_nt_error(cli
);
7599 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7600 printf("pathinfo returned %s, expected "
7601 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7606 status
= cli_ntcreate(cli
, streamname
, 0x16,
7607 FILE_READ_DATA
|FILE_READ_EA
|
7608 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
7609 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
7610 FILE_OPEN
, 0, 0, &fnum
);
7612 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
7613 printf("ntcreate returned %s, expected "
7614 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7620 cli_rmdir(cli
, dname
);
7624 static bool run_local_substitute(int dummy
)
7628 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
7629 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7630 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7631 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7632 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
7633 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
7634 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7635 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7637 /* Different captialization rules in sub_basic... */
7639 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7645 static bool run_local_base64(int dummy
)
7650 for (i
=1; i
<2000; i
++) {
7651 DATA_BLOB blob1
, blob2
;
7654 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
7656 generate_random_buffer(blob1
.data
, blob1
.length
);
7658 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
7660 d_fprintf(stderr
, "base64_encode_data_blob failed "
7661 "for %d bytes\n", i
);
7664 blob2
= base64_decode_data_blob(b64
);
7667 if (data_blob_cmp(&blob1
, &blob2
)) {
7668 d_fprintf(stderr
, "data_blob_cmp failed for %d "
7672 TALLOC_FREE(blob1
.data
);
7673 data_blob_free(&blob2
);
7678 static bool run_local_gencache(int dummy
)
7684 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
7685 d_printf("%s: gencache_set() failed\n", __location__
);
7689 if (!gencache_get("foo", NULL
, NULL
)) {
7690 d_printf("%s: gencache_get() failed\n", __location__
);
7694 if (!gencache_get("foo", &val
, &tm
)) {
7695 d_printf("%s: gencache_get() failed\n", __location__
);
7699 if (strcmp(val
, "bar") != 0) {
7700 d_printf("%s: gencache_get() returned %s, expected %s\n",
7701 __location__
, val
, "bar");
7708 if (!gencache_del("foo")) {
7709 d_printf("%s: gencache_del() failed\n", __location__
);
7712 if (gencache_del("foo")) {
7713 d_printf("%s: second gencache_del() succeeded\n",
7718 if (gencache_get("foo", &val
, &tm
)) {
7719 d_printf("%s: gencache_get() on deleted entry "
7720 "succeeded\n", __location__
);
7724 blob
= data_blob_string_const_null("bar");
7725 tm
= time(NULL
) + 60;
7727 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
7728 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
7732 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7733 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
7737 if (strcmp((const char *)blob
.data
, "bar") != 0) {
7738 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7739 __location__
, (const char *)blob
.data
, "bar");
7740 data_blob_free(&blob
);
7744 data_blob_free(&blob
);
7746 if (!gencache_del("foo")) {
7747 d_printf("%s: gencache_del() failed\n", __location__
);
7750 if (gencache_del("foo")) {
7751 d_printf("%s: second gencache_del() succeeded\n",
7756 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
7757 d_printf("%s: gencache_get_data_blob() on deleted entry "
7758 "succeeded\n", __location__
);
7765 static bool rbt_testval(struct db_context
*db
, const char *key
,
7768 struct db_record
*rec
;
7769 TDB_DATA data
= string_tdb_data(value
);
7774 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7776 d_fprintf(stderr
, "fetch_locked failed\n");
7779 status
= dbwrap_record_store(rec
, data
, 0);
7780 if (!NT_STATUS_IS_OK(status
)) {
7781 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
7786 rec
= dbwrap_fetch_locked(db
, db
, string_tdb_data(key
));
7788 d_fprintf(stderr
, "second fetch_locked failed\n");
7792 dbvalue
= dbwrap_record_get_value(rec
);
7793 if ((dbvalue
.dsize
!= data
.dsize
)
7794 || (memcmp(dbvalue
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
7795 d_fprintf(stderr
, "Got wrong data back\n");
7805 static bool run_local_rbtree(int dummy
)
7807 struct db_context
*db
;
7811 db
= db_open_rbt(NULL
);
7814 d_fprintf(stderr
, "db_open_rbt failed\n");
7818 for (i
=0; i
<1000; i
++) {
7821 if (asprintf(&key
, "key%ld", random()) == -1) {
7824 if (asprintf(&value
, "value%ld", random()) == -1) {
7829 if (!rbt_testval(db
, key
, value
)) {
7836 if (asprintf(&value
, "value%ld", random()) == -1) {
7841 if (!rbt_testval(db
, key
, value
)) {
7860 local test for character set functions
7862 This is a very simple test for the functionality in convert_string_error()
7864 static bool run_local_convert_string(int dummy
)
7866 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
7867 const char *test_strings
[2] = { "March", "M\303\244rz" };
7871 for (i
=0; i
<2; i
++) {
7872 const char *str
= test_strings
[i
];
7873 int len
= strlen(str
);
7874 size_t converted_size
;
7877 memset(dst
, 'X', sizeof(dst
));
7879 /* first try with real source length */
7880 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7885 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7889 if (converted_size
!= len
) {
7890 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7891 str
, len
, (int)converted_size
);
7895 if (strncmp(str
, dst
, converted_size
) != 0) {
7896 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7900 if (strlen(str
) != converted_size
) {
7901 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7902 (int)strlen(str
), (int)converted_size
);
7906 if (dst
[converted_size
] != 'X') {
7907 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7911 /* now with srclen==-1, this causes the nul to be
7913 ret
= convert_string_error(CH_UNIX
, CH_UTF8
,
7918 d_fprintf(stderr
, "Failed to convert '%s' to CH_DISPLAY\n", str
);
7922 if (converted_size
!= len
+1) {
7923 d_fprintf(stderr
, "Converted size of '%s' should be %d - got %d\n",
7924 str
, len
, (int)converted_size
);
7928 if (strncmp(str
, dst
, converted_size
) != 0) {
7929 d_fprintf(stderr
, "Expected '%s' to match '%s'\n", str
, dst
);
7933 if (len
+1 != converted_size
) {
7934 d_fprintf(stderr
, "Expected '%s' length %d - got %d\n", str
,
7935 len
+1, (int)converted_size
);
7939 if (dst
[converted_size
] != 'X') {
7940 d_fprintf(stderr
, "Expected no termination of '%s'\n", dst
);
7947 TALLOC_FREE(tmp_ctx
);
7950 TALLOC_FREE(tmp_ctx
);
7955 struct talloc_dict_test
{
7959 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
7961 int *count
= (int *)priv
;
7966 static bool run_local_talloc_dict(int dummy
)
7968 struct talloc_dict
*dict
;
7969 struct talloc_dict_test
*t
;
7972 dict
= talloc_dict_init(talloc_tos());
7977 t
= talloc(talloc_tos(), struct talloc_dict_test
);
7984 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
7989 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
8002 static bool run_local_string_to_sid(int dummy
) {
8005 if (string_to_sid(&sid
, "S--1-5-32-545")) {
8006 printf("allowing S--1-5-32-545\n");
8009 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
8010 printf("allowing S-1-5-32-+545\n");
8013 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")) {
8014 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8017 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
8018 printf("allowing S-1-5-32-545-abc\n");
8021 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
8022 printf("could not parse S-1-5-32-545\n");
8025 if (!dom_sid_equal(&sid
, &global_sid_Builtin_Users
)) {
8026 printf("mis-parsed S-1-5-32-545 as %s\n",
8027 sid_string_tos(&sid
));
8033 static bool run_local_binary_to_sid(int dummy
) {
8034 struct dom_sid
*sid
= talloc(NULL
, struct dom_sid
);
8035 static const char good_binary_sid
[] = {
8036 0x1, /* revision number */
8038 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8039 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8040 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8041 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8042 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8043 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8044 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8045 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8046 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8047 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8048 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8049 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8050 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8051 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8052 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8053 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8056 static const char long_binary_sid
[] = {
8057 0x1, /* revision number */
8059 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8060 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8061 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8062 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8063 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8067 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8068 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8069 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8070 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8071 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8072 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8073 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8074 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8075 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8076 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8077 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8080 static const char long_binary_sid2
[] = {
8081 0x1, /* revision number */
8083 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8084 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8098 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8099 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8100 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8101 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8102 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8103 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8104 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8105 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8106 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8107 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8108 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8109 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8110 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8111 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8112 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8113 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8114 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8115 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8118 if (!sid_parse(good_binary_sid
, sizeof(good_binary_sid
), sid
)) {
8121 if (sid_parse(long_binary_sid2
, sizeof(long_binary_sid2
), sid
)) {
8124 if (sid_parse(long_binary_sid
, sizeof(long_binary_sid
), sid
)) {
8130 /* Split a path name into filename and stream name components. Canonicalise
8131 * such that an implicit $DATA token is always explicit.
8133 * The "specification" of this function can be found in the
8134 * run_local_stream_name() function in torture.c, I've tried those
8135 * combinations against a W2k3 server.
8138 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
8139 char **pbase
, char **pstream
)
8142 char *stream
= NULL
;
8143 char *sname
; /* stream name */
8144 const char *stype
; /* stream type */
8146 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
8148 sname
= strchr_m(fname
, ':');
8150 if (lp_posix_pathnames() || (sname
== NULL
)) {
8151 if (pbase
!= NULL
) {
8152 base
= talloc_strdup(mem_ctx
, fname
);
8153 NT_STATUS_HAVE_NO_MEMORY(base
);
8158 if (pbase
!= NULL
) {
8159 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
8160 NT_STATUS_HAVE_NO_MEMORY(base
);
8165 stype
= strchr_m(sname
, ':');
8167 if (stype
== NULL
) {
8168 sname
= talloc_strdup(mem_ctx
, sname
);
8172 if (strcasecmp_m(stype
, ":$DATA") != 0) {
8174 * If there is an explicit stream type, so far we only
8175 * allow $DATA. Is there anything else allowed? -- vl
8177 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
8179 return NT_STATUS_OBJECT_NAME_INVALID
;
8181 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
8185 if (sname
== NULL
) {
8187 return NT_STATUS_NO_MEMORY
;
8190 if (sname
[0] == '\0') {
8192 * no stream name, so no stream
8197 if (pstream
!= NULL
) {
8198 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
8199 if (stream
== NULL
) {
8202 return NT_STATUS_NO_MEMORY
;
8205 * upper-case the type field
8207 strupper_m(strchr_m(stream
, ':')+1);
8211 if (pbase
!= NULL
) {
8214 if (pstream
!= NULL
) {
8217 return NT_STATUS_OK
;
8220 static bool test_stream_name(const char *fname
, const char *expected_base
,
8221 const char *expected_stream
,
8222 NTSTATUS expected_status
)
8226 char *stream
= NULL
;
8228 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
8229 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
8233 if (!NT_STATUS_IS_OK(status
)) {
8237 if (base
== NULL
) goto error
;
8239 if (strcmp(expected_base
, base
) != 0) goto error
;
8241 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
8242 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
8244 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
8248 TALLOC_FREE(stream
);
8252 d_fprintf(stderr
, "Do test_stream(%s, %s, %s, %s)\n",
8253 fname
, expected_base
? expected_base
: "<NULL>",
8254 expected_stream
? expected_stream
: "<NULL>",
8255 nt_errstr(expected_status
));
8256 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
8257 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
8260 TALLOC_FREE(stream
);
8264 static bool run_local_stream_name(int dummy
)
8268 ret
&= test_stream_name(
8269 "bla", "bla", NULL
, NT_STATUS_OK
);
8270 ret
&= test_stream_name(
8271 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
8272 ret
&= test_stream_name(
8273 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8274 ret
&= test_stream_name(
8275 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8276 ret
&= test_stream_name(
8277 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
8278 ret
&= test_stream_name(
8279 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
8280 ret
&= test_stream_name(
8281 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
8282 ret
&= test_stream_name(
8283 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
8288 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
8290 if (a
.length
!= b
.length
) {
8291 printf("a.length=%d != b.length=%d\n",
8292 (int)a
.length
, (int)b
.length
);
8295 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
8296 printf("a.data and b.data differ\n");
8302 static bool run_local_memcache(int dummy
)
8304 struct memcache
*cache
;
8306 DATA_BLOB d1
, d2
, d3
;
8307 DATA_BLOB v1
, v2
, v3
;
8309 TALLOC_CTX
*mem_ctx
;
8311 size_t size1
, size2
;
8314 cache
= memcache_init(NULL
, 100);
8316 if (cache
== NULL
) {
8317 printf("memcache_init failed\n");
8321 d1
= data_blob_const("d1", 2);
8322 d2
= data_blob_const("d2", 2);
8323 d3
= data_blob_const("d3", 2);
8325 k1
= data_blob_const("d1", 2);
8326 k2
= data_blob_const("d2", 2);
8328 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
8329 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
8331 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
8332 printf("could not find k1\n");
8335 if (!data_blob_equal(d1
, v1
)) {
8339 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8340 printf("could not find k2\n");
8343 if (!data_blob_equal(d2
, v2
)) {
8347 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
8349 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
8350 printf("could not find replaced k1\n");
8353 if (!data_blob_equal(d3
, v3
)) {
8357 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
8359 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
8360 printf("Did find k2, should have been purged\n");
8366 cache
= memcache_init(NULL
, 0);
8368 mem_ctx
= talloc_init("foo");
8370 str1
= talloc_strdup(mem_ctx
, "string1");
8371 str2
= talloc_strdup(mem_ctx
, "string2");
8373 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8374 data_blob_string_const("torture"), &str1
);
8375 size1
= talloc_total_size(cache
);
8377 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
8378 data_blob_string_const("torture"), &str2
);
8379 size2
= talloc_total_size(cache
);
8381 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
8383 if (size2
> size1
) {
8384 printf("memcache leaks memory!\n");
8394 static void wbclient_done(struct tevent_req
*req
)
8397 struct winbindd_response
*wb_resp
;
8398 int *i
= (int *)tevent_req_callback_data_void(req
);
8400 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
8403 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
8406 static bool run_local_wbclient(int dummy
)
8408 struct event_context
*ev
;
8409 struct wb_context
**wb_ctx
;
8410 struct winbindd_request wb_req
;
8411 bool result
= false;
8414 BlockSignals(True
, SIGPIPE
);
8416 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
8421 wb_ctx
= talloc_array(ev
, struct wb_context
*, nprocs
);
8422 if (wb_ctx
== NULL
) {
8426 ZERO_STRUCT(wb_req
);
8427 wb_req
.cmd
= WINBINDD_PING
;
8429 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
8431 for (i
=0; i
<nprocs
; i
++) {
8432 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
8433 if (wb_ctx
[i
] == NULL
) {
8436 for (j
=0; j
<torture_numops
; j
++) {
8437 struct tevent_req
*req
;
8438 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
8439 (j
% 2) == 0, &wb_req
);
8443 tevent_req_set_callback(req
, wbclient_done
, &i
);
8449 while (i
< nprocs
* torture_numops
) {
8450 tevent_loop_once(ev
);
8459 static void getaddrinfo_finished(struct tevent_req
*req
)
8461 char *name
= (char *)tevent_req_callback_data_void(req
);
8462 struct addrinfo
*ainfo
;
8465 res
= getaddrinfo_recv(req
, &ainfo
);
8467 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
8470 d_printf("gai(%s) succeeded\n", name
);
8471 freeaddrinfo(ainfo
);
8474 static bool run_getaddrinfo_send(int dummy
)
8476 TALLOC_CTX
*frame
= talloc_stackframe();
8477 struct fncall_context
*ctx
;
8478 struct tevent_context
*ev
;
8479 bool result
= false;
8480 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
8481 "www.slashdot.org", "heise.de" };
8482 struct tevent_req
*reqs
[4];
8485 ev
= event_context_init(frame
);
8490 ctx
= fncall_context_init(frame
, 4);
8492 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
8493 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
8495 if (reqs
[i
] == NULL
) {
8498 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
8499 discard_const_p(void, names
[i
]));
8502 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
8503 tevent_loop_once(ev
);
8512 static bool dbtrans_inc(struct db_context
*db
)
8514 struct db_record
*rec
;
8520 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8522 printf(__location__
"fetch_lock failed\n");
8526 value
= dbwrap_record_get_value(rec
);
8528 if (value
.dsize
!= sizeof(uint32_t)) {
8529 printf(__location__
"value.dsize = %d\n",
8534 val
= (uint32_t *)value
.dptr
;
8537 status
= dbwrap_record_store(rec
, make_tdb_data((uint8_t *)val
,
8540 if (!NT_STATUS_IS_OK(status
)) {
8541 printf(__location__
"store failed: %s\n",
8552 static bool run_local_dbtrans(int dummy
)
8554 struct db_context
*db
;
8555 struct db_record
*rec
;
8561 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
8562 O_RDWR
|O_CREAT
, 0600);
8564 printf("Could not open transtest.db\n");
8568 res
= dbwrap_transaction_start(db
);
8570 printf(__location__
"transaction_start failed\n");
8574 rec
= dbwrap_fetch_locked(db
, db
, string_term_tdb_data("transtest"));
8576 printf(__location__
"fetch_lock failed\n");
8580 value
= dbwrap_record_get_value(rec
);
8582 if (value
.dptr
== NULL
) {
8584 status
= dbwrap_record_store(
8585 rec
, make_tdb_data((uint8_t *)&initial
,
8588 if (!NT_STATUS_IS_OK(status
)) {
8589 printf(__location__
"store returned %s\n",
8597 res
= dbwrap_transaction_commit(db
);
8599 printf(__location__
"transaction_commit failed\n");
8607 res
= dbwrap_transaction_start(db
);
8609 printf(__location__
"transaction_start failed\n");
8613 status
= dbwrap_fetch_uint32(db
, "transtest", &val
);
8614 if (!NT_STATUS_IS_OK(status
)) {
8615 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8620 for (i
=0; i
<10; i
++) {
8621 if (!dbtrans_inc(db
)) {
8626 status
= dbwrap_fetch_uint32(db
, "transtest", &val2
);
8627 if (!NT_STATUS_IS_OK(status
)) {
8628 printf(__location__
"dbwrap_fetch_uint32 failed: %s\n",
8633 if (val2
!= val
+ 10) {
8634 printf(__location__
"val=%d, val2=%d\n",
8635 (int)val
, (int)val2
);
8639 printf("val2=%d\r", val2
);
8641 res
= dbwrap_transaction_commit(db
);
8643 printf(__location__
"transaction_commit failed\n");
8653 * Just a dummy test to be run under a debugger. There's no real way
8654 * to inspect the tevent_select specific function from outside of
8658 static bool run_local_tevent_select(int dummy
)
8660 struct tevent_context
*ev
;
8661 struct tevent_fd
*fd1
, *fd2
;
8662 bool result
= false;
8664 ev
= tevent_context_init_byname(NULL
, "select");
8666 d_fprintf(stderr
, "tevent_context_init_byname failed\n");
8670 fd1
= tevent_add_fd(ev
, ev
, 2, 0, NULL
, NULL
);
8672 d_fprintf(stderr
, "tevent_add_fd failed\n");
8675 fd2
= tevent_add_fd(ev
, ev
, 3, 0, NULL
, NULL
);
8677 d_fprintf(stderr
, "tevent_add_fd failed\n");
8682 fd2
= tevent_add_fd(ev
, ev
, 1, 0, NULL
, NULL
);
8684 d_fprintf(stderr
, "tevent_add_fd failed\n");
8694 static double create_procs(bool (*fn
)(int), bool *result
)
8697 volatile pid_t
*child_status
;
8698 volatile bool *child_status_out
;
8701 struct timeval start
;
8705 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
8706 if (!child_status
) {
8707 printf("Failed to setup shared memory\n");
8711 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
8712 if (!child_status_out
) {
8713 printf("Failed to setup result status shared memory\n");
8717 for (i
= 0; i
< nprocs
; i
++) {
8718 child_status
[i
] = 0;
8719 child_status_out
[i
] = True
;
8722 start
= timeval_current();
8724 for (i
=0;i
<nprocs
;i
++) {
8727 pid_t mypid
= getpid();
8728 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
8730 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
8733 if (torture_open_connection(¤t_cli
, i
)) break;
8735 printf("pid %d failed to start\n", (int)getpid());
8741 child_status
[i
] = getpid();
8743 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
8745 child_status_out
[i
] = fn(i
);
8752 for (i
=0;i
<nprocs
;i
++) {
8753 if (child_status
[i
]) synccount
++;
8755 if (synccount
== nprocs
) break;
8757 } while (timeval_elapsed(&start
) < 30);
8759 if (synccount
!= nprocs
) {
8760 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
8762 return timeval_elapsed(&start
);
8765 /* start the client load */
8766 start
= timeval_current();
8768 for (i
=0;i
<nprocs
;i
++) {
8769 child_status
[i
] = 0;
8772 printf("%d clients started\n", nprocs
);
8774 for (i
=0;i
<nprocs
;i
++) {
8775 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
8780 for (i
=0;i
<nprocs
;i
++) {
8781 if (!child_status_out
[i
]) {
8785 return timeval_elapsed(&start
);
8788 #define FLAG_MULTIPROC 1
8795 {"FDPASS", run_fdpasstest
, 0},
8796 {"LOCK1", run_locktest1
, 0},
8797 {"LOCK2", run_locktest2
, 0},
8798 {"LOCK3", run_locktest3
, 0},
8799 {"LOCK4", run_locktest4
, 0},
8800 {"LOCK5", run_locktest5
, 0},
8801 {"LOCK6", run_locktest6
, 0},
8802 {"LOCK7", run_locktest7
, 0},
8803 {"LOCK8", run_locktest8
, 0},
8804 {"LOCK9", run_locktest9
, 0},
8805 {"UNLINK", run_unlinktest
, 0},
8806 {"BROWSE", run_browsetest
, 0},
8807 {"ATTR", run_attrtest
, 0},
8808 {"TRANS2", run_trans2test
, 0},
8809 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
8810 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
8811 {"RANDOMIPC", run_randomipc
, 0},
8812 {"NEGNOWAIT", run_negprot_nowait
, 0},
8813 {"NBENCH", run_nbench
, 0},
8814 {"NBENCH2", run_nbench2
, 0},
8815 {"OPLOCK1", run_oplock1
, 0},
8816 {"OPLOCK2", run_oplock2
, 0},
8817 {"OPLOCK4", run_oplock4
, 0},
8818 {"DIR", run_dirtest
, 0},
8819 {"DIR1", run_dirtest1
, 0},
8820 {"DIR-CREATETIME", run_dir_createtime
, 0},
8821 {"DENY1", torture_denytest1
, 0},
8822 {"DENY2", torture_denytest2
, 0},
8823 {"TCON", run_tcon_test
, 0},
8824 {"TCONDEV", run_tcon_devtype_test
, 0},
8825 {"RW1", run_readwritetest
, 0},
8826 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
8827 {"RW3", run_readwritelarge
, 0},
8828 {"RW-SIGNING", run_readwritelarge_signtest
, 0},
8829 {"OPEN", run_opentest
, 0},
8830 {"POSIX", run_simple_posix_open_test
, 0},
8831 {"POSIX-APPEND", run_posix_append
, 0},
8832 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create
, 0},
8833 {"ASYNC-ECHO", run_async_echo
, 0},
8834 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
8835 { "SHORTNAME-TEST", run_shortname_test
, 0},
8836 { "ADDRCHANGE", run_addrchange
, 0},
8838 {"OPENATTR", run_openattrtest
, 0},
8840 {"XCOPY", run_xcopy
, 0},
8841 {"RENAME", run_rename
, 0},
8842 {"DELETE", run_deletetest
, 0},
8843 {"DELETE-LN", run_deletetest_ln
, 0},
8844 {"PROPERTIES", run_properties
, 0},
8845 {"MANGLE", torture_mangle
, 0},
8846 {"MANGLE1", run_mangle1
, 0},
8847 {"W2K", run_w2ktest
, 0},
8848 {"TRANS2SCAN", torture_trans2_scan
, 0},
8849 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
8850 {"UTABLE", torture_utable
, 0},
8851 {"CASETABLE", torture_casetable
, 0},
8852 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
8853 {"PIPE_NUMBER", run_pipe_number
, 0},
8854 {"TCON2", run_tcon2_test
, 0},
8855 {"IOCTL", torture_ioctl_test
, 0},
8856 {"CHKPATH", torture_chkpath_test
, 0},
8857 {"FDSESS", run_fdsesstest
, 0},
8858 { "EATEST", run_eatest
, 0},
8859 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
8860 { "CHAIN1", run_chain1
, 0},
8861 { "CHAIN2", run_chain2
, 0},
8862 { "WINDOWS-WRITE", run_windows_write
, 0},
8863 { "NTTRANS-CREATE", run_nttrans_create
, 0},
8864 { "NTTRANS-FSCTL", run_nttrans_fsctl
, 0},
8865 { "CLI_ECHO", run_cli_echo
, 0},
8866 { "GETADDRINFO", run_getaddrinfo_send
, 0},
8867 { "TLDAP", run_tldap
},
8868 { "STREAMERROR", run_streamerror
},
8869 { "NOTIFY-BENCH", run_notify_bench
},
8870 { "BAD-NBT-SESSION", run_bad_nbt_session
},
8871 { "SMB-ANY-CONNECT", run_smb_any_connect
},
8872 { "NOTIFY-ONLINE", run_notify_online
},
8873 { "SMB2-BASIC", run_smb2_basic
},
8874 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
8875 { "LOCAL-GENCACHE", run_local_gencache
, 0},
8876 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
8877 { "LOCAL-BASE64", run_local_base64
, 0},
8878 { "LOCAL-RBTREE", run_local_rbtree
, 0},
8879 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
8880 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
8881 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
8882 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
8883 { "LOCAL-binary_to_sid", run_local_binary_to_sid
, 0},
8884 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
8885 { "LOCAL-TEVENT-SELECT", run_local_tevent_select
, 0},
8886 { "LOCAL-CONVERT-STRING", run_local_convert_string
, 0},
8887 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info
, 0},
8888 { "LOCAL-sprintf_append", run_local_sprintf_append
, 0},
8893 /****************************************************************************
8894 run a specified test or "ALL"
8895 ****************************************************************************/
8896 static bool run_test(const char *name
)
8903 if (strequal(name
,"ALL")) {
8904 for (i
=0;torture_ops
[i
].name
;i
++) {
8905 run_test(torture_ops
[i
].name
);
8910 for (i
=0;torture_ops
[i
].name
;i
++) {
8911 fstr_sprintf(randomfname
, "\\XX%x",
8912 (unsigned)random());
8914 if (strequal(name
, torture_ops
[i
].name
)) {
8916 printf("Running %s\n", name
);
8917 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
8918 t
= create_procs(torture_ops
[i
].fn
, &result
);
8921 printf("TEST %s FAILED!\n", name
);
8924 struct timeval start
;
8925 start
= timeval_current();
8926 if (!torture_ops
[i
].fn(0)) {
8928 printf("TEST %s FAILED!\n", name
);
8930 t
= timeval_elapsed(&start
);
8932 printf("%s took %g secs\n\n", name
, t
);
8937 printf("Did not find a test named %s\n", name
);
8945 static void usage(void)
8949 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8950 printf("Please use samba4 torture.\n\n");
8952 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8954 printf("\t-d debuglevel\n");
8955 printf("\t-U user%%pass\n");
8956 printf("\t-k use kerberos\n");
8957 printf("\t-N numprocs\n");
8958 printf("\t-n my_netbios_name\n");
8959 printf("\t-W workgroup\n");
8960 printf("\t-o num_operations\n");
8961 printf("\t-O socket_options\n");
8962 printf("\t-m maximum protocol\n");
8963 printf("\t-L use oplocks\n");
8964 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8965 printf("\t-A showall\n");
8966 printf("\t-p port\n");
8967 printf("\t-s seed\n");
8968 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8969 printf("\t-f filename filename to test\n");
8972 printf("tests are:");
8973 for (i
=0;torture_ops
[i
].name
;i
++) {
8974 printf(" %s", torture_ops
[i
].name
);
8978 printf("default test is ALL\n");
8983 /****************************************************************************
8985 ****************************************************************************/
8986 int main(int argc
,char *argv
[])
8992 bool correct
= True
;
8993 TALLOC_CTX
*frame
= talloc_stackframe();
8994 int seed
= time(NULL
);
8996 #ifdef HAVE_SETBUFFER
8997 setbuffer(stdout
, NULL
, 0);
9000 setup_logging("smbtorture", DEBUG_STDOUT
);
9004 if (is_default_dyn_CONFIGFILE()) {
9005 if(getenv("SMB_CONF_PATH")) {
9006 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9009 lp_load_global(get_dyn_CONFIGFILE());
9016 for(p
= argv
[1]; *p
; p
++)
9020 if (strncmp(argv
[1], "//", 2)) {
9024 fstrcpy(host
, &argv
[1][2]);
9025 p
= strchr_m(&host
[2],'/');
9030 fstrcpy(share
, p
+1);
9032 fstrcpy(myname
, get_myname(talloc_tos()));
9034 fprintf(stderr
, "Failed to get my hostname.\n");
9038 if (*username
== 0 && getenv("LOGNAME")) {
9039 fstrcpy(username
,getenv("LOGNAME"));
9045 fstrcpy(workgroup
, lp_workgroup());
9047 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9051 port_to_use
= atoi(optarg
);
9054 seed
= atoi(optarg
);
9057 fstrcpy(workgroup
,optarg
);
9060 max_protocol
= interpret_protocol(optarg
, max_protocol
);
9063 nprocs
= atoi(optarg
);
9066 torture_numops
= atoi(optarg
);
9069 lp_set_cmdline("log level", optarg
);
9078 local_path
= optarg
;
9081 torture_showall
= True
;
9084 fstrcpy(myname
, optarg
);
9087 client_txt
= optarg
;
9094 use_kerberos
= True
;
9096 d_printf("No kerberos support compiled in\n");
9102 fstrcpy(username
,optarg
);
9103 p
= strchr_m(username
,'%');
9106 fstrcpy(password
, p
+1);
9111 fstrcpy(multishare_conn_fname
, optarg
);
9112 use_multishare_conn
= True
;
9115 torture_blocksize
= atoi(optarg
);
9118 test_filename
= SMB_STRDUP(optarg
);
9121 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
9126 d_printf("using seed %d\n", seed
);
9130 if(use_kerberos
&& !gotuser
) gotpass
= True
;
9133 p
= getpass("Password:");
9135 fstrcpy(password
, p
);
9140 printf("host=%s share=%s user=%s myname=%s\n",
9141 host
, share
, username
, myname
);
9143 if (argc
== optind
) {
9144 correct
= run_test("ALL");
9146 for (i
=optind
;i
<argc
;i
++) {
9147 if (!run_test(argv
[i
])) {