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 "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
28 static fstring host
, workgroup
, share
, password
, username
, myname
;
29 static int max_protocol
= PROTOCOL_NT1
;
30 static const char *sockops
="TCP_NODELAY";
32 static int port_to_use
=0;
33 int torture_numops
=100;
34 int torture_blocksize
=1024*1024;
35 static int procnum
; /* records process count number when forking */
36 static struct cli_state
*current_cli
;
37 static fstring randomfname
;
38 static bool use_oplocks
;
39 static bool use_level_II_oplocks
;
40 static const char *client_txt
= "client_oplocks.txt";
41 static bool use_kerberos
;
42 static fstring multishare_conn_fname
;
43 static bool use_multishare_conn
= False
;
44 static bool do_encrypt
;
45 static const char *local_path
= NULL
;
47 bool torture_showall
= False
;
49 static double create_procs(bool (*fn
)(int), bool *result
);
52 /* return a pointer to a anonymous shared memory segment of size "size"
53 which will persist across fork() but will disappear when all processes
56 The memory is not zeroed
58 This function uses system5 shared memory. It takes advantage of a property
59 that the memory is not destroyed if it is attached when the id is removed
61 void *shm_setup(int size
)
67 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
69 printf("can't get shared memory\n");
72 shm_unlink("private");
73 if (ftruncate(shmid
, size
) == -1) {
74 printf("can't set shared memory size\n");
77 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
78 if (ret
== MAP_FAILED
) {
79 printf("can't map shared memory\n");
83 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
85 printf("can't get shared memory\n");
88 ret
= (void *)shmat(shmid
, 0, 0);
89 if (!ret
|| ret
== (void *)-1) {
90 printf("can't attach to shared memory\n");
93 /* the following releases the ipc, but note that this process
94 and all its children will still have access to the memory, its
95 just that the shmid is no longer valid for other shm calls. This
96 means we don't leave behind lots of shm segments after we exit
98 See Stevens "advanced programming in unix env" for details
100 shmctl(shmid
, IPC_RMID
, 0);
106 /********************************************************************
107 Ensure a connection is encrypted.
108 ********************************************************************/
110 static bool force_cli_encryption(struct cli_state
*c
,
111 const char *sharename
)
114 uint32 caplow
, caphigh
;
117 if (!SERVER_HAS_UNIX_CIFS(c
)) {
118 d_printf("Encryption required and "
119 "server that doesn't support "
120 "UNIX extensions - failing connect\n");
124 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
126 if (!NT_STATUS_IS_OK(status
)) {
127 d_printf("Encryption required and "
128 "can't get UNIX CIFS extensions "
129 "version from server: %s\n", nt_errstr(status
));
133 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
134 d_printf("Encryption required and "
135 "share %s doesn't support "
136 "encryption.\n", sharename
);
140 if (c
->use_kerberos
) {
141 status
= cli_gss_smb_encryption_start(c
);
143 status
= cli_raw_ntlm_smb_encryption_start(c
,
149 if (!NT_STATUS_IS_OK(status
)) {
150 d_printf("Encryption required and "
151 "setup failed with error %s.\n",
160 static struct cli_state
*open_nbt_connection(void)
162 struct nmb_name called
, calling
;
163 struct sockaddr_storage ss
;
167 make_nmb_name(&calling
, myname
, 0x0);
168 make_nmb_name(&called
, host
, 0x20);
172 if (!(c
= cli_initialise())) {
173 printf("Failed initialize cli_struct to connect with %s\n", host
);
177 c
->port
= port_to_use
;
179 status
= cli_connect(c
, host
, &ss
);
180 if (!NT_STATUS_IS_OK(status
)) {
181 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
185 c
->use_kerberos
= use_kerberos
;
187 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
188 if (use_oplocks
) c
->use_oplocks
= True
;
189 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
191 if (!cli_session_request(c
, &calling
, &called
)) {
193 * Well, that failed, try *SMBSERVER ...
194 * However, we must reconnect as well ...
196 status
= cli_connect(c
, host
, &ss
);
197 if (!NT_STATUS_IS_OK(status
)) {
198 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
202 make_nmb_name(&called
, "*SMBSERVER", 0x20);
203 if (!cli_session_request(c
, &calling
, &called
)) {
204 printf("%s rejected the session\n",host
);
205 printf("We tried with a called name of %s & %s\n",
215 /* Insert a NULL at the first separator of the given path and return a pointer
216 * to the remainder of the string.
219 terminate_path_at_separator(char * path
)
227 if ((p
= strchr_m(path
, '/'))) {
232 if ((p
= strchr_m(path
, '\\'))) {
242 parse a //server/share type UNC name
244 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
245 char **hostname
, char **sharename
)
249 *hostname
= *sharename
= NULL
;
251 if (strncmp(unc_name
, "\\\\", 2) &&
252 strncmp(unc_name
, "//", 2)) {
256 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
257 p
= terminate_path_at_separator(*hostname
);
260 *sharename
= talloc_strdup(mem_ctx
, p
);
261 terminate_path_at_separator(*sharename
);
264 if (*hostname
&& *sharename
) {
268 TALLOC_FREE(*hostname
);
269 TALLOC_FREE(*sharename
);
273 static bool torture_open_connection_share(struct cli_state
**c
,
274 const char *hostname
,
275 const char *sharename
)
282 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
284 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
285 if (use_level_II_oplocks
)
286 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
288 status
= cli_full_connection(c
, myname
,
289 hostname
, NULL
, port_to_use
,
292 password
, flags
, Undefined
, &retry
);
293 if (!NT_STATUS_IS_OK(status
)) {
294 printf("failed to open share connection: //%s/%s port:%d - %s\n",
295 hostname
, sharename
, port_to_use
, nt_errstr(status
));
299 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
302 return force_cli_encryption(*c
,
308 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
310 char **unc_list
= NULL
;
311 int num_unc_names
= 0;
314 if (use_multishare_conn
==True
) {
316 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
317 if (!unc_list
|| num_unc_names
<= 0) {
318 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
322 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
324 printf("Failed to parse UNC name %s\n",
325 unc_list
[conn_index
% num_unc_names
]);
326 TALLOC_FREE(unc_list
);
330 result
= torture_open_connection_share(c
, h
, s
);
332 /* h, s were copied earlier */
333 TALLOC_FREE(unc_list
);
337 return torture_open_connection_share(c
, host
, share
);
340 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
342 uint16 old_vuid
= cli
->vuid
;
343 fstring old_user_name
;
344 size_t passlen
= strlen(password
);
348 fstrcpy(old_user_name
, cli
->user_name
);
350 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
354 *new_vuid
= cli
->vuid
;
355 cli
->vuid
= old_vuid
;
356 status
= cli_set_username(cli
, old_user_name
);
357 if (!NT_STATUS_IS_OK(status
)) {
364 bool torture_close_connection(struct cli_state
*c
)
369 status
= cli_tdis(c
);
370 if (!NT_STATUS_IS_OK(status
)) {
371 printf("tdis failed (%s)\n", nt_errstr(status
));
381 /* check if the server produced the expected error code */
382 static bool check_error(int line
, struct cli_state
*c
,
383 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
385 if (cli_is_dos_error(c
)) {
389 /* Check DOS error */
391 cli_dos_error(c
, &cclass
, &num
);
393 if (eclass
!= cclass
|| ecode
!= num
) {
394 printf("unexpected error code class=%d code=%d\n",
395 (int)cclass
, (int)num
);
396 printf(" expected %d/%d %s (line=%d)\n",
397 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
406 status
= cli_nt_error(c
);
408 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
409 printf("unexpected error code %s\n", nt_errstr(status
));
410 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
419 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
421 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
422 if (!check_error(__LINE__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
428 static bool rw_torture(struct cli_state
*c
)
430 const char *lockfname
= "\\torture.lck";
434 pid_t pid2
, pid
= getpid();
440 memset(buf
, '\0', sizeof(buf
));
442 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
444 if (!NT_STATUS_IS_OK(status
)) {
445 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
447 if (!NT_STATUS_IS_OK(status
)) {
448 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
452 for (i
=0;i
<torture_numops
;i
++) {
453 unsigned n
= (unsigned)sys_random()%10;
455 printf("%d\r", i
); fflush(stdout
);
457 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
459 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
463 if (!NT_STATUS_IS_OK(cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
, &fnum
))) {
464 printf("open failed (%s)\n", cli_errstr(c
));
469 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
470 printf("write failed (%s)\n", cli_errstr(c
));
475 if (cli_write(c
, fnum
, 0, (char *)buf
,
476 sizeof(pid
)+(j
*sizeof(buf
)),
477 sizeof(buf
)) != sizeof(buf
)) {
478 printf("write failed (%s)\n", cli_errstr(c
));
485 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
486 printf("read failed (%s)\n", cli_errstr(c
));
491 printf("data corruption!\n");
495 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
496 printf("close failed (%s)\n", cli_errstr(c
));
500 if (!NT_STATUS_IS_OK(cli_unlink(c
, fname
, aSYSTEM
| aHIDDEN
))) {
501 printf("unlink failed (%s)\n", cli_errstr(c
));
505 if (!NT_STATUS_IS_OK(cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int)))) {
506 printf("unlock failed (%s)\n", cli_errstr(c
));
512 cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
);
519 static bool run_torture(int dummy
)
521 struct cli_state
*cli
;
526 cli_sockopt(cli
, sockops
);
528 ret
= rw_torture(cli
);
530 if (!torture_close_connection(cli
)) {
537 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
539 uint16_t fnum
= (uint16_t)-1;
544 unsigned countprev
= 0;
550 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
552 SIVAL(buf
, i
, sys_random());
557 if (!NT_STATUS_IS_OK(cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
558 DENY_NONE
, &fnum
))) {
559 printf("first open read/write of %s failed (%s)\n",
560 lockfname
, cli_errstr(c
));
566 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
568 status
= cli_open(c
, lockfname
, O_RDONLY
,
570 if (!NT_STATUS_IS_OK(status
)) {
575 if (!NT_STATUS_IS_OK(status
)) {
576 printf("second open read-only of %s failed (%s)\n",
577 lockfname
, cli_errstr(c
));
583 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
585 if (count
>= countprev
) {
586 printf("%d %8d\r", i
, count
);
589 countprev
+= (sizeof(buf
) / 20);
594 sent
= ((unsigned)sys_random()%(20))+ 1;
595 if (sent
> sizeof(buf
) - count
)
597 sent
= sizeof(buf
) - count
;
600 if (cli_write(c
, fnum
, 0, buf
+count
, count
, (size_t)sent
) != sent
) {
601 printf("write failed (%s)\n", cli_errstr(c
));
607 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
611 printf("read failed offset:%d size:%ld (%s)\n",
612 count
, (unsigned long)sizeof(buf
)-count
,
619 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
621 printf("read/write compare failed\n");
622 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
631 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
632 printf("close failed (%s)\n", cli_errstr(c
));
639 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
641 const char *lockfname
= "\\torture2.lck";
650 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
651 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
654 if (!NT_STATUS_IS_OK(cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
655 DENY_NONE
, &fnum1
))) {
656 printf("first open read/write of %s failed (%s)\n",
657 lockfname
, cli_errstr(c1
));
660 if (!NT_STATUS_IS_OK(cli_open(c2
, lockfname
, O_RDONLY
,
661 DENY_NONE
, &fnum2
))) {
662 printf("second open read-only of %s failed (%s)\n",
663 lockfname
, cli_errstr(c2
));
664 cli_close(c1
, fnum1
);
668 for (i
=0;i
<torture_numops
;i
++)
670 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
672 printf("%d\r", i
); fflush(stdout
);
675 generate_random_buffer((unsigned char *)buf
, buf_size
);
677 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
678 printf("write failed (%s)\n", cli_errstr(c1
));
683 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
684 printf("read failed (%s)\n", cli_errstr(c2
));
685 printf("read %d, expected %ld\n", (int)bytes_read
,
686 (unsigned long)buf_size
);
691 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
693 printf("read/write compare failed\n");
699 if (!NT_STATUS_IS_OK(cli_close(c2
, fnum2
))) {
700 printf("close failed (%s)\n", cli_errstr(c2
));
703 if (!NT_STATUS_IS_OK(cli_close(c1
, fnum1
))) {
704 printf("close failed (%s)\n", cli_errstr(c1
));
708 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
709 printf("unlink failed (%s)\n", cli_errstr(c1
));
716 static bool run_readwritetest(int dummy
)
718 struct cli_state
*cli1
, *cli2
;
719 bool test1
, test2
= False
;
721 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
724 cli_sockopt(cli1
, sockops
);
725 cli_sockopt(cli2
, sockops
);
727 printf("starting readwritetest\n");
729 test1
= rw_torture2(cli1
, cli2
);
730 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
733 test2
= rw_torture2(cli1
, cli1
);
734 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
737 if (!torture_close_connection(cli1
)) {
741 if (!torture_close_connection(cli2
)) {
745 return (test1
&& test2
);
748 static bool run_readwritemulti(int dummy
)
750 struct cli_state
*cli
;
755 cli_sockopt(cli
, sockops
);
757 printf("run_readwritemulti: fname %s\n", randomfname
);
758 test
= rw_torture3(cli
, randomfname
);
760 if (!torture_close_connection(cli
)) {
767 static bool run_readwritelarge(int dummy
)
769 static struct cli_state
*cli1
;
771 const char *lockfname
= "\\large.dat";
776 if (!torture_open_connection(&cli1
, 0)) {
779 cli_sockopt(cli1
, sockops
);
780 memset(buf
,'\0',sizeof(buf
));
782 cli1
->max_xmit
= 128*1024;
784 printf("starting readwritelarge\n");
786 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
788 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
789 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
793 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
795 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
796 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
800 if (fsize
== sizeof(buf
))
801 printf("readwritelarge test 1 succeeded (size = %lx)\n",
802 (unsigned long)fsize
);
804 printf("readwritelarge test 1 failed (size = %lx)\n",
805 (unsigned long)fsize
);
809 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
810 printf("close failed (%s)\n", cli_errstr(cli1
));
814 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
815 printf("unlink failed (%s)\n", cli_errstr(cli1
));
819 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
820 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
824 cli1
->max_xmit
= 4*1024;
826 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
));
828 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
829 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
833 if (fsize
== sizeof(buf
))
834 printf("readwritelarge test 2 succeeded (size = %lx)\n",
835 (unsigned long)fsize
);
837 printf("readwritelarge test 2 failed (size = %lx)\n",
838 (unsigned long)fsize
);
843 /* ToDo - set allocation. JRA */
844 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
845 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
848 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
849 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
853 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
856 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
857 printf("close failed (%s)\n", cli_errstr(cli1
));
861 if (!torture_close_connection(cli1
)) {
870 #define ival(s) strtol(s, NULL, 0)
872 /* run a test that simulates an approximate netbench client load */
873 static bool run_netbench(int client
)
875 struct cli_state
*cli
;
880 const char *params
[20];
887 cli_sockopt(cli
, sockops
);
891 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
893 f
= fopen(client_txt
, "r");
900 while (fgets(line
, sizeof(line
)-1, f
)) {
904 line
[strlen(line
)-1] = 0;
906 /* printf("[%d] %s\n", line_count, line); */
908 all_string_sub(line
,"client1", cname
, sizeof(line
));
910 /* parse the command parameters */
911 params
[0] = strtok_r(line
, " ", &saveptr
);
913 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
919 if (!strncmp(params
[0],"SMB", 3)) {
920 printf("ERROR: You are using a dbench 1 load file\n");
924 if (!strcmp(params
[0],"NTCreateX")) {
925 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
927 } else if (!strcmp(params
[0],"Close")) {
928 nb_close(ival(params
[1]));
929 } else if (!strcmp(params
[0],"Rename")) {
930 nb_rename(params
[1], params
[2]);
931 } else if (!strcmp(params
[0],"Unlink")) {
932 nb_unlink(params
[1]);
933 } else if (!strcmp(params
[0],"Deltree")) {
934 nb_deltree(params
[1]);
935 } else if (!strcmp(params
[0],"Rmdir")) {
937 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
938 nb_qpathinfo(params
[1]);
939 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
940 nb_qfileinfo(ival(params
[1]));
941 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
942 nb_qfsinfo(ival(params
[1]));
943 } else if (!strcmp(params
[0],"FIND_FIRST")) {
944 nb_findfirst(params
[1]);
945 } else if (!strcmp(params
[0],"WriteX")) {
946 nb_writex(ival(params
[1]),
947 ival(params
[2]), ival(params
[3]), ival(params
[4]));
948 } else if (!strcmp(params
[0],"ReadX")) {
949 nb_readx(ival(params
[1]),
950 ival(params
[2]), ival(params
[3]), ival(params
[4]));
951 } else if (!strcmp(params
[0],"Flush")) {
952 nb_flush(ival(params
[1]));
954 printf("Unknown operation %s\n", params
[0]);
962 if (!torture_close_connection(cli
)) {
970 /* run a test that simulates an approximate netbench client load */
971 static bool run_nbench(int dummy
)
980 signal(SIGALRM
, nb_alarm
);
982 t
= create_procs(run_netbench
, &correct
);
985 printf("\nThroughput %g MB/sec\n",
986 1.0e-6 * nbio_total() / t
);
992 This test checks for two things:
994 1) correct support for retaining locks over a close (ie. the server
995 must not use posix semantics)
996 2) support for lock timeouts
998 static bool run_locktest1(int dummy
)
1000 struct cli_state
*cli1
, *cli2
;
1001 const char *fname
= "\\lockt1.lck";
1002 uint16_t fnum1
, fnum2
, fnum3
;
1004 unsigned lock_timeout
;
1006 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1009 cli_sockopt(cli1
, sockops
);
1010 cli_sockopt(cli2
, sockops
);
1012 printf("starting locktest1\n");
1014 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1016 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1017 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1020 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1021 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1024 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1025 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1029 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1030 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1035 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1036 printf("lock2 succeeded! This is a locking bug\n");
1039 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1040 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1044 lock_timeout
= (1 + (random() % 20));
1045 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1047 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1048 printf("lock3 succeeded! This is a locking bug\n");
1051 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1052 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1056 if (ABS(t2
- t1
) < lock_timeout
-1) {
1057 printf("error: This server appears not to support timed lock requests\n");
1060 printf("server slept for %u seconds for a %u second timeout\n",
1061 (unsigned int)(t2
-t1
), lock_timeout
);
1063 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1064 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1068 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1069 printf("lock4 succeeded! This is a locking bug\n");
1072 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1073 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1076 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1077 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1081 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1082 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1086 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1087 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1092 if (!torture_close_connection(cli1
)) {
1096 if (!torture_close_connection(cli2
)) {
1100 printf("Passed locktest1\n");
1105 this checks to see if a secondary tconx can use open files from an
1108 static bool run_tcon_test(int dummy
)
1110 static struct cli_state
*cli
;
1111 const char *fname
= "\\tcontest.tmp";
1113 uint16 cnum1
, cnum2
, cnum3
;
1114 uint16 vuid1
, vuid2
;
1119 memset(buf
, '\0', sizeof(buf
));
1121 if (!torture_open_connection(&cli
, 0)) {
1124 cli_sockopt(cli
, sockops
);
1126 printf("starting tcontest\n");
1128 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1130 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1131 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1138 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1139 printf("initial write failed (%s)", cli_errstr(cli
));
1143 status
= cli_tcon_andx(cli
, share
, "?????",
1144 password
, strlen(password
)+1);
1145 if (!NT_STATUS_IS_OK(status
)) {
1146 printf("%s refused 2nd tree connect (%s)\n", host
,
1153 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1154 vuid2
= cli
->vuid
+ 1;
1156 /* try a write with the wrong tid */
1159 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1160 printf("* server allows write with wrong TID\n");
1163 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1167 /* try a write with an invalid tid */
1170 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1171 printf("* server allows write with invalid TID\n");
1174 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1177 /* try a write with an invalid vuid */
1181 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1182 printf("* server allows write with invalid VUID\n");
1185 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1191 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1192 printf("close failed (%s)\n", cli_errstr(cli
));
1198 status
= cli_tdis(cli
);
1199 if (!NT_STATUS_IS_OK(status
)) {
1200 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1206 if (!torture_close_connection(cli
)) {
1215 checks for old style tcon support
1217 static bool run_tcon2_test(int dummy
)
1219 static struct cli_state
*cli
;
1220 uint16 cnum
, max_xmit
;
1224 if (!torture_open_connection(&cli
, 0)) {
1227 cli_sockopt(cli
, sockops
);
1229 printf("starting tcon2 test\n");
1231 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1235 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1237 if (!NT_STATUS_IS_OK(status
)) {
1238 printf("tcon2 failed : %s\n", cli_errstr(cli
));
1240 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1241 (int)max_xmit
, (int)cnum
, SVAL(cli
->inbuf
, smb_tid
));
1244 if (!torture_close_connection(cli
)) {
1248 printf("Passed tcon2 test\n");
1252 static bool tcon_devtest(struct cli_state
*cli
,
1253 const char *myshare
, const char *devtype
,
1254 const char *return_devtype
,
1255 NTSTATUS expected_error
)
1260 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1261 password
, strlen(password
)+1);
1263 if (NT_STATUS_IS_OK(expected_error
)) {
1264 if (NT_STATUS_IS_OK(status
)) {
1265 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1268 printf("tconX to share %s with type %s "
1269 "succeeded but returned the wrong "
1270 "device type (got [%s] but should have got [%s])\n",
1271 myshare
, devtype
, cli
->dev
, return_devtype
);
1275 printf("tconX to share %s with type %s "
1276 "should have succeeded but failed\n",
1282 if (NT_STATUS_IS_OK(status
)) {
1283 printf("tconx to share %s with type %s "
1284 "should have failed but succeeded\n",
1288 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1292 printf("Returned unexpected error\n");
1301 checks for correct tconX support
1303 static bool run_tcon_devtype_test(int dummy
)
1305 static struct cli_state
*cli1
= NULL
;
1311 status
= cli_full_connection(&cli1
, myname
,
1312 host
, NULL
, port_to_use
,
1314 username
, workgroup
,
1315 password
, flags
, Undefined
, &retry
);
1317 if (!NT_STATUS_IS_OK(status
)) {
1318 printf("could not open connection\n");
1322 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1325 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1328 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1331 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1334 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1337 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1340 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1343 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1346 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1349 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1355 printf("Passed tcondevtest\n");
1362 This test checks that
1364 1) the server supports multiple locking contexts on the one SMB
1365 connection, distinguished by PID.
1367 2) the server correctly fails overlapping locks made by the same PID (this
1368 goes against POSIX behaviour, which is why it is tricky to implement)
1370 3) the server denies unlock requests by an incorrect client PID
1372 static bool run_locktest2(int dummy
)
1374 static struct cli_state
*cli
;
1375 const char *fname
= "\\lockt2.lck";
1376 uint16_t fnum1
, fnum2
, fnum3
;
1377 bool correct
= True
;
1379 if (!torture_open_connection(&cli
, 0)) {
1383 cli_sockopt(cli
, sockops
);
1385 printf("starting locktest2\n");
1387 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1391 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1392 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1396 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1397 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1403 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1404 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1410 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1411 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1415 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1416 printf("WRITE lock1 succeeded! This is a locking bug\n");
1419 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1420 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1423 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1424 printf("WRITE lock2 succeeded! This is a locking bug\n");
1427 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1428 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1431 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1432 printf("READ lock2 succeeded! This is a locking bug\n");
1435 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1436 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1439 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1440 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1443 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1444 printf("unlock at 100 succeeded! This is a locking bug\n");
1448 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1449 printf("unlock1 succeeded! This is a locking bug\n");
1452 if (!check_error(__LINE__
, cli
,
1454 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1457 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1458 printf("unlock2 succeeded! This is a locking bug\n");
1461 if (!check_error(__LINE__
, cli
,
1463 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1466 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1467 printf("lock3 succeeded! This is a locking bug\n");
1470 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1475 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1476 printf("close1 failed (%s)\n", cli_errstr(cli
));
1480 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1481 printf("close2 failed (%s)\n", cli_errstr(cli
));
1485 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1486 printf("close3 failed (%s)\n", cli_errstr(cli
));
1490 if (!torture_close_connection(cli
)) {
1494 printf("locktest2 finished\n");
1501 This test checks that
1503 1) the server supports the full offset range in lock requests
1505 static bool run_locktest3(int dummy
)
1507 static struct cli_state
*cli1
, *cli2
;
1508 const char *fname
= "\\lockt3.lck";
1509 uint16_t fnum1
, fnum2
;
1512 bool correct
= True
;
1514 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1516 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1519 cli_sockopt(cli1
, sockops
);
1520 cli_sockopt(cli2
, sockops
);
1522 printf("starting locktest3\n");
1524 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1526 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1527 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1530 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1531 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1535 for (offset
=i
=0;i
<torture_numops
;i
++) {
1537 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1538 printf("lock1 %d failed (%s)\n",
1544 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1545 printf("lock2 %d failed (%s)\n",
1552 for (offset
=i
=0;i
<torture_numops
;i
++) {
1555 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1556 printf("error: lock1 %d succeeded!\n", i
);
1560 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1561 printf("error: lock2 %d succeeded!\n", i
);
1565 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1566 printf("error: lock3 %d succeeded!\n", i
);
1570 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1571 printf("error: lock4 %d succeeded!\n", i
);
1576 for (offset
=i
=0;i
<torture_numops
;i
++) {
1579 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1580 printf("unlock1 %d failed (%s)\n",
1586 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1587 printf("unlock2 %d failed (%s)\n",
1594 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1595 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1599 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1600 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1604 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1605 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1609 if (!torture_close_connection(cli1
)) {
1613 if (!torture_close_connection(cli2
)) {
1617 printf("finished locktest3\n");
1622 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1623 printf("** "); correct = False; \
1627 looks at overlapping locks
1629 static bool run_locktest4(int dummy
)
1631 static struct cli_state
*cli1
, *cli2
;
1632 const char *fname
= "\\lockt4.lck";
1633 uint16_t fnum1
, fnum2
, f
;
1636 bool correct
= True
;
1638 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1642 cli_sockopt(cli1
, sockops
);
1643 cli_sockopt(cli2
, sockops
);
1645 printf("starting locktest4\n");
1647 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1649 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1650 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1652 memset(buf
, 0, sizeof(buf
));
1654 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1655 printf("Failed to create file\n");
1660 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1661 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1662 EXPECTED(ret
, False
);
1663 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1665 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1666 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1667 EXPECTED(ret
, True
);
1668 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1670 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1671 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1672 EXPECTED(ret
, False
);
1673 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1675 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1676 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1677 EXPECTED(ret
, True
);
1678 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1680 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1681 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1682 EXPECTED(ret
, False
);
1683 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1685 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1686 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1687 EXPECTED(ret
, True
);
1688 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1690 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1691 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1692 EXPECTED(ret
, True
);
1693 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1695 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1696 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1697 EXPECTED(ret
, False
);
1698 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1700 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1701 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1702 EXPECTED(ret
, False
);
1703 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1705 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1706 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1707 EXPECTED(ret
, True
);
1708 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1710 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1711 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1712 EXPECTED(ret
, False
);
1713 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1715 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1716 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1717 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1718 EXPECTED(ret
, False
);
1719 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1722 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1723 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1724 EXPECTED(ret
, False
);
1725 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1727 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1728 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1729 EXPECTED(ret
, False
);
1730 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1733 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1734 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1735 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1736 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1737 EXPECTED(ret
, True
);
1738 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1741 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1742 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1743 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1744 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1745 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1746 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1747 EXPECTED(ret
, True
);
1748 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1750 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1751 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1752 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1753 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1754 EXPECTED(ret
, True
);
1755 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1757 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1758 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1759 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1760 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1761 EXPECTED(ret
, True
);
1762 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1764 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1765 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1766 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1767 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1768 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1769 EXPECTED(ret
, True
);
1770 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1772 cli_close(cli1
, fnum1
);
1773 cli_close(cli2
, fnum2
);
1774 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1775 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1776 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1777 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1778 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1779 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1780 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1782 cli_close(cli1
, fnum1
);
1783 EXPECTED(ret
, True
);
1784 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1787 cli_close(cli1
, fnum1
);
1788 cli_close(cli2
, fnum2
);
1789 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1790 torture_close_connection(cli1
);
1791 torture_close_connection(cli2
);
1793 printf("finished locktest4\n");
1798 looks at lock upgrade/downgrade.
1800 static bool run_locktest5(int dummy
)
1802 static struct cli_state
*cli1
, *cli2
;
1803 const char *fname
= "\\lockt5.lck";
1804 uint16_t fnum1
, fnum2
, fnum3
;
1807 bool correct
= True
;
1809 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1813 cli_sockopt(cli1
, sockops
);
1814 cli_sockopt(cli2
, sockops
);
1816 printf("starting locktest5\n");
1818 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1820 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1821 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1822 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1824 memset(buf
, 0, sizeof(buf
));
1826 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1827 printf("Failed to create file\n");
1832 /* Check for NT bug... */
1833 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1834 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1835 cli_close(cli1
, fnum1
);
1836 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1837 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1838 EXPECTED(ret
, True
);
1839 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1840 cli_close(cli1
, fnum1
);
1841 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1842 cli_unlock(cli1
, fnum3
, 0, 1);
1844 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1845 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1846 EXPECTED(ret
, True
);
1847 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1849 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1850 EXPECTED(ret
, False
);
1852 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1854 /* Unlock the process 2 lock. */
1855 cli_unlock(cli2
, fnum2
, 0, 4);
1857 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1858 EXPECTED(ret
, False
);
1860 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1862 /* Unlock the process 1 fnum3 lock. */
1863 cli_unlock(cli1
, fnum3
, 0, 4);
1865 /* Stack 2 more locks here. */
1866 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1867 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1869 EXPECTED(ret
, True
);
1870 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
1872 /* Unlock the first process lock, then check this was the WRITE lock that was
1875 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
1876 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1878 EXPECTED(ret
, True
);
1879 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
1881 /* Unlock the process 2 lock. */
1882 cli_unlock(cli2
, fnum2
, 0, 4);
1884 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1886 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
1887 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
1888 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
1890 EXPECTED(ret
, True
);
1891 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
1893 /* Ensure the next unlock fails. */
1894 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
1895 EXPECTED(ret
, False
);
1896 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
1898 /* Ensure connection 2 can get a write lock. */
1899 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1900 EXPECTED(ret
, True
);
1902 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
1906 cli_close(cli1
, fnum1
);
1907 cli_close(cli2
, fnum2
);
1908 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1909 if (!torture_close_connection(cli1
)) {
1912 if (!torture_close_connection(cli2
)) {
1916 printf("finished locktest5\n");
1922 tries the unusual lockingX locktype bits
1924 static bool run_locktest6(int dummy
)
1926 static struct cli_state
*cli
;
1927 const char *fname
[1] = { "\\lock6.txt" };
1932 if (!torture_open_connection(&cli
, 0)) {
1936 cli_sockopt(cli
, sockops
);
1938 printf("starting locktest6\n");
1941 printf("Testing %s\n", fname
[i
]);
1943 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
1945 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
1946 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
1947 cli_close(cli
, fnum
);
1948 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
1950 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
1951 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
1952 cli_close(cli
, fnum
);
1953 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
1955 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
1958 torture_close_connection(cli
);
1960 printf("finished locktest6\n");
1964 static bool run_locktest7(int dummy
)
1966 struct cli_state
*cli1
;
1967 const char *fname
= "\\lockt7.lck";
1970 bool correct
= False
;
1972 if (!torture_open_connection(&cli1
, 0)) {
1976 cli_sockopt(cli1
, sockops
);
1978 printf("starting locktest7\n");
1980 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1982 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1984 memset(buf
, 0, sizeof(buf
));
1986 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1987 printf("Failed to create file\n");
1991 cli_setpid(cli1
, 1);
1993 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
1994 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
1997 printf("pid1 successfully locked range 130:4 for READ\n");
2000 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2001 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2004 printf("pid1 successfully read the range 130:4\n");
2007 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2008 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2009 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2010 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2014 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2018 cli_setpid(cli1
, 2);
2020 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2021 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2023 printf("pid2 successfully read the range 130:4\n");
2026 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2027 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2028 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2029 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2033 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2037 cli_setpid(cli1
, 1);
2038 cli_unlock(cli1
, fnum1
, 130, 4);
2040 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2041 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2044 printf("pid1 successfully locked range 130:4 for WRITE\n");
2047 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2048 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2051 printf("pid1 successfully read the range 130:4\n");
2054 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2055 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2058 printf("pid1 successfully wrote to the range 130:4\n");
2061 cli_setpid(cli1
, 2);
2063 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2064 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2065 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2066 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2070 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2074 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2075 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2076 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2077 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2081 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2085 cli_unlock(cli1
, fnum1
, 130, 0);
2089 cli_close(cli1
, fnum1
);
2090 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2091 torture_close_connection(cli1
);
2093 printf("finished locktest7\n");
2098 * This demonstrates a problem with our use of GPFS share modes: A file
2099 * descriptor sitting in the pending close queue holding a GPFS share mode
2100 * blocks opening a file another time. Happens with Word 2007 temp files.
2101 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2102 * open is denied with NT_STATUS_SHARING_VIOLATION.
2105 static bool run_locktest8(int dummy
)
2107 struct cli_state
*cli1
;
2108 const char *fname
= "\\lockt8.lck";
2109 uint16_t fnum1
, fnum2
;
2111 bool correct
= False
;
2114 if (!torture_open_connection(&cli1
, 0)) {
2118 cli_sockopt(cli1
, sockops
);
2120 printf("starting locktest8\n");
2122 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2124 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2126 if (!NT_STATUS_IS_OK(status
)) {
2127 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2131 memset(buf
, 0, sizeof(buf
));
2133 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2134 if (!NT_STATUS_IS_OK(status
)) {
2135 d_fprintf(stderr
, "cli_open second time returned %s\n",
2140 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2141 printf("Unable to apply read lock on range 1:1, error was "
2142 "%s\n", cli_errstr(cli1
));
2146 status
= cli_close(cli1
, fnum1
);
2147 if (!NT_STATUS_IS_OK(status
)) {
2148 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2152 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2153 if (!NT_STATUS_IS_OK(status
)) {
2154 d_fprintf(stderr
, "cli_open third time returned %s\n",
2162 cli_close(cli1
, fnum1
);
2163 cli_close(cli1
, fnum2
);
2164 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2165 torture_close_connection(cli1
);
2167 printf("finished locktest8\n");
2172 * This test is designed to be run in conjunction with
2173 * external NFS or POSIX locks taken in the filesystem.
2174 * It checks that the smbd server will block until the
2175 * lock is released and then acquire it. JRA.
2178 static bool got_alarm
;
2179 static int alarm_fd
;
2181 static void alarm_handler(int dummy
)
2186 static void alarm_handler_parent(int dummy
)
2191 static void do_local_lock(int read_fd
, int write_fd
)
2196 const char *local_pathname
= NULL
;
2199 local_pathname
= talloc_asprintf(talloc_tos(),
2200 "%s/lockt9.lck", local_path
);
2201 if (!local_pathname
) {
2202 printf("child: alloc fail\n");
2206 unlink(local_pathname
);
2207 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2209 printf("child: open of %s failed %s.\n",
2210 local_pathname
, strerror(errno
));
2214 /* Now take a fcntl lock. */
2215 lock
.l_type
= F_WRLCK
;
2216 lock
.l_whence
= SEEK_SET
;
2219 lock
.l_pid
= getpid();
2221 ret
= fcntl(fd
,F_SETLK
,&lock
);
2223 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2224 local_pathname
, strerror(errno
));
2227 printf("child: got lock 0:4 on file %s.\n",
2232 CatchSignal(SIGALRM
, alarm_handler
);
2234 /* Signal the parent. */
2235 if (write(write_fd
, &c
, 1) != 1) {
2236 printf("child: start signal fail %s.\n",
2243 /* Wait for the parent to be ready. */
2244 if (read(read_fd
, &c
, 1) != 1) {
2245 printf("child: reply signal fail %s.\n",
2253 printf("child: released lock 0:4 on file %s.\n",
2259 static bool run_locktest9(int dummy
)
2261 struct cli_state
*cli1
;
2262 const char *fname
= "\\lockt9.lck";
2264 bool correct
= False
;
2265 int pipe_in
[2], pipe_out
[2];
2269 struct timeval start
;
2273 printf("starting locktest9\n");
2275 if (local_path
== NULL
) {
2276 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2280 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2285 if (child_pid
== -1) {
2289 if (child_pid
== 0) {
2291 do_local_lock(pipe_out
[0], pipe_in
[1]);
2301 ret
= read(pipe_in
[0], &c
, 1);
2303 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2308 if (!torture_open_connection(&cli1
, 0)) {
2312 cli_sockopt(cli1
, sockops
);
2314 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2316 if (!NT_STATUS_IS_OK(status
)) {
2317 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2321 /* Ensure the child has the lock. */
2322 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2323 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2326 d_printf("Child has the lock.\n");
2329 /* Tell the child to wait 5 seconds then exit. */
2330 ret
= write(pipe_out
[1], &c
, 1);
2332 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2337 /* Wait 20 seconds for the lock. */
2338 alarm_fd
= cli1
->fd
;
2339 CatchSignal(SIGALRM
, alarm_handler_parent
);
2342 start
= timeval_current();
2344 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2345 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2346 "%s\n", cli_errstr(cli1
));
2351 seconds
= timeval_elapsed(&start
);
2353 printf("Parent got the lock after %.2f seconds.\n",
2356 status
= cli_close(cli1
, fnum
);
2357 if (!NT_STATUS_IS_OK(status
)) {
2358 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2365 cli_close(cli1
, fnum
);
2366 torture_close_connection(cli1
);
2370 printf("finished locktest9\n");
2375 test whether fnums and tids open on one VC are available on another (a major
2378 static bool run_fdpasstest(int dummy
)
2380 struct cli_state
*cli1
, *cli2
;
2381 const char *fname
= "\\fdpass.tst";
2385 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2388 cli_sockopt(cli1
, sockops
);
2389 cli_sockopt(cli2
, sockops
);
2391 printf("starting fdpasstest\n");
2393 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2395 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2396 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2400 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2401 printf("write failed (%s)\n", cli_errstr(cli1
));
2405 cli2
->vuid
= cli1
->vuid
;
2406 cli2
->cnum
= cli1
->cnum
;
2407 cli2
->pid
= cli1
->pid
;
2409 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2410 printf("read succeeded! nasty security hole [%s]\n",
2415 cli_close(cli1
, fnum1
);
2416 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2418 torture_close_connection(cli1
);
2419 torture_close_connection(cli2
);
2421 printf("finished fdpasstest\n");
2425 static bool run_fdsesstest(int dummy
)
2427 struct cli_state
*cli
;
2432 const char *fname
= "\\fdsess.tst";
2433 const char *fname1
= "\\fdsess1.tst";
2439 if (!torture_open_connection(&cli
, 0))
2441 cli_sockopt(cli
, sockops
);
2443 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2446 saved_cnum
= cli
->cnum
;
2447 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2449 new_cnum
= cli
->cnum
;
2450 cli
->cnum
= saved_cnum
;
2452 printf("starting fdsesstest\n");
2454 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2455 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2457 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2458 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2462 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2463 printf("write failed (%s)\n", cli_errstr(cli
));
2467 saved_vuid
= cli
->vuid
;
2468 cli
->vuid
= new_vuid
;
2470 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2471 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2475 /* Try to open a file with different vuid, samba cnum. */
2476 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2477 printf("create with different vuid, same cnum succeeded.\n");
2478 cli_close(cli
, fnum2
);
2479 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2481 printf("create with different vuid, same cnum failed.\n");
2482 printf("This will cause problems with service clients.\n");
2486 cli
->vuid
= saved_vuid
;
2488 /* Try with same vuid, different cnum. */
2489 cli
->cnum
= new_cnum
;
2491 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2492 printf("read succeeded with different cnum![%s]\n",
2497 cli
->cnum
= saved_cnum
;
2498 cli_close(cli
, fnum1
);
2499 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2501 torture_close_connection(cli
);
2503 printf("finished fdsesstest\n");
2508 This test checks that
2510 1) the server does not allow an unlink on a file that is open
2512 static bool run_unlinktest(int dummy
)
2514 struct cli_state
*cli
;
2515 const char *fname
= "\\unlink.tst";
2517 bool correct
= True
;
2519 if (!torture_open_connection(&cli
, 0)) {
2523 cli_sockopt(cli
, sockops
);
2525 printf("starting unlink test\n");
2527 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2531 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2532 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2536 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2537 printf("error: server allowed unlink on an open file\n");
2540 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2541 NT_STATUS_SHARING_VIOLATION
);
2544 cli_close(cli
, fnum
);
2545 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2547 if (!torture_close_connection(cli
)) {
2551 printf("unlink test finished\n");
2558 test how many open files this server supports on the one socket
2560 static bool run_maxfidtest(int dummy
)
2562 struct cli_state
*cli
;
2563 const char *ftemplate
= "\\maxfid.%d.%d";
2565 uint16_t fnums
[0x11000];
2568 bool correct
= True
;
2573 printf("failed to connect\n");
2577 cli_sockopt(cli
, sockops
);
2579 for (i
=0; i
<0x11000; i
++) {
2580 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2581 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2582 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2583 printf("open of %s failed (%s)\n",
2584 fname
, cli_errstr(cli
));
2585 printf("maximum fnum is %d\n", i
);
2593 printf("cleaning up\n");
2595 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2596 cli_close(cli
, fnums
[i
]);
2597 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2598 printf("unlink of %s failed (%s)\n",
2599 fname
, cli_errstr(cli
));
2606 printf("maxfid test finished\n");
2607 if (!torture_close_connection(cli
)) {
2613 /* generate a random buffer */
2614 static void rand_buf(char *buf
, int len
)
2617 *buf
= (char)sys_random();
2622 /* send smb negprot commands, not reading the response */
2623 static bool run_negprot_nowait(int dummy
)
2626 static struct cli_state
*cli
;
2627 bool correct
= True
;
2629 printf("starting negprot nowait test\n");
2631 if (!(cli
= open_nbt_connection())) {
2635 for (i
=0;i
<50000;i
++) {
2636 cli_negprot_sendsync(cli
);
2639 if (!torture_close_connection(cli
)) {
2643 printf("finished negprot nowait test\n");
2649 /* send random IPC commands */
2650 static bool run_randomipc(int dummy
)
2652 char *rparam
= NULL
;
2654 unsigned int rdrcnt
,rprcnt
;
2656 int api
, param_len
, i
;
2657 struct cli_state
*cli
;
2658 bool correct
= True
;
2661 printf("starting random ipc test\n");
2663 if (!torture_open_connection(&cli
, 0)) {
2667 for (i
=0;i
<count
;i
++) {
2668 api
= sys_random() % 500;
2669 param_len
= (sys_random() % 64);
2671 rand_buf(param
, param_len
);
2676 param
, param_len
, 8,
2677 NULL
, 0, BUFFER_SIZE
,
2681 printf("%d/%d\r", i
,count
);
2684 printf("%d/%d\n", i
, count
);
2686 if (!torture_close_connection(cli
)) {
2690 printf("finished random ipc test\n");
2697 static void browse_callback(const char *sname
, uint32 stype
,
2698 const char *comment
, void *state
)
2700 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2706 This test checks the browse list code
2709 static bool run_browsetest(int dummy
)
2711 static struct cli_state
*cli
;
2712 bool correct
= True
;
2714 printf("starting browse test\n");
2716 if (!torture_open_connection(&cli
, 0)) {
2720 printf("domain list:\n");
2721 cli_NetServerEnum(cli
, cli
->server_domain
,
2722 SV_TYPE_DOMAIN_ENUM
,
2723 browse_callback
, NULL
);
2725 printf("machine list:\n");
2726 cli_NetServerEnum(cli
, cli
->server_domain
,
2728 browse_callback
, NULL
);
2730 if (!torture_close_connection(cli
)) {
2734 printf("browse test finished\n");
2742 This checks how the getatr calls works
2744 static bool run_attrtest(int dummy
)
2746 struct cli_state
*cli
;
2749 const char *fname
= "\\attrib123456789.tst";
2750 bool correct
= True
;
2752 printf("starting attrib test\n");
2754 if (!torture_open_connection(&cli
, 0)) {
2758 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2759 cli_open(cli
, fname
,
2760 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2761 cli_close(cli
, fnum
);
2762 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2763 printf("getatr failed (%s)\n", cli_errstr(cli
));
2767 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2768 printf("ERROR: SMBgetatr bug. time is %s",
2774 t2
= t
-60*60*24; /* 1 day ago */
2776 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
2777 printf("setatr failed (%s)\n", cli_errstr(cli
));
2781 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2782 printf("getatr failed (%s)\n", cli_errstr(cli
));
2787 printf("ERROR: getatr/setatr bug. times are\n%s",
2789 printf("%s", ctime(&t2
));
2793 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2795 if (!torture_close_connection(cli
)) {
2799 printf("attrib test finished\n");
2806 This checks a couple of trans2 calls
2808 static bool run_trans2test(int dummy
)
2810 struct cli_state
*cli
;
2813 time_t c_time
, a_time
, m_time
;
2814 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
2815 const char *fname
= "\\trans2.tst";
2816 const char *dname
= "\\trans2";
2817 const char *fname2
= "\\trans2\\trans2.tst";
2819 bool correct
= True
;
2823 printf("starting trans2 test\n");
2825 if (!torture_open_connection(&cli
, 0)) {
2829 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
2830 if (!NT_STATUS_IS_OK(status
)) {
2831 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2836 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2837 cli_open(cli
, fname
,
2838 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2839 if (!cli_qfileinfo(cli
, fnum
, NULL
, &size
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2840 &m_time_ts
, NULL
)) {
2841 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
2845 if (!cli_qfilename(cli
, fnum
, pname
, sizeof(pname
))) {
2846 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
2850 if (strcmp(pname
, fname
)) {
2851 printf("qfilename gave different name? [%s] [%s]\n",
2856 cli_close(cli
, fnum
);
2860 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2861 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2862 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
2863 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2866 cli_close(cli
, fnum
);
2868 if (!cli_qpathinfo(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
)) {
2869 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli
));
2872 if (c_time
!= m_time
) {
2873 printf("create time=%s", ctime(&c_time
));
2874 printf("modify time=%s", ctime(&m_time
));
2875 printf("This system appears to have sticky create times\n");
2877 if (a_time
% (60*60) == 0) {
2878 printf("access time=%s", ctime(&a_time
));
2879 printf("This system appears to set a midnight access time\n");
2883 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
2884 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
2890 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2891 cli_open(cli
, fname
,
2892 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2893 cli_close(cli
, fnum
);
2894 if (!cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2895 &m_time_ts
, &size
, NULL
, NULL
)) {
2896 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2899 if (w_time_ts
.tv_sec
< 60*60*24*2) {
2900 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
2901 printf("This system appears to set a initial 0 write time\n");
2906 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2909 /* check if the server updates the directory modification time
2910 when creating a new file */
2911 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
2912 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
2916 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2917 &m_time_ts
, &size
, NULL
, NULL
)) {
2918 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2922 cli_open(cli
, fname2
,
2923 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2924 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
2925 cli_close(cli
, fnum
);
2926 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2927 &m_time2_ts
, &size
, NULL
, NULL
)) {
2928 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2931 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
2933 printf("This system does not update directory modification times\n");
2937 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
2938 cli_rmdir(cli
, dname
);
2940 if (!torture_close_connection(cli
)) {
2944 printf("trans2 test finished\n");
2950 This checks new W2K calls.
2953 static bool new_trans(struct cli_state
*pcli
, int fnum
, int level
)
2957 bool correct
= True
;
2959 if (!cli_qfileinfo_test(pcli
, fnum
, level
, &buf
, &len
)) {
2960 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
, cli_errstr(pcli
));
2963 printf("qfileinfo: level %d, len = %u\n", level
, len
);
2964 dump_data(0, (uint8
*)buf
, len
);
2971 static bool run_w2ktest(int dummy
)
2973 struct cli_state
*cli
;
2975 const char *fname
= "\\w2ktest\\w2k.tst";
2977 bool correct
= True
;
2979 printf("starting w2k test\n");
2981 if (!torture_open_connection(&cli
, 0)) {
2985 cli_open(cli
, fname
,
2986 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
2988 for (level
= 1004; level
< 1040; level
++) {
2989 new_trans(cli
, fnum
, level
);
2992 cli_close(cli
, fnum
);
2994 if (!torture_close_connection(cli
)) {
2998 printf("w2k test finished\n");
3005 this is a harness for some oplock tests
3007 static bool run_oplock1(int dummy
)
3009 struct cli_state
*cli1
;
3010 const char *fname
= "\\lockt1.lck";
3012 bool correct
= True
;
3014 printf("starting oplock test 1\n");
3016 if (!torture_open_connection(&cli1
, 0)) {
3020 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3022 cli_sockopt(cli1
, sockops
);
3024 cli1
->use_oplocks
= True
;
3026 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3027 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3031 cli1
->use_oplocks
= False
;
3033 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3034 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3036 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3037 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3041 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3042 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3046 if (!torture_close_connection(cli1
)) {
3050 printf("finished oplock test 1\n");
3055 static bool run_oplock2(int dummy
)
3057 struct cli_state
*cli1
, *cli2
;
3058 const char *fname
= "\\lockt2.lck";
3059 uint16_t fnum1
, fnum2
;
3060 int saved_use_oplocks
= use_oplocks
;
3062 bool correct
= True
;
3063 volatile bool *shared_correct
;
3065 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3066 *shared_correct
= True
;
3068 use_level_II_oplocks
= True
;
3071 printf("starting oplock test 2\n");
3073 if (!torture_open_connection(&cli1
, 0)) {
3074 use_level_II_oplocks
= False
;
3075 use_oplocks
= saved_use_oplocks
;
3079 cli1
->use_oplocks
= True
;
3080 cli1
->use_level_II_oplocks
= True
;
3082 if (!torture_open_connection(&cli2
, 1)) {
3083 use_level_II_oplocks
= False
;
3084 use_oplocks
= saved_use_oplocks
;
3088 cli2
->use_oplocks
= True
;
3089 cli2
->use_level_II_oplocks
= True
;
3091 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3093 cli_sockopt(cli1
, sockops
);
3094 cli_sockopt(cli2
, sockops
);
3096 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3097 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3101 /* Don't need the globals any more. */
3102 use_level_II_oplocks
= False
;
3103 use_oplocks
= saved_use_oplocks
;
3107 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3108 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3109 *shared_correct
= False
;
3115 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3116 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3117 *shared_correct
= False
;
3125 /* Ensure cli1 processes the break. Empty file should always return 0
3128 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3129 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3133 /* Should now be at level II. */
3134 /* Test if sending a write locks causes a break to none. */
3136 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3137 printf("lock failed (%s)\n", cli_errstr(cli1
));
3141 cli_unlock(cli1
, fnum1
, 0, 4);
3145 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3146 printf("lock failed (%s)\n", cli_errstr(cli1
));
3150 cli_unlock(cli1
, fnum1
, 0, 4);
3154 cli_read(cli1
, fnum1
, buf
, 0, 4);
3157 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3158 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
3163 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3164 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3170 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3171 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3175 if (!torture_close_connection(cli1
)) {
3179 if (!*shared_correct
) {
3183 printf("finished oplock test 2\n");
3188 /* handler for oplock 3 tests */
3189 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3191 printf("got oplock break fnum=%d level=%d\n",
3193 return cli_oplock_ack(cli
, fnum
, level
);
3196 static bool run_oplock3(int dummy
)
3198 struct cli_state
*cli
;
3199 const char *fname
= "\\oplockt3.dat";
3201 char buf
[4] = "abcd";
3202 bool correct
= True
;
3203 volatile bool *shared_correct
;
3205 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3206 *shared_correct
= True
;
3208 printf("starting oplock test 3\n");
3213 use_level_II_oplocks
= True
;
3214 if (!torture_open_connection(&cli
, 0)) {
3215 *shared_correct
= False
;
3219 /* try to trigger a oplock break in parent */
3220 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3221 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3227 use_level_II_oplocks
= True
;
3228 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3231 cli_oplock_handler(cli
, oplock3_handler
);
3232 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3233 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3234 cli_close(cli
, fnum
);
3235 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3236 cli
->timeout
= 20000;
3237 cli_receive_smb(cli
);
3238 printf("finished oplock test 3\n");
3240 return (correct
&& *shared_correct
);
3242 /* What are we looking for here? What's sucess and what's FAILURE? */
3248 Test delete on close semantics.
3250 static bool run_deletetest(int dummy
)
3252 struct cli_state
*cli1
= NULL
;
3253 struct cli_state
*cli2
= NULL
;
3254 const char *fname
= "\\delete.file";
3255 uint16_t fnum1
= (uint16_t)-1;
3256 uint16_t fnum2
= (uint16_t)-1;
3257 bool correct
= True
;
3259 printf("starting delete test\n");
3261 if (!torture_open_connection(&cli1
, 0)) {
3265 cli_sockopt(cli1
, sockops
);
3267 /* Test 1 - this should delete the file on close. */
3269 cli_setatr(cli1
, fname
, 0, 0);
3270 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3272 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3273 0, FILE_OVERWRITE_IF
,
3274 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3275 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3282 uint32
*accinfo
= NULL
;
3284 cli_qfileinfo_test(cli1
, fnum1
, SMB_FILE_ACCESS_INFORMATION
, (char **)&accinfo
, &len
);
3286 printf("access mode = 0x%lx\n", *accinfo
);
3291 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3292 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3297 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3298 printf("[1] open of %s succeeded (should fail)\n", fname
);
3303 printf("first delete on close test succeeded.\n");
3305 /* Test 2 - this should delete the file on close. */
3307 cli_setatr(cli1
, fname
, 0, 0);
3308 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3310 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3311 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3312 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3313 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3318 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3319 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3324 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3325 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3330 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3331 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3332 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3333 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3337 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3339 printf("second delete on close test succeeded.\n");
3342 cli_setatr(cli1
, fname
, 0, 0);
3343 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3345 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3346 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3347 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3352 /* This should fail with a sharing violation - open for delete is only compatible
3353 with SHARE_DELETE. */
3355 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3356 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3357 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3362 /* This should succeed. */
3364 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3365 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3366 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3371 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3372 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3377 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3378 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3383 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3384 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3389 /* This should fail - file should no longer be there. */
3391 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3392 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3393 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3394 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3396 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3400 printf("third delete on close test succeeded.\n");
3403 cli_setatr(cli1
, fname
, 0, 0);
3404 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3406 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3407 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3408 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3413 /* This should succeed. */
3414 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3415 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3416 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3421 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3422 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3427 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3428 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3433 /* This should fail - no more opens once delete on close set. */
3434 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3435 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3436 FILE_OPEN
, 0, 0, &fnum2
))) {
3437 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3441 printf("fourth delete on close test succeeded.\n");
3443 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3444 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3450 cli_setatr(cli1
, fname
, 0, 0);
3451 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3453 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3454 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3459 /* This should fail - only allowed on NT opens with DELETE access. */
3461 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3462 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3467 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3468 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3473 printf("fifth delete on close test succeeded.\n");
3476 cli_setatr(cli1
, fname
, 0, 0);
3477 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3479 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3480 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3481 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3482 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3487 /* This should fail - only allowed on NT opens with DELETE access. */
3489 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3490 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3495 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3496 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3501 printf("sixth delete on close test succeeded.\n");
3504 cli_setatr(cli1
, fname
, 0, 0);
3505 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3507 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3508 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3509 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3514 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3515 printf("[7] setting delete_on_close on file failed !\n");
3520 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3521 printf("[7] unsetting delete_on_close on file failed !\n");
3526 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3527 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3532 /* This next open should succeed - we reset the flag. */
3534 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3535 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3540 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3541 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3546 printf("seventh delete on close test succeeded.\n");
3549 cli_setatr(cli1
, fname
, 0, 0);
3550 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3552 if (!torture_open_connection(&cli2
, 1)) {
3553 printf("[8] failed to open second connection.\n");
3558 cli_sockopt(cli1
, sockops
);
3560 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3561 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3562 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3563 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3568 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3569 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3570 FILE_OPEN
, 0, 0, &fnum2
))) {
3571 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3576 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3577 printf("[8] setting delete_on_close on file failed !\n");
3582 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3583 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3588 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3589 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3594 /* This should fail.. */
3595 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3596 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3600 printf("eighth delete on close test succeeded.\n");
3602 /* This should fail - we need to set DELETE_ACCESS. */
3603 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3604 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3605 printf("[9] open of %s succeeded should have failed!\n", fname
);
3610 printf("ninth delete on close test succeeded.\n");
3612 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3613 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3614 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3619 /* This should delete the file. */
3620 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3621 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3626 /* This should fail.. */
3627 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3628 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3632 printf("tenth delete on close test succeeded.\n");
3634 cli_setatr(cli1
, fname
, 0, 0);
3635 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3637 /* What error do we get when attempting to open a read-only file with
3640 /* Create a readonly file. */
3641 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3642 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3643 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3648 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3649 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3654 /* Now try open for delete access. */
3655 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3656 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3657 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3658 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3659 cli_close(cli1
, fnum1
);
3663 NTSTATUS nterr
= cli_nt_error(cli1
);
3664 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
3665 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
3669 printf("eleventh delete on close test succeeded.\n");
3673 printf("finished delete test\n");
3676 /* FIXME: This will crash if we aborted before cli2 got
3677 * intialized, because these functions don't handle
3678 * uninitialized connections. */
3680 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
3681 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
3682 cli_setatr(cli1
, fname
, 0, 0);
3683 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3685 if (cli1
&& !torture_close_connection(cli1
)) {
3688 if (cli2
&& !torture_close_connection(cli2
)) {
3696 print out server properties
3698 static bool run_properties(int dummy
)
3700 struct cli_state
*cli
;
3701 bool correct
= True
;
3703 printf("starting properties test\n");
3707 if (!torture_open_connection(&cli
, 0)) {
3711 cli_sockopt(cli
, sockops
);
3713 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
3715 if (!torture_close_connection(cli
)) {
3724 /* FIRST_DESIRED_ACCESS 0xf019f */
3725 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3726 FILE_READ_EA| /* 0xf */ \
3727 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3728 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3729 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3730 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3731 /* SECOND_DESIRED_ACCESS 0xe0080 */
3732 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3733 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3734 WRITE_OWNER_ACCESS /* 0xe0000 */
3737 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3738 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3740 WRITE_OWNER_ACCESS /* */
3744 Test ntcreate calls made by xcopy
3746 static bool run_xcopy(int dummy
)
3748 static struct cli_state
*cli1
;
3749 const char *fname
= "\\test.txt";
3750 bool correct
= True
;
3751 uint16_t fnum1
, fnum2
;
3753 printf("starting xcopy test\n");
3755 if (!torture_open_connection(&cli1
, 0)) {
3759 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3760 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
3761 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
3762 0x4044, 0, &fnum1
))) {
3763 printf("First open failed - %s\n", cli_errstr(cli1
));
3767 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3768 SECOND_DESIRED_ACCESS
, 0,
3769 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
3770 0x200000, 0, &fnum2
))) {
3771 printf("second open failed - %s\n", cli_errstr(cli1
));
3775 if (!torture_close_connection(cli1
)) {
3783 Test rename on files open with share delete and no share delete.
3785 static bool run_rename(int dummy
)
3787 static struct cli_state
*cli1
;
3788 const char *fname
= "\\test.txt";
3789 const char *fname1
= "\\test1.txt";
3790 bool correct
= True
;
3794 printf("starting rename test\n");
3796 if (!torture_open_connection(&cli1
, 0)) {
3800 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3801 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3802 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3803 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3804 printf("First open failed - %s\n", cli_errstr(cli1
));
3808 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3809 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
3811 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3815 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3816 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
3820 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3821 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3822 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3824 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
3826 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
3828 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3829 if (!NT_STATUS_IS_OK(status
)) {
3830 printf("Second open failed - %s\n", cli_errstr(cli1
));
3834 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3835 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
3838 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3841 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3842 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
3846 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3847 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3849 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3850 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3851 printf("Third open failed - %s\n", cli_errstr(cli1
));
3860 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3861 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
3862 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3865 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
3866 printf("[8] setting delete_on_close on file failed !\n");
3870 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3871 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3877 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3878 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
3881 printf("Third rename succeeded (SHARE_NONE)\n");
3884 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3885 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
3889 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3890 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3894 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3895 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3896 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3900 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3901 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
3903 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3907 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3908 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3912 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3913 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3917 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3918 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3919 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
3923 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3924 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3928 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
3932 * Now check if the first name still exists ...
3935 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3937 printf("Opening original file after rename of open file fails: %s\n",
3941 printf("Opening original file after rename of open file works ...\n");
3942 (void)cli_close(cli1, fnum2);
3948 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3949 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
3953 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3954 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3956 if (!torture_close_connection(cli1
)) {
3963 static bool run_pipe_number(int dummy
)
3965 struct cli_state
*cli1
;
3966 const char *pipe_name
= "\\SPOOLSS";
3970 printf("starting pipenumber test\n");
3971 if (!torture_open_connection(&cli1
, 0)) {
3975 cli_sockopt(cli1
, sockops
);
3977 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
3978 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
3979 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
3983 printf("\r%6d", num_pipes
);
3986 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
3987 torture_close_connection(cli1
);
3992 Test open mode returns on read-only files.
3994 static bool run_opentest(int dummy
)
3996 static struct cli_state
*cli1
;
3997 static struct cli_state
*cli2
;
3998 const char *fname
= "\\readonly.file";
3999 uint16_t fnum1
, fnum2
;
4002 bool correct
= True
;
4005 printf("starting open test\n");
4007 if (!torture_open_connection(&cli1
, 0)) {
4011 cli_setatr(cli1
, fname
, 0, 0);
4012 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4014 cli_sockopt(cli1
, sockops
);
4016 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4017 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4021 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4022 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4026 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4027 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
4031 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4032 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4036 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4037 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4039 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4040 NT_STATUS_ACCESS_DENIED
)) {
4041 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4044 printf("finished open test 1\n");
4046 cli_close(cli1
, fnum1
);
4048 /* Now try not readonly and ensure ERRbadshare is returned. */
4050 cli_setatr(cli1
, fname
, 0, 0);
4052 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4053 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4057 /* This will fail - but the error should be ERRshare. */
4058 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4060 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4061 NT_STATUS_SHARING_VIOLATION
)) {
4062 printf("correct error code ERRDOS/ERRbadshare returned\n");
4065 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4066 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4070 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4072 printf("finished open test 2\n");
4074 /* Test truncate open disposition on file opened for read. */
4076 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4077 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4081 /* write 20 bytes. */
4083 memset(buf
, '\0', 20);
4085 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4086 printf("write failed (%s)\n", cli_errstr(cli1
));
4090 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4091 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4095 /* Ensure size == 20. */
4096 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4097 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4102 printf("(3) file size != 20\n");
4106 /* Now test if we can truncate a file opened for readonly. */
4108 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4109 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4113 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4114 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4118 /* Ensure size == 0. */
4119 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4120 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4125 printf("(3) file size != 0\n");
4128 printf("finished open test 3\n");
4130 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4133 printf("testing ctemp\n");
4134 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4135 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4138 printf("ctemp gave path %s\n", tmp_path
);
4139 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4140 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4142 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4143 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4146 /* Test the non-io opens... */
4148 if (!torture_open_connection(&cli2
, 1)) {
4152 cli_setatr(cli2
, fname
, 0, 0);
4153 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4155 cli_sockopt(cli2
, sockops
);
4157 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4159 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4160 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4161 printf("test 1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4165 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4166 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4167 printf("test 1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4171 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4172 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4175 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4176 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4180 printf("non-io open test #1 passed.\n");
4182 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4184 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4186 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4187 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4188 printf("test 2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4192 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4193 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4194 printf("test 2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4198 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4199 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4202 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4203 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4207 printf("non-io open test #2 passed.\n");
4209 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4211 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4213 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4214 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4215 printf("test 3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4219 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4220 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4221 printf("test 3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4225 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4226 printf("test 3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4229 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4230 printf("test 3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4234 printf("non-io open test #3 passed.\n");
4236 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4238 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4240 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4241 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4242 printf("test 4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4246 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4247 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4248 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4252 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4254 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4255 printf("test 4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4259 printf("non-io open test #4 passed.\n");
4261 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4263 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4265 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4266 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4267 printf("test 5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4271 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4272 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4273 printf("test 5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4277 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4278 printf("test 5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4282 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4283 printf("test 5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4287 printf("non-io open test #5 passed.\n");
4289 printf("TEST #6 testing 1 non-io open, one io open\n");
4291 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4294 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4295 printf("test 6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4299 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4300 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4301 printf("test 6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4305 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4306 printf("test 6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4310 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4311 printf("test 6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4315 printf("non-io open test #6 passed.\n");
4317 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4319 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4321 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4322 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4323 printf("test 7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4327 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4328 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4329 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4333 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4335 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4336 printf("test 7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4340 printf("non-io open test #7 passed.\n");
4342 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4344 if (!torture_close_connection(cli1
)) {
4347 if (!torture_close_connection(cli2
)) {
4354 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4356 uint16 major
, minor
;
4357 uint32 caplow
, caphigh
;
4360 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4361 printf("Server doesn't support UNIX CIFS extensions.\n");
4362 return NT_STATUS_NOT_SUPPORTED
;
4365 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4367 if (!NT_STATUS_IS_OK(status
)) {
4368 printf("Server didn't return UNIX CIFS extensions: %s\n",
4373 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4375 if (!NT_STATUS_IS_OK(status
)) {
4376 printf("Server doesn't support setting UNIX CIFS extensions: "
4377 "%s.\n", nt_errstr(status
));
4381 return NT_STATUS_OK
;
4385 Test POSIX open /mkdir calls.
4387 static bool run_simple_posix_open_test(int dummy
)
4389 static struct cli_state
*cli1
;
4390 const char *fname
= "posix:file";
4391 const char *hname
= "posix:hlink";
4392 const char *sname
= "posix:symlink";
4393 const char *dname
= "posix:dir";
4396 uint16_t fnum1
= (uint16_t)-1;
4397 SMB_STRUCT_STAT sbuf
;
4398 bool correct
= false;
4401 printf("Starting simple POSIX open test\n");
4403 if (!torture_open_connection(&cli1
, 0)) {
4407 cli_sockopt(cli1
, sockops
);
4409 status
= torture_setup_unix_extensions(cli1
);
4410 if (!NT_STATUS_IS_OK(status
)) {
4414 cli_setatr(cli1
, fname
, 0, 0);
4415 cli_posix_unlink(cli1
, fname
);
4416 cli_setatr(cli1
, dname
, 0, 0);
4417 cli_posix_rmdir(cli1
, dname
);
4418 cli_setatr(cli1
, hname
, 0, 0);
4419 cli_posix_unlink(cli1
, hname
);
4420 cli_setatr(cli1
, sname
, 0, 0);
4421 cli_posix_unlink(cli1
, sname
);
4423 /* Create a directory. */
4424 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4425 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4429 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4430 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4434 /* Test ftruncate - set file size. */
4435 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4436 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4440 /* Ensure st_size == 1000 */
4441 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4442 printf("stat failed (%s)\n", cli_errstr(cli1
));
4446 if (sbuf
.st_ex_size
!= 1000) {
4447 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4451 /* Test ftruncate - set file size back to zero. */
4452 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4453 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4457 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4458 printf("close failed (%s)\n", cli_errstr(cli1
));
4462 /* Now open the file again for read only. */
4463 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4464 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4468 /* Now unlink while open. */
4469 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
4470 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4474 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4475 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4479 /* Ensure the file has gone. */
4480 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4481 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4485 /* What happens when we try and POSIX open a directory ? */
4486 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
4487 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
4490 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
4491 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4496 /* Create the file. */
4497 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4498 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4502 /* Write some data into it. */
4503 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4504 printf("cli_write failed: %s\n", cli_errstr(cli1
));
4508 cli_close(cli1
, fnum1
);
4510 /* Now create a hardlink. */
4511 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
4512 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4516 /* Now create a symlink. */
4517 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
4518 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
4522 /* Open the hardlink for read. */
4523 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
4524 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4528 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
4529 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4533 if (memcmp(buf
, "TEST DATA\n", 10)) {
4534 printf("invalid data read from hardlink\n");
4538 /* Do a POSIX lock/unlock. */
4539 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
4540 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
4544 /* Punch a hole in the locked area. */
4545 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
4546 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
4550 cli_close(cli1
, fnum1
);
4552 /* Open the symlink for read - this should fail. A POSIX
4553 client should not be doing opens on a symlink. */
4554 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
4555 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
4558 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
4559 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
4560 printf("POSIX open of %s should have failed "
4561 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4562 "failed with %s instead.\n",
4563 sname
, cli_errstr(cli1
));
4568 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
4569 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
4573 if (strcmp(namebuf
, fname
) != 0) {
4574 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4575 sname
, fname
, namebuf
);
4579 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
4580 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
4584 printf("Simple POSIX open test passed\n");
4589 if (fnum1
!= (uint16_t)-1) {
4590 cli_close(cli1
, fnum1
);
4591 fnum1
= (uint16_t)-1;
4594 cli_setatr(cli1
, sname
, 0, 0);
4595 cli_posix_unlink(cli1
, sname
);
4596 cli_setatr(cli1
, hname
, 0, 0);
4597 cli_posix_unlink(cli1
, hname
);
4598 cli_setatr(cli1
, fname
, 0, 0);
4599 cli_posix_unlink(cli1
, fname
);
4600 cli_setatr(cli1
, dname
, 0, 0);
4601 cli_posix_rmdir(cli1
, dname
);
4603 if (!torture_close_connection(cli1
)) {
4611 static uint32 open_attrs_table
[] = {
4612 FILE_ATTRIBUTE_NORMAL
,
4613 FILE_ATTRIBUTE_ARCHIVE
,
4614 FILE_ATTRIBUTE_READONLY
,
4615 FILE_ATTRIBUTE_HIDDEN
,
4616 FILE_ATTRIBUTE_SYSTEM
,
4618 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
4619 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
4620 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
4621 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4622 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4623 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4625 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4626 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4627 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4628 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
4631 struct trunc_open_results
{
4638 static struct trunc_open_results attr_results
[] = {
4639 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4640 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4641 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4642 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4643 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4644 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4645 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4646 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4647 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4648 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4649 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4650 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
4651 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4652 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4653 { 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
},
4654 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4655 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4656 { 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
},
4657 { 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
},
4658 { 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
},
4659 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4660 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4661 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4662 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4663 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4664 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
4667 static bool run_openattrtest(int dummy
)
4669 static struct cli_state
*cli1
;
4670 const char *fname
= "\\openattr.file";
4672 bool correct
= True
;
4674 unsigned int i
, j
, k
, l
;
4676 printf("starting open attr test\n");
4678 if (!torture_open_connection(&cli1
, 0)) {
4682 cli_sockopt(cli1
, sockops
);
4684 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
4685 cli_setatr(cli1
, fname
, 0, 0);
4686 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4687 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
4688 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4689 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4693 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4694 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4698 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
4699 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
4700 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
4701 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4702 if (attr_results
[l
].num
== k
) {
4703 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4704 k
, open_attrs_table
[i
],
4705 open_attrs_table
[j
],
4706 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
4710 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
4711 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4712 k
, open_attrs_table
[i
], open_attrs_table
[j
],
4717 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
4723 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4724 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
4728 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
4729 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
4734 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4735 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
4738 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4739 if (attr_results
[l
].num
== k
) {
4740 if (attr
!= attr_results
[l
].result_attr
||
4741 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
4742 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
4743 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4744 open_attrs_table
[i
],
4745 open_attrs_table
[j
],
4747 attr_results
[l
].result_attr
);
4757 cli_setatr(cli1
, fname
, 0, 0);
4758 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4760 printf("open attr test %s.\n", correct
? "passed" : "failed");
4762 if (!torture_close_connection(cli1
)) {
4768 static void list_fn(const char *mnt
, file_info
*finfo
, const char *name
, void *state
)
4774 test directory listing speed
4776 static bool run_dirtest(int dummy
)
4779 static struct cli_state
*cli
;
4781 struct timeval core_start
;
4782 bool correct
= True
;
4784 printf("starting directory test\n");
4786 if (!torture_open_connection(&cli
, 0)) {
4790 cli_sockopt(cli
, sockops
);
4793 for (i
=0;i
<torture_numops
;i
++) {
4795 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4796 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
4797 fprintf(stderr
,"Failed to open %s\n", fname
);
4800 cli_close(cli
, fnum
);
4803 core_start
= timeval_current();
4805 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
4806 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
4807 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
4809 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
4812 for (i
=0;i
<torture_numops
;i
++) {
4814 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4815 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4818 if (!torture_close_connection(cli
)) {
4822 printf("finished dirtest\n");
4827 static void del_fn(const char *mnt
, file_info
*finfo
, const char *mask
, void *state
)
4829 struct cli_state
*pcli
= (struct cli_state
*)state
;
4831 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
4833 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
4836 if (finfo
->mode
& aDIR
) {
4837 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
4838 printf("del_fn: failed to rmdir %s\n,", fname
);
4840 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
4841 printf("del_fn: failed to unlink %s\n,", fname
);
4847 sees what IOCTLs are supported
4849 bool torture_ioctl_test(int dummy
)
4851 static struct cli_state
*cli
;
4852 uint16_t device
, function
;
4854 const char *fname
= "\\ioctl.dat";
4858 if (!torture_open_connection(&cli
, 0)) {
4862 printf("starting ioctl test\n");
4864 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4866 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4867 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4871 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
4872 printf("ioctl device info: %s\n", cli_errstr(cli
));
4874 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
4875 printf("ioctl job info: %s\n", cli_errstr(cli
));
4877 for (device
=0;device
<0x100;device
++) {
4878 printf("testing device=0x%x\n", device
);
4879 for (function
=0;function
<0x100;function
++) {
4880 uint32 code
= (device
<<16) | function
;
4882 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
4884 if (NT_STATUS_IS_OK(status
)) {
4885 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
4887 data_blob_free(&blob
);
4892 if (!torture_close_connection(cli
)) {
4901 tries varients of chkpath
4903 bool torture_chkpath_test(int dummy
)
4905 static struct cli_state
*cli
;
4909 if (!torture_open_connection(&cli
, 0)) {
4913 printf("starting chkpath test\n");
4915 /* cleanup from an old run */
4916 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4917 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
4918 cli_rmdir(cli
, "\\chkpath.dir");
4920 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
4921 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
4925 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
4926 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
4930 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4931 printf("open1 failed (%s)\n", cli_errstr(cli
));
4934 cli_close(cli
, fnum
);
4936 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
4937 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
4941 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
4942 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
4946 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
4947 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4948 NT_STATUS_NOT_A_DIRECTORY
);
4950 printf("* chkpath on a file should fail\n");
4954 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
4955 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
4956 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
4958 printf("* chkpath on a non existant file should fail\n");
4962 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4963 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4964 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
4966 printf("* chkpath on a non existent component should fail\n");
4970 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4971 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
4972 cli_rmdir(cli
, "\\chkpath.dir");
4974 if (!torture_close_connection(cli
)) {
4981 static bool run_eatest(int dummy
)
4983 static struct cli_state
*cli
;
4984 const char *fname
= "\\eatest.txt";
4985 bool correct
= True
;
4989 struct ea_struct
*ea_list
= NULL
;
4990 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
4992 printf("starting eatest\n");
4994 if (!torture_open_connection(&cli
, 0)) {
4995 talloc_destroy(mem_ctx
);
4999 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5000 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5001 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5002 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5003 0x4044, 0, &fnum
))) {
5004 printf("open failed - %s\n", cli_errstr(cli
));
5005 talloc_destroy(mem_ctx
);
5009 for (i
= 0; i
< 10; i
++) {
5010 fstring ea_name
, ea_val
;
5012 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5013 memset(ea_val
, (char)i
+1, i
+1);
5014 if (!cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1)) {
5015 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5016 talloc_destroy(mem_ctx
);
5021 cli_close(cli
, fnum
);
5022 for (i
= 0; i
< 10; i
++) {
5023 fstring ea_name
, ea_val
;
5025 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5026 memset(ea_val
, (char)i
+1, i
+1);
5027 if (!cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1)) {
5028 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5029 talloc_destroy(mem_ctx
);
5034 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
5035 printf("ea_get list failed - %s\n", cli_errstr(cli
));
5039 printf("num_eas = %d\n", (int)num_eas
);
5041 if (num_eas
!= 20) {
5042 printf("Should be 20 EA's stored... failing.\n");
5046 for (i
= 0; i
< num_eas
; i
++) {
5047 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5048 dump_data(0, ea_list
[i
].value
.data
,
5049 ea_list
[i
].value
.length
);
5052 /* Setting EA's to zero length deletes them. Test this */
5053 printf("Now deleting all EA's - case indepenent....\n");
5056 cli_set_ea_path(cli
, fname
, "", "", 0);
5058 for (i
= 0; i
< 20; i
++) {
5060 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5061 if (!cli_set_ea_path(cli
, fname
, ea_name
, "", 0)) {
5062 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5063 talloc_destroy(mem_ctx
);
5069 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
5070 printf("ea_get list failed - %s\n", cli_errstr(cli
));
5074 printf("num_eas = %d\n", (int)num_eas
);
5075 for (i
= 0; i
< num_eas
; i
++) {
5076 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5077 dump_data(0, ea_list
[i
].value
.data
,
5078 ea_list
[i
].value
.length
);
5082 printf("deleting EA's failed.\n");
5086 /* Try and delete a non existant EA. */
5087 if (!cli_set_ea_path(cli
, fname
, "foo", "", 0)) {
5088 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli
));
5092 talloc_destroy(mem_ctx
);
5093 if (!torture_close_connection(cli
)) {
5100 static bool run_dirtest1(int dummy
)
5103 static struct cli_state
*cli
;
5106 bool correct
= True
;
5108 printf("starting directory test\n");
5110 if (!torture_open_connection(&cli
, 0)) {
5114 cli_sockopt(cli
, sockops
);
5116 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5117 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5118 cli_rmdir(cli
, "\\LISTDIR");
5119 cli_mkdir(cli
, "\\LISTDIR");
5121 /* Create 1000 files and 1000 directories. */
5122 for (i
=0;i
<1000;i
++) {
5124 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5125 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5126 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5127 fprintf(stderr
,"Failed to open %s\n", fname
);
5130 cli_close(cli
, fnum
);
5132 for (i
=0;i
<1000;i
++) {
5134 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5135 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5136 fprintf(stderr
,"Failed to open %s\n", fname
);
5141 /* Now ensure that doing an old list sees both files and directories. */
5142 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, NULL
);
5143 printf("num_seen = %d\n", num_seen
);
5144 /* We should see 100 files + 1000 directories + . and .. */
5145 if (num_seen
!= 2002)
5148 /* Ensure if we have the "must have" bits we only see the
5151 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, NULL
);
5152 printf("num_seen = %d\n", num_seen
);
5153 if (num_seen
!= 1002)
5156 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, NULL
);
5157 printf("num_seen = %d\n", num_seen
);
5158 if (num_seen
!= 1000)
5161 /* Delete everything. */
5162 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5163 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5164 cli_rmdir(cli
, "\\LISTDIR");
5167 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5168 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5169 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5172 if (!torture_close_connection(cli
)) {
5176 printf("finished dirtest1\n");
5181 static bool run_error_map_extract(int dummy
) {
5183 static struct cli_state
*c_dos
;
5184 static struct cli_state
*c_nt
;
5189 uint32 flgs2
, errnum
;
5196 /* NT-Error connection */
5198 if (!(c_nt
= open_nbt_connection())) {
5202 c_nt
->use_spnego
= False
;
5204 status
= cli_negprot(c_nt
);
5206 if (!NT_STATUS_IS_OK(status
)) {
5207 printf("%s rejected the NT-error negprot (%s)\n", host
,
5213 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5215 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5219 /* DOS-Error connection */
5221 if (!(c_dos
= open_nbt_connection())) {
5225 c_dos
->use_spnego
= False
;
5226 c_dos
->force_dos_errors
= True
;
5228 status
= cli_negprot(c_dos
);
5229 if (!NT_STATUS_IS_OK(status
)) {
5230 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5232 cli_shutdown(c_dos
);
5236 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5238 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5242 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5243 fstr_sprintf(user
, "%X", error
);
5245 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5246 password
, strlen(password
),
5247 password
, strlen(password
),
5249 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5252 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5254 /* Case #1: 32-bit NT errors */
5255 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5256 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5258 printf("/** Dos error on NT connection! (%s) */\n",
5260 nt_status
= NT_STATUS(0xc0000000);
5263 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5264 password
, strlen(password
),
5265 password
, strlen(password
),
5267 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5269 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5271 /* Case #1: 32-bit NT errors */
5272 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5273 printf("/** NT error on DOS connection! (%s) */\n",
5275 errnum
= errclass
= 0;
5277 cli_dos_error(c_dos
, &errclass
, &errnum
);
5280 if (NT_STATUS_V(nt_status
) != error
) {
5281 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5282 get_nt_error_c_code(NT_STATUS(error
)),
5283 get_nt_error_c_code(nt_status
));
5286 printf("\t{%s,\t%s,\t%s},\n",
5287 smb_dos_err_class(errclass
),
5288 smb_dos_err_name(errclass
, errnum
),
5289 get_nt_error_c_code(NT_STATUS(error
)));
5294 static bool run_sesssetup_bench(int dummy
)
5296 static struct cli_state
*c
;
5297 const char *fname
= "\\file.dat";
5302 if (!torture_open_connection(&c
, 0)) {
5306 if (!NT_STATUS_IS_OK(cli_ntcreate(
5307 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5308 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5309 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5310 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5314 for (i
=0; i
<torture_numops
; i
++) {
5315 status
= cli_session_setup(
5317 password
, strlen(password
),
5318 password
, strlen(password
),
5320 if (!NT_STATUS_IS_OK(status
)) {
5321 d_printf("(%s) cli_session_setup failed: %s\n",
5322 __location__
, nt_errstr(status
));
5326 d_printf("\r%d ", (int)c
->vuid
);
5328 status
= cli_ulogoff(c
);
5329 if (!NT_STATUS_IS_OK(status
)) {
5330 d_printf("(%s) cli_ulogoff failed: %s\n",
5331 __location__
, nt_errstr(status
));
5340 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5341 uid_t uid
, gid_t gid
, const char *expected
)
5346 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5348 if (strcmp(subst
, expected
) != 0) {
5349 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5350 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5359 static void chain1_open_completion(struct tevent_req
*req
)
5363 status
= cli_open_recv(req
, &fnum
);
5366 d_printf("cli_open_recv returned %s: %d\n",
5368 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5371 static void chain1_write_completion(struct tevent_req
*req
)
5375 status
= cli_write_andx_recv(req
, &written
);
5378 d_printf("cli_write_andx_recv returned %s: %d\n",
5380 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5383 static void chain1_close_completion(struct tevent_req
*req
)
5386 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5388 status
= cli_close_recv(req
);
5393 d_printf("cli_close returned %s\n", nt_errstr(status
));
5396 static bool run_chain1(int dummy
)
5398 struct cli_state
*cli1
;
5399 struct event_context
*evt
= event_context_init(NULL
);
5400 struct tevent_req
*reqs
[3], *smbreqs
[3];
5402 const char *str
= "foobar";
5405 printf("starting chain1 test\n");
5406 if (!torture_open_connection(&cli1
, 0)) {
5410 cli_sockopt(cli1
, sockops
);
5412 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5413 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5414 if (reqs
[0] == NULL
) return false;
5415 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5418 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5419 (uint8_t *)str
, 0, strlen(str
)+1,
5420 smbreqs
, 1, &smbreqs
[1]);
5421 if (reqs
[1] == NULL
) return false;
5422 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5424 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5425 if (reqs
[2] == NULL
) return false;
5426 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5428 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5429 if (!NT_STATUS_IS_OK(status
)) {
5434 event_loop_once(evt
);
5437 torture_close_connection(cli1
);
5441 static void chain2_sesssetup_completion(struct tevent_req
*req
)
5444 status
= cli_session_setup_guest_recv(req
);
5445 d_printf("sesssetup returned %s\n", nt_errstr(status
));
5448 static void chain2_tcon_completion(struct tevent_req
*req
)
5450 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5452 status
= cli_tcon_andx_recv(req
);
5453 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
5457 static bool run_chain2(int dummy
)
5459 struct cli_state
*cli1
;
5460 struct event_context
*evt
= event_context_init(NULL
);
5461 struct tevent_req
*reqs
[2], *smbreqs
[2];
5465 printf("starting chain2 test\n");
5466 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
5467 port_to_use
, Undefined
, 0, NULL
);
5468 if (!NT_STATUS_IS_OK(status
)) {
5472 cli_sockopt(cli1
, sockops
);
5474 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
5476 if (reqs
[0] == NULL
) return false;
5477 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
5479 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
5480 "?????", NULL
, 0, &smbreqs
[1]);
5481 if (reqs
[1] == NULL
) return false;
5482 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
5484 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5485 if (!NT_STATUS_IS_OK(status
)) {
5490 event_loop_once(evt
);
5493 torture_close_connection(cli1
);
5498 struct torture_createdel_state
{
5499 struct tevent_context
*ev
;
5500 struct cli_state
*cli
;
5503 static void torture_createdel_created(struct tevent_req
*subreq
);
5504 static void torture_createdel_closed(struct tevent_req
*subreq
);
5506 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
5507 struct tevent_context
*ev
,
5508 struct cli_state
*cli
,
5511 struct tevent_req
*req
, *subreq
;
5512 struct torture_createdel_state
*state
;
5514 req
= tevent_req_create(mem_ctx
, &state
,
5515 struct torture_createdel_state
);
5522 subreq
= cli_ntcreate_send(
5523 state
, ev
, cli
, name
, 0,
5524 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5525 FILE_ATTRIBUTE_NORMAL
,
5526 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5527 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
5529 if (tevent_req_nomem(subreq
, req
)) {
5530 return tevent_req_post(req
, ev
);
5532 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
5536 static void torture_createdel_created(struct tevent_req
*subreq
)
5538 struct tevent_req
*req
= tevent_req_callback_data(
5539 subreq
, struct tevent_req
);
5540 struct torture_createdel_state
*state
= tevent_req_data(
5541 req
, struct torture_createdel_state
);
5545 status
= cli_ntcreate_recv(subreq
, &fnum
);
5546 TALLOC_FREE(subreq
);
5547 if (!NT_STATUS_IS_OK(status
)) {
5548 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5549 nt_errstr(status
)));
5550 tevent_req_nterror(req
, status
);
5554 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
5555 if (tevent_req_nomem(subreq
, req
)) {
5558 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
5561 static void torture_createdel_closed(struct tevent_req
*subreq
)
5563 struct tevent_req
*req
= tevent_req_callback_data(
5564 subreq
, struct tevent_req
);
5567 status
= cli_close_recv(subreq
);
5568 if (!NT_STATUS_IS_OK(status
)) {
5569 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
5570 tevent_req_nterror(req
, status
);
5573 tevent_req_done(req
);
5576 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
5578 return tevent_req_simple_recv_ntstatus(req
);
5581 struct torture_createdels_state
{
5582 struct tevent_context
*ev
;
5583 struct cli_state
*cli
;
5584 const char *base_name
;
5588 struct tevent_req
**reqs
;
5591 static void torture_createdels_done(struct tevent_req
*subreq
);
5593 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
5594 struct tevent_context
*ev
,
5595 struct cli_state
*cli
,
5596 const char *base_name
,
5600 struct tevent_req
*req
;
5601 struct torture_createdels_state
*state
;
5604 req
= tevent_req_create(mem_ctx
, &state
,
5605 struct torture_createdels_state
);
5611 state
->base_name
= talloc_strdup(state
, base_name
);
5612 if (tevent_req_nomem(state
->base_name
, req
)) {
5613 return tevent_req_post(req
, ev
);
5615 state
->num_files
= MAX(num_parallel
, num_files
);
5617 state
->received
= 0;
5619 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
5620 if (tevent_req_nomem(state
->reqs
, req
)) {
5621 return tevent_req_post(req
, ev
);
5624 for (i
=0; i
<num_parallel
; i
++) {
5627 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5629 if (tevent_req_nomem(name
, req
)) {
5630 return tevent_req_post(req
, ev
);
5632 state
->reqs
[i
] = torture_createdel_send(
5633 state
->reqs
, state
->ev
, state
->cli
, name
);
5634 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5635 return tevent_req_post(req
, ev
);
5637 name
= talloc_move(state
->reqs
[i
], &name
);
5638 tevent_req_set_callback(state
->reqs
[i
],
5639 torture_createdels_done
, req
);
5645 static void torture_createdels_done(struct tevent_req
*subreq
)
5647 struct tevent_req
*req
= tevent_req_callback_data(
5648 subreq
, struct tevent_req
);
5649 struct torture_createdels_state
*state
= tevent_req_data(
5650 req
, struct torture_createdels_state
);
5651 size_t num_parallel
= talloc_array_length(state
->reqs
);
5656 status
= torture_createdel_recv(subreq
);
5657 if (!NT_STATUS_IS_OK(status
)){
5658 DEBUG(10, ("torture_createdel_recv returned %s\n",
5659 nt_errstr(status
)));
5660 TALLOC_FREE(subreq
);
5661 tevent_req_nterror(req
, status
);
5665 for (i
=0; i
<num_parallel
; i
++) {
5666 if (subreq
== state
->reqs
[i
]) {
5670 if (i
== num_parallel
) {
5671 DEBUG(10, ("received something we did not send\n"));
5672 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
5675 TALLOC_FREE(state
->reqs
[i
]);
5677 if (state
->sent
>= state
->num_files
) {
5678 tevent_req_done(req
);
5682 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5684 if (tevent_req_nomem(name
, req
)) {
5687 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
5689 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5692 name
= talloc_move(state
->reqs
[i
], &name
);
5693 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
5697 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
5699 return tevent_req_simple_recv_ntstatus(req
);
5702 struct swallow_notify_state
{
5703 struct tevent_context
*ev
;
5704 struct cli_state
*cli
;
5706 uint32_t completion_filter
;
5708 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
5712 static void swallow_notify_done(struct tevent_req
*subreq
);
5714 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
5715 struct tevent_context
*ev
,
5716 struct cli_state
*cli
,
5718 uint32_t completion_filter
,
5720 bool (*fn
)(uint32_t action
,
5725 struct tevent_req
*req
, *subreq
;
5726 struct swallow_notify_state
*state
;
5728 req
= tevent_req_create(mem_ctx
, &state
,
5729 struct swallow_notify_state
);
5736 state
->completion_filter
= completion_filter
;
5737 state
->recursive
= recursive
;
5741 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5742 0xffff, state
->completion_filter
,
5744 if (tevent_req_nomem(subreq
, req
)) {
5745 return tevent_req_post(req
, ev
);
5747 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5751 static void swallow_notify_done(struct tevent_req
*subreq
)
5753 struct tevent_req
*req
= tevent_req_callback_data(
5754 subreq
, struct tevent_req
);
5755 struct swallow_notify_state
*state
= tevent_req_data(
5756 req
, struct swallow_notify_state
);
5758 uint32_t i
, num_changes
;
5759 struct notify_change
*changes
;
5761 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
5762 TALLOC_FREE(subreq
);
5763 if (!NT_STATUS_IS_OK(status
)) {
5764 DEBUG(10, ("cli_notify_recv returned %s\n",
5765 nt_errstr(status
)));
5766 tevent_req_nterror(req
, status
);
5770 for (i
=0; i
<num_changes
; i
++) {
5771 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
5773 TALLOC_FREE(changes
);
5775 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5776 0xffff, state
->completion_filter
,
5778 if (tevent_req_nomem(subreq
, req
)) {
5781 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5784 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
5786 if (DEBUGLEVEL
> 5) {
5787 d_printf("%d %s\n", (int)action
, name
);
5792 static void notify_bench_done(struct tevent_req
*req
)
5794 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
5798 static bool run_notify_bench(int dummy
)
5800 const char *dname
= "\\notify-bench";
5801 struct tevent_context
*ev
;
5804 struct tevent_req
*req1
;
5805 struct tevent_req
*req2
= NULL
;
5806 int i
, num_unc_names
;
5807 int num_finished
= 0;
5809 printf("starting notify-bench test\n");
5811 if (use_multishare_conn
) {
5813 unc_list
= file_lines_load(multishare_conn_fname
,
5814 &num_unc_names
, 0, NULL
);
5815 if (!unc_list
|| num_unc_names
<= 0) {
5816 d_printf("Failed to load unc names list from '%s'\n",
5817 multishare_conn_fname
);
5820 TALLOC_FREE(unc_list
);
5825 ev
= tevent_context_init(talloc_tos());
5827 d_printf("tevent_context_init failed\n");
5831 for (i
=0; i
<num_unc_names
; i
++) {
5832 struct cli_state
*cli
;
5835 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5837 if (base_fname
== NULL
) {
5841 if (!torture_open_connection(&cli
, i
)) {
5845 status
= cli_ntcreate(cli
, dname
, 0,
5846 MAXIMUM_ALLOWED_ACCESS
,
5847 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5849 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
5852 if (!NT_STATUS_IS_OK(status
)) {
5853 d_printf("Could not create %s: %s\n", dname
,
5858 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
5859 FILE_NOTIFY_CHANGE_FILE_NAME
|
5860 FILE_NOTIFY_CHANGE_DIR_NAME
|
5861 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
5862 FILE_NOTIFY_CHANGE_LAST_WRITE
,
5863 false, print_notifies
, NULL
);
5865 d_printf("Could not create notify request\n");
5869 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
5870 base_fname
, 10, torture_numops
);
5872 d_printf("Could not create createdels request\n");
5875 TALLOC_FREE(base_fname
);
5877 tevent_req_set_callback(req2
, notify_bench_done
,
5881 while (num_finished
< num_unc_names
) {
5883 ret
= tevent_loop_once(ev
);
5885 d_printf("tevent_loop_once failed\n");
5890 if (!tevent_req_poll(req2
, ev
)) {
5891 d_printf("tevent_req_poll failed\n");
5894 status
= torture_createdels_recv(req2
);
5895 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
5900 static bool run_mangle1(int dummy
)
5902 struct cli_state
*cli
;
5903 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
5907 time_t change_time
, access_time
, write_time
;
5911 printf("starting mangle1 test\n");
5912 if (!torture_open_connection(&cli
, 0)) {
5916 cli_sockopt(cli
, sockops
);
5918 if (!NT_STATUS_IS_OK(cli_ntcreate(
5919 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5920 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5921 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
5924 cli_close(cli
, fnum
);
5926 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
5927 if (!NT_STATUS_IS_OK(status
)) {
5928 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5932 d_printf("alt_name: %s\n", alt_name
);
5934 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
5935 d_printf("cli_open(%s) failed: %s\n", alt_name
,
5939 cli_close(cli
, fnum
);
5941 if (!cli_qpathinfo(cli
, alt_name
, &change_time
, &access_time
,
5942 &write_time
, &size
, &mode
)) {
5943 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name
,
5951 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
5953 size_t *to_pull
= (size_t *)priv
;
5954 size_t thistime
= *to_pull
;
5956 thistime
= MIN(thistime
, n
);
5957 if (thistime
== 0) {
5961 memset(buf
, 0, thistime
);
5962 *to_pull
-= thistime
;
5966 static bool run_windows_write(int dummy
)
5968 struct cli_state
*cli1
;
5972 const char *fname
= "\\writetest.txt";
5973 struct timeval start_time
;
5977 printf("starting windows_write test\n");
5978 if (!torture_open_connection(&cli1
, 0)) {
5982 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
5983 printf("open failed (%s)\n", cli_errstr(cli1
));
5987 cli_sockopt(cli1
, sockops
);
5989 start_time
= timeval_current();
5991 for (i
=0; i
<torture_numops
; i
++) {
5993 off_t start
= i
* torture_blocksize
;
5995 size_t to_pull
= torture_blocksize
- 1;
5997 if (cli_write(cli1
, fnum
, 0, &c
,
5998 start
+ torture_blocksize
- 1, 1) != 1) {
5999 printf("cli_write failed: %s\n", cli_errstr(cli1
));
6003 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6004 null_source
, &to_pull
);
6005 if (!NT_STATUS_IS_OK(status
)) {
6006 printf("cli_push returned: %s\n", nt_errstr(status
));
6011 seconds
= timeval_elapsed(&start_time
);
6012 kbytes
= (double)torture_blocksize
* torture_numops
;
6015 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6016 (double)seconds
, (int)(kbytes
/seconds
));
6020 cli_close(cli1
, fnum
);
6021 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6022 torture_close_connection(cli1
);
6026 static bool run_cli_echo(int dummy
)
6028 struct cli_state
*cli
;
6031 printf("starting cli_echo test\n");
6032 if (!torture_open_connection(&cli
, 0)) {
6035 cli_sockopt(cli
, sockops
);
6037 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6039 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6041 torture_close_connection(cli
);
6042 return NT_STATUS_IS_OK(status
);
6045 static bool run_uid_regression_test(int dummy
)
6047 static struct cli_state
*cli
;
6050 bool correct
= True
;
6053 printf("starting uid regression test\n");
6055 if (!torture_open_connection(&cli
, 0)) {
6059 cli_sockopt(cli
, sockops
);
6061 /* Ok - now save then logoff our current user. */
6062 old_vuid
= cli
->vuid
;
6064 status
= cli_ulogoff(cli
);
6065 if (!NT_STATUS_IS_OK(status
)) {
6066 d_printf("(%s) cli_ulogoff failed: %s\n",
6067 __location__
, nt_errstr(status
));
6072 cli
->vuid
= old_vuid
;
6074 /* Try an operation. */
6075 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\uid_reg_test"))) {
6076 /* We expect bad uid. */
6077 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6078 NT_STATUS_NO_SUCH_USER
)) {
6083 old_cnum
= cli
->cnum
;
6085 /* Now try a SMBtdis with the invald vuid set to zero. */
6088 /* This should succeed. */
6089 status
= cli_tdis(cli
);
6091 if (NT_STATUS_IS_OK(status
)) {
6092 printf("First tdis with invalid vuid should succeed.\n");
6094 printf("First tdis failed (%s)\n", nt_errstr(status
));
6097 cli
->vuid
= old_vuid
;
6098 cli
->cnum
= old_cnum
;
6100 /* This should fail. */
6101 status
= cli_tdis(cli
);
6102 if (NT_STATUS_IS_OK(status
)) {
6103 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6105 /* Should be bad tid. */
6106 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6107 NT_STATUS_NETWORK_NAME_DELETED
)) {
6112 cli_rmdir(cli
, "\\uid_reg_test");
6121 static const char *illegal_chars
= "*\\/?<>|\":";
6122 static char force_shortname_chars
[] = " +,.[];=\177";
6124 static void shortname_del_fn(const char *mnt
, file_info
*finfo
, const char *mask
, void *state
)
6126 struct cli_state
*pcli
= (struct cli_state
*)state
;
6128 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6130 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6133 if (finfo
->mode
& aDIR
) {
6134 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
6135 printf("del_fn: failed to rmdir %s\n,", fname
);
6137 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
6138 printf("del_fn: failed to unlink %s\n,", fname
);
6147 static void shortname_list_fn(const char *mnt
, file_info
*finfo
, const char *name
, void *state
)
6149 struct sn_state
*s
= (struct sn_state
*)state
;
6153 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6154 i
, finfo
->name
, finfo
->short_name
);
6157 if (strchr(force_shortname_chars
, i
)) {
6158 if (!finfo
->short_name
[0]) {
6159 /* Shortname not created when it should be. */
6160 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6161 __location__
, finfo
->name
, i
);
6164 } else if (finfo
->short_name
[0]){
6165 /* Shortname created when it should not be. */
6166 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6167 __location__
, finfo
->short_name
, finfo
->name
);
6172 static bool run_shortname_test(int dummy
)
6174 static struct cli_state
*cli
;
6175 bool correct
= True
;
6180 printf("starting shortname test\n");
6182 if (!torture_open_connection(&cli
, 0)) {
6186 cli_sockopt(cli
, sockops
);
6188 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6189 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6190 cli_rmdir(cli
, "\\shortname");
6192 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6193 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6194 __location__
, cli_errstr(cli
));
6199 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6200 strlcat(fname
, "test .txt", sizeof(fname
));
6204 for (i
= 32; i
< 128; i
++) {
6206 uint16_t fnum
= (uint16_t)-1;
6210 if (strchr(illegal_chars
, i
)) {
6215 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6216 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6217 if (!NT_STATUS_IS_OK(status
)) {
6218 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6219 __location__
, fname
, cli_errstr(cli
));
6223 cli_close(cli
, fnum
);
6224 if (cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
, &s
) != 1) {
6225 d_printf("(%s) failed to list %s: %s\n",
6226 __location__
, fname
, cli_errstr(cli
));
6230 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6231 d_printf("(%s) failed to delete %s: %s\n",
6232 __location__
, fname
, cli_errstr(cli
));
6245 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6246 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6247 cli_rmdir(cli
, "\\shortname");
6248 torture_close_connection(cli
);
6252 static void pagedsearch_cb(struct tevent_req
*req
)
6255 struct tldap_message
*msg
;
6258 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6259 if (rc
!= TLDAP_SUCCESS
) {
6260 d_printf("tldap_search_paged_recv failed: %s\n",
6261 tldap_err2string(rc
));
6264 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6268 if (!tldap_entry_dn(msg
, &dn
)) {
6269 d_printf("tldap_entry_dn failed\n");
6272 d_printf("%s\n", dn
);
6276 static bool run_tldap(int dummy
)
6278 struct tldap_context
*ld
;
6281 struct sockaddr_storage addr
;
6282 struct tevent_context
*ev
;
6283 struct tevent_req
*req
;
6286 if (!resolve_name(host
, &addr
, 0, false)) {
6287 d_printf("could not find host %s\n", host
);
6290 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6291 if (!NT_STATUS_IS_OK(status
)) {
6292 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6296 ld
= tldap_context_create(talloc_tos(), fd
);
6299 d_printf("tldap_context_create failed\n");
6303 rc
= tldap_fetch_rootdse(ld
);
6304 if (rc
!= TLDAP_SUCCESS
) {
6305 d_printf("tldap_fetch_rootdse failed: %s\n",
6306 tldap_errstr(talloc_tos(), ld
, rc
));
6310 basedn
= tldap_talloc_single_attribute(
6311 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6312 if (basedn
== NULL
) {
6313 d_printf("no defaultNamingContext\n");
6316 d_printf("defaultNamingContext: %s\n", basedn
);
6318 ev
= tevent_context_init(talloc_tos());
6320 d_printf("tevent_context_init failed\n");
6324 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6325 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6327 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6329 d_printf("tldap_search_paged_send failed\n");
6332 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6334 tevent_req_poll(req
, ev
);
6342 static bool run_streamerror(int dummy
)
6344 struct cli_state
*cli
;
6345 const char *dname
= "\\testdir";
6346 const char *streamname
=
6347 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6349 time_t change_time
, access_time
, write_time
;
6351 uint16_t mode
, fnum
;
6354 if (!torture_open_connection(&cli
, 0)) {
6358 cli_rmdir(cli
, dname
);
6360 status
= cli_mkdir(cli
, dname
);
6361 if (!NT_STATUS_IS_OK(status
)) {
6362 printf("mkdir failed: %s\n", nt_errstr(status
));
6366 cli_qpathinfo(cli
, streamname
, &change_time
, &access_time
, &write_time
,
6368 status
= cli_nt_error(cli
);
6370 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6371 printf("pathinfo returned %s, expected "
6372 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6377 status
= cli_ntcreate(cli
, streamname
, 0x16,
6378 FILE_READ_DATA
|FILE_READ_EA
|
6379 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
6380 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6381 FILE_OPEN
, 0, 0, &fnum
);
6383 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6384 printf("ntcreate returned %s, expected "
6385 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6391 cli_rmdir(cli
, dname
);
6395 static bool run_local_substitute(int dummy
)
6399 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
6400 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6401 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6402 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6403 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
6404 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
6405 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6406 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6408 /* Different captialization rules in sub_basic... */
6410 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6416 static bool run_local_base64(int dummy
)
6421 for (i
=1; i
<2000; i
++) {
6422 DATA_BLOB blob1
, blob2
;
6425 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
6427 generate_random_buffer(blob1
.data
, blob1
.length
);
6429 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
6431 d_fprintf(stderr
, "base64_encode_data_blob failed "
6432 "for %d bytes\n", i
);
6435 blob2
= base64_decode_data_blob(b64
);
6438 if (data_blob_cmp(&blob1
, &blob2
)) {
6439 d_fprintf(stderr
, "data_blob_cmp failed for %d "
6443 TALLOC_FREE(blob1
.data
);
6444 data_blob_free(&blob2
);
6449 static bool run_local_gencache(int dummy
)
6455 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
6456 d_printf("%s: gencache_set() failed\n", __location__
);
6460 if (!gencache_get("foo", NULL
, NULL
)) {
6461 d_printf("%s: gencache_get() failed\n", __location__
);
6465 if (!gencache_get("foo", &val
, &tm
)) {
6466 d_printf("%s: gencache_get() failed\n", __location__
);
6470 if (strcmp(val
, "bar") != 0) {
6471 d_printf("%s: gencache_get() returned %s, expected %s\n",
6472 __location__
, val
, "bar");
6479 if (!gencache_del("foo")) {
6480 d_printf("%s: gencache_del() failed\n", __location__
);
6483 if (gencache_del("foo")) {
6484 d_printf("%s: second gencache_del() succeeded\n",
6489 if (gencache_get("foo", &val
, &tm
)) {
6490 d_printf("%s: gencache_get() on deleted entry "
6491 "succeeded\n", __location__
);
6495 blob
= data_blob_string_const_null("bar");
6496 tm
= time(NULL
) + 60;
6498 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
6499 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
6503 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6504 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
6508 if (strcmp((const char *)blob
.data
, "bar") != 0) {
6509 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6510 __location__
, (const char *)blob
.data
, "bar");
6511 data_blob_free(&blob
);
6515 data_blob_free(&blob
);
6517 if (!gencache_del("foo")) {
6518 d_printf("%s: gencache_del() failed\n", __location__
);
6521 if (gencache_del("foo")) {
6522 d_printf("%s: second gencache_del() succeeded\n",
6527 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6528 d_printf("%s: gencache_get_data_blob() on deleted entry "
6529 "succeeded\n", __location__
);
6536 static bool rbt_testval(struct db_context
*db
, const char *key
,
6539 struct db_record
*rec
;
6540 TDB_DATA data
= string_tdb_data(value
);
6544 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6546 d_fprintf(stderr
, "fetch_locked failed\n");
6549 status
= rec
->store(rec
, data
, 0);
6550 if (!NT_STATUS_IS_OK(status
)) {
6551 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
6556 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6558 d_fprintf(stderr
, "second fetch_locked failed\n");
6561 if ((rec
->value
.dsize
!= data
.dsize
)
6562 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
6563 d_fprintf(stderr
, "Got wrong data back\n");
6573 static bool run_local_rbtree(int dummy
)
6575 struct db_context
*db
;
6579 db
= db_open_rbt(NULL
);
6582 d_fprintf(stderr
, "db_open_rbt failed\n");
6586 for (i
=0; i
<1000; i
++) {
6589 if (asprintf(&key
, "key%ld", random()) == -1) {
6592 if (asprintf(&value
, "value%ld", random()) == -1) {
6597 if (!rbt_testval(db
, key
, value
)) {
6604 if (asprintf(&value
, "value%ld", random()) == -1) {
6609 if (!rbt_testval(db
, key
, value
)) {
6626 struct talloc_dict_test
{
6630 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
6632 int *count
= (int *)priv
;
6637 static bool run_local_talloc_dict(int dummy
)
6639 struct talloc_dict
*dict
;
6640 struct talloc_dict_test
*t
;
6643 dict
= talloc_dict_init(talloc_tos());
6648 t
= talloc(talloc_tos(), struct talloc_dict_test
);
6655 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
6660 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
6673 /* Split a path name into filename and stream name components. Canonicalise
6674 * such that an implicit $DATA token is always explicit.
6676 * The "specification" of this function can be found in the
6677 * run_local_stream_name() function in torture.c, I've tried those
6678 * combinations against a W2k3 server.
6681 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
6682 char **pbase
, char **pstream
)
6685 char *stream
= NULL
;
6686 char *sname
; /* stream name */
6687 const char *stype
; /* stream type */
6689 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
6691 sname
= strchr_m(fname
, ':');
6693 if (lp_posix_pathnames() || (sname
== NULL
)) {
6694 if (pbase
!= NULL
) {
6695 base
= talloc_strdup(mem_ctx
, fname
);
6696 NT_STATUS_HAVE_NO_MEMORY(base
);
6701 if (pbase
!= NULL
) {
6702 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
6703 NT_STATUS_HAVE_NO_MEMORY(base
);
6708 stype
= strchr_m(sname
, ':');
6710 if (stype
== NULL
) {
6711 sname
= talloc_strdup(mem_ctx
, sname
);
6715 if (StrCaseCmp(stype
, ":$DATA") != 0) {
6717 * If there is an explicit stream type, so far we only
6718 * allow $DATA. Is there anything else allowed? -- vl
6720 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
6722 return NT_STATUS_OBJECT_NAME_INVALID
;
6724 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
6728 if (sname
== NULL
) {
6730 return NT_STATUS_NO_MEMORY
;
6733 if (sname
[0] == '\0') {
6735 * no stream name, so no stream
6740 if (pstream
!= NULL
) {
6741 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
6742 if (stream
== NULL
) {
6745 return NT_STATUS_NO_MEMORY
;
6748 * upper-case the type field
6750 strupper_m(strchr_m(stream
, ':')+1);
6754 if (pbase
!= NULL
) {
6757 if (pstream
!= NULL
) {
6760 return NT_STATUS_OK
;
6763 static bool test_stream_name(const char *fname
, const char *expected_base
,
6764 const char *expected_stream
,
6765 NTSTATUS expected_status
)
6769 char *stream
= NULL
;
6771 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
6772 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
6776 if (!NT_STATUS_IS_OK(status
)) {
6780 if (base
== NULL
) goto error
;
6782 if (strcmp(expected_base
, base
) != 0) goto error
;
6784 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
6785 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
6787 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
6791 TALLOC_FREE(stream
);
6795 d_fprintf(stderr
, "test_stream(%s, %s, %s, %s)\n",
6796 fname
, expected_base
? expected_base
: "<NULL>",
6797 expected_stream
? expected_stream
: "<NULL>",
6798 nt_errstr(expected_status
));
6799 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
6800 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
6803 TALLOC_FREE(stream
);
6807 static bool run_local_stream_name(int dummy
)
6811 ret
&= test_stream_name(
6812 "bla", "bla", NULL
, NT_STATUS_OK
);
6813 ret
&= test_stream_name(
6814 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
6815 ret
&= test_stream_name(
6816 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6817 ret
&= test_stream_name(
6818 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6819 ret
&= test_stream_name(
6820 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6821 ret
&= test_stream_name(
6822 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
6823 ret
&= test_stream_name(
6824 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
6825 ret
&= test_stream_name(
6826 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
6831 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
6833 if (a
.length
!= b
.length
) {
6834 printf("a.length=%d != b.length=%d\n",
6835 (int)a
.length
, (int)b
.length
);
6838 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
6839 printf("a.data and b.data differ\n");
6845 static bool run_local_memcache(int dummy
)
6847 struct memcache
*cache
;
6849 DATA_BLOB d1
, d2
, d3
;
6850 DATA_BLOB v1
, v2
, v3
;
6852 TALLOC_CTX
*mem_ctx
;
6854 size_t size1
, size2
;
6857 cache
= memcache_init(NULL
, 100);
6859 if (cache
== NULL
) {
6860 printf("memcache_init failed\n");
6864 d1
= data_blob_const("d1", 2);
6865 d2
= data_blob_const("d2", 2);
6866 d3
= data_blob_const("d3", 2);
6868 k1
= data_blob_const("d1", 2);
6869 k2
= data_blob_const("d2", 2);
6871 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
6872 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
6874 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
6875 printf("could not find k1\n");
6878 if (!data_blob_equal(d1
, v1
)) {
6882 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
6883 printf("could not find k2\n");
6886 if (!data_blob_equal(d2
, v2
)) {
6890 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
6892 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
6893 printf("could not find replaced k1\n");
6896 if (!data_blob_equal(d3
, v3
)) {
6900 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
6902 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
6903 printf("Did find k2, should have been purged\n");
6909 cache
= memcache_init(NULL
, 0);
6911 mem_ctx
= talloc_init("foo");
6913 str1
= talloc_strdup(mem_ctx
, "string1");
6914 str2
= talloc_strdup(mem_ctx
, "string2");
6916 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
6917 data_blob_string_const("torture"), &str1
);
6918 size1
= talloc_total_size(cache
);
6920 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
6921 data_blob_string_const("torture"), &str2
);
6922 size2
= talloc_total_size(cache
);
6924 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
6926 if (size2
> size1
) {
6927 printf("memcache leaks memory!\n");
6937 static void wbclient_done(struct tevent_req
*req
)
6940 struct winbindd_response
*wb_resp
;
6941 int *i
= (int *)tevent_req_callback_data_void(req
);
6943 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
6946 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
6949 static bool run_local_wbclient(int dummy
)
6951 struct event_context
*ev
;
6952 struct wb_context
**wb_ctx
;
6953 struct winbindd_request wb_req
;
6954 bool result
= false;
6957 BlockSignals(True
, SIGPIPE
);
6959 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
6964 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
6965 if (wb_ctx
== NULL
) {
6969 ZERO_STRUCT(wb_req
);
6970 wb_req
.cmd
= WINBINDD_PING
;
6972 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
6974 for (i
=0; i
<nprocs
; i
++) {
6975 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
6976 if (wb_ctx
[i
] == NULL
) {
6979 for (j
=0; j
<torture_numops
; j
++) {
6980 struct tevent_req
*req
;
6981 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
6982 (j
% 2) == 0, &wb_req
);
6986 tevent_req_set_callback(req
, wbclient_done
, &i
);
6992 while (i
< nprocs
* torture_numops
) {
6993 event_loop_once(ev
);
7002 static void getaddrinfo_finished(struct tevent_req
*req
)
7004 char *name
= (char *)tevent_req_callback_data_void(req
);
7005 struct addrinfo
*ainfo
;
7008 res
= getaddrinfo_recv(req
, &ainfo
);
7010 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7013 d_printf("gai(%s) succeeded\n", name
);
7014 freeaddrinfo(ainfo
);
7017 static bool run_getaddrinfo_send(int dummy
)
7019 TALLOC_CTX
*frame
= talloc_stackframe();
7020 struct fncall_context
*ctx
;
7021 struct tevent_context
*ev
;
7022 bool result
= false;
7023 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7024 "www.slashdot.org", "heise.de" };
7025 struct tevent_req
*reqs
[4];
7028 ev
= event_context_init(frame
);
7033 ctx
= fncall_context_init(frame
, 4);
7035 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7036 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7038 if (reqs
[i
] == NULL
) {
7041 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7045 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7046 tevent_loop_once(ev
);
7056 static double create_procs(bool (*fn
)(int), bool *result
)
7059 volatile pid_t
*child_status
;
7060 volatile bool *child_status_out
;
7063 struct timeval start
;
7067 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
7068 if (!child_status
) {
7069 printf("Failed to setup shared memory\n");
7073 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
7074 if (!child_status_out
) {
7075 printf("Failed to setup result status shared memory\n");
7079 for (i
= 0; i
< nprocs
; i
++) {
7080 child_status
[i
] = 0;
7081 child_status_out
[i
] = True
;
7084 start
= timeval_current();
7086 for (i
=0;i
<nprocs
;i
++) {
7089 pid_t mypid
= getpid();
7090 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
7092 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
7095 if (torture_open_connection(¤t_cli
, i
)) break;
7097 printf("pid %d failed to start\n", (int)getpid());
7103 child_status
[i
] = getpid();
7105 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
7107 child_status_out
[i
] = fn(i
);
7114 for (i
=0;i
<nprocs
;i
++) {
7115 if (child_status
[i
]) synccount
++;
7117 if (synccount
== nprocs
) break;
7119 } while (timeval_elapsed(&start
) < 30);
7121 if (synccount
!= nprocs
) {
7122 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
7124 return timeval_elapsed(&start
);
7127 /* start the client load */
7128 start
= timeval_current();
7130 for (i
=0;i
<nprocs
;i
++) {
7131 child_status
[i
] = 0;
7134 printf("%d clients started\n", nprocs
);
7136 for (i
=0;i
<nprocs
;i
++) {
7137 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
7142 for (i
=0;i
<nprocs
;i
++) {
7143 if (!child_status_out
[i
]) {
7147 return timeval_elapsed(&start
);
7150 #define FLAG_MULTIPROC 1
7157 {"FDPASS", run_fdpasstest
, 0},
7158 {"LOCK1", run_locktest1
, 0},
7159 {"LOCK2", run_locktest2
, 0},
7160 {"LOCK3", run_locktest3
, 0},
7161 {"LOCK4", run_locktest4
, 0},
7162 {"LOCK5", run_locktest5
, 0},
7163 {"LOCK6", run_locktest6
, 0},
7164 {"LOCK7", run_locktest7
, 0},
7165 {"LOCK8", run_locktest8
, 0},
7166 {"LOCK9", run_locktest9
, 0},
7167 {"UNLINK", run_unlinktest
, 0},
7168 {"BROWSE", run_browsetest
, 0},
7169 {"ATTR", run_attrtest
, 0},
7170 {"TRANS2", run_trans2test
, 0},
7171 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
7172 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
7173 {"RANDOMIPC", run_randomipc
, 0},
7174 {"NEGNOWAIT", run_negprot_nowait
, 0},
7175 {"NBENCH", run_nbench
, 0},
7176 {"OPLOCK1", run_oplock1
, 0},
7177 {"OPLOCK2", run_oplock2
, 0},
7178 {"OPLOCK3", run_oplock3
, 0},
7179 {"DIR", run_dirtest
, 0},
7180 {"DIR1", run_dirtest1
, 0},
7181 {"DENY1", torture_denytest1
, 0},
7182 {"DENY2", torture_denytest2
, 0},
7183 {"TCON", run_tcon_test
, 0},
7184 {"TCONDEV", run_tcon_devtype_test
, 0},
7185 {"RW1", run_readwritetest
, 0},
7186 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
7187 {"RW3", run_readwritelarge
, 0},
7188 {"OPEN", run_opentest
, 0},
7189 {"POSIX", run_simple_posix_open_test
, 0},
7190 {"POSIX-APPEND", run_posix_append
, 0},
7191 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
7192 { "SHORTNAME-TEST", run_shortname_test
, 0},
7194 {"OPENATTR", run_openattrtest
, 0},
7196 {"XCOPY", run_xcopy
, 0},
7197 {"RENAME", run_rename
, 0},
7198 {"DELETE", run_deletetest
, 0},
7199 {"PROPERTIES", run_properties
, 0},
7200 {"MANGLE", torture_mangle
, 0},
7201 {"MANGLE1", run_mangle1
, 0},
7202 {"W2K", run_w2ktest
, 0},
7203 {"TRANS2SCAN", torture_trans2_scan
, 0},
7204 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
7205 {"UTABLE", torture_utable
, 0},
7206 {"CASETABLE", torture_casetable
, 0},
7207 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
7208 {"PIPE_NUMBER", run_pipe_number
, 0},
7209 {"TCON2", run_tcon2_test
, 0},
7210 {"IOCTL", torture_ioctl_test
, 0},
7211 {"CHKPATH", torture_chkpath_test
, 0},
7212 {"FDSESS", run_fdsesstest
, 0},
7213 { "EATEST", run_eatest
, 0},
7214 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
7215 { "CHAIN1", run_chain1
, 0},
7216 { "CHAIN2", run_chain2
, 0},
7217 { "WINDOWS-WRITE", run_windows_write
, 0},
7218 { "CLI_ECHO", run_cli_echo
, 0},
7219 { "GETADDRINFO", run_getaddrinfo_send
, 0},
7220 { "TLDAP", run_tldap
},
7221 { "STREAMERROR", run_streamerror
},
7222 { "NOTIFY-BENCH", run_notify_bench
},
7223 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
7224 { "LOCAL-GENCACHE", run_local_gencache
, 0},
7225 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
7226 { "LOCAL-BASE64", run_local_base64
, 0},
7227 { "LOCAL-RBTREE", run_local_rbtree
, 0},
7228 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
7229 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
7230 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
7235 /****************************************************************************
7236 run a specified test or "ALL"
7237 ****************************************************************************/
7238 static bool run_test(const char *name
)
7245 if (strequal(name
,"ALL")) {
7246 for (i
=0;torture_ops
[i
].name
;i
++) {
7247 run_test(torture_ops
[i
].name
);
7252 for (i
=0;torture_ops
[i
].name
;i
++) {
7253 fstr_sprintf(randomfname
, "\\XX%x",
7254 (unsigned)random());
7256 if (strequal(name
, torture_ops
[i
].name
)) {
7258 printf("Running %s\n", name
);
7259 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
7260 t
= create_procs(torture_ops
[i
].fn
, &result
);
7263 printf("TEST %s FAILED!\n", name
);
7266 struct timeval start
;
7267 start
= timeval_current();
7268 if (!torture_ops
[i
].fn(0)) {
7270 printf("TEST %s FAILED!\n", name
);
7272 t
= timeval_elapsed(&start
);
7274 printf("%s took %g secs\n\n", name
, t
);
7279 printf("Did not find a test named %s\n", name
);
7287 static void usage(void)
7291 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7292 printf("Please use samba4 torture.\n\n");
7294 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7296 printf("\t-d debuglevel\n");
7297 printf("\t-U user%%pass\n");
7298 printf("\t-k use kerberos\n");
7299 printf("\t-N numprocs\n");
7300 printf("\t-n my_netbios_name\n");
7301 printf("\t-W workgroup\n");
7302 printf("\t-o num_operations\n");
7303 printf("\t-O socket_options\n");
7304 printf("\t-m maximum protocol\n");
7305 printf("\t-L use oplocks\n");
7306 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7307 printf("\t-A showall\n");
7308 printf("\t-p port\n");
7309 printf("\t-s seed\n");
7310 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7313 printf("tests are:");
7314 for (i
=0;torture_ops
[i
].name
;i
++) {
7315 printf(" %s", torture_ops
[i
].name
);
7319 printf("default test is ALL\n");
7324 /****************************************************************************
7326 ****************************************************************************/
7327 int main(int argc
,char *argv
[])
7333 bool correct
= True
;
7334 TALLOC_CTX
*frame
= talloc_stackframe();
7335 int seed
= time(NULL
);
7339 #ifdef HAVE_SETBUFFER
7340 setbuffer(stdout
, NULL
, 0);
7345 if (is_default_dyn_CONFIGFILE()) {
7346 if(getenv("SMB_CONF_PATH")) {
7347 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7350 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
7357 for(p
= argv
[1]; *p
; p
++)
7361 if (strncmp(argv
[1], "//", 2)) {
7365 fstrcpy(host
, &argv
[1][2]);
7366 p
= strchr_m(&host
[2],'/');
7371 fstrcpy(share
, p
+1);
7373 fstrcpy(myname
, get_myname(talloc_tos()));
7375 fprintf(stderr
, "Failed to get my hostname.\n");
7379 if (*username
== 0 && getenv("LOGNAME")) {
7380 fstrcpy(username
,getenv("LOGNAME"));
7386 fstrcpy(workgroup
, lp_workgroup());
7388 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
7391 port_to_use
= atoi(optarg
);
7394 seed
= atoi(optarg
);
7397 fstrcpy(workgroup
,optarg
);
7400 max_protocol
= interpret_protocol(optarg
, max_protocol
);
7403 nprocs
= atoi(optarg
);
7406 torture_numops
= atoi(optarg
);
7409 DEBUGLEVEL
= atoi(optarg
);
7418 local_path
= optarg
;
7421 torture_showall
= True
;
7424 fstrcpy(myname
, optarg
);
7427 client_txt
= optarg
;
7434 use_kerberos
= True
;
7436 d_printf("No kerberos support compiled in\n");
7442 fstrcpy(username
,optarg
);
7443 p
= strchr_m(username
,'%');
7446 fstrcpy(password
, p
+1);
7451 fstrcpy(multishare_conn_fname
, optarg
);
7452 use_multishare_conn
= True
;
7455 torture_blocksize
= atoi(optarg
);
7458 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
7463 d_printf("using seed %d\n", seed
);
7467 if(use_kerberos
&& !gotuser
) gotpass
= True
;
7470 p
= getpass("Password:");
7472 fstrcpy(password
, p
);
7477 printf("host=%s share=%s user=%s myname=%s\n",
7478 host
, share
, username
, myname
);
7480 if (argc
== optind
) {
7481 correct
= run_test("ALL");
7483 for (i
=optind
;i
<argc
;i
++) {
7484 if (!run_test(argv
[i
])) {