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"
24 #include "libcli/security/dom_sid.h"
26 #include "tldap_util.h"
31 static fstring host
, workgroup
, share
, password
, username
, myname
;
32 static int max_protocol
= PROTOCOL_NT1
;
33 static const char *sockops
="TCP_NODELAY";
35 static int port_to_use
=0;
36 int torture_numops
=100;
37 int torture_blocksize
=1024*1024;
38 static int procnum
; /* records process count number when forking */
39 static struct cli_state
*current_cli
;
40 static fstring randomfname
;
41 static bool use_oplocks
;
42 static bool use_level_II_oplocks
;
43 static const char *client_txt
= "client_oplocks.txt";
44 static bool use_kerberos
;
45 static fstring multishare_conn_fname
;
46 static bool use_multishare_conn
= False
;
47 static bool do_encrypt
;
48 static const char *local_path
= NULL
;
50 bool torture_showall
= False
;
52 static double create_procs(bool (*fn
)(int), bool *result
);
55 /* return a pointer to a anonymous shared memory segment of size "size"
56 which will persist across fork() but will disappear when all processes
59 The memory is not zeroed
61 This function uses system5 shared memory. It takes advantage of a property
62 that the memory is not destroyed if it is attached when the id is removed
64 void *shm_setup(int size
)
70 shmid
= shm_open("private", O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
72 printf("can't get shared memory\n");
75 shm_unlink("private");
76 if (ftruncate(shmid
, size
) == -1) {
77 printf("can't set shared memory size\n");
80 ret
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, shmid
, 0);
81 if (ret
== MAP_FAILED
) {
82 printf("can't map shared memory\n");
86 shmid
= shmget(IPC_PRIVATE
, size
, S_IRUSR
| S_IWUSR
);
88 printf("can't get shared memory\n");
91 ret
= (void *)shmat(shmid
, 0, 0);
92 if (!ret
|| ret
== (void *)-1) {
93 printf("can't attach to shared memory\n");
96 /* the following releases the ipc, but note that this process
97 and all its children will still have access to the memory, its
98 just that the shmid is no longer valid for other shm calls. This
99 means we don't leave behind lots of shm segments after we exit
101 See Stevens "advanced programming in unix env" for details
103 shmctl(shmid
, IPC_RMID
, 0);
109 /********************************************************************
110 Ensure a connection is encrypted.
111 ********************************************************************/
113 static bool force_cli_encryption(struct cli_state
*c
,
114 const char *sharename
)
117 uint32 caplow
, caphigh
;
120 if (!SERVER_HAS_UNIX_CIFS(c
)) {
121 d_printf("Encryption required and "
122 "server that doesn't support "
123 "UNIX extensions - failing connect\n");
127 status
= cli_unix_extensions_version(c
, &major
, &minor
, &caplow
,
129 if (!NT_STATUS_IS_OK(status
)) {
130 d_printf("Encryption required and "
131 "can't get UNIX CIFS extensions "
132 "version from server: %s\n", nt_errstr(status
));
136 if (!(caplow
& CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP
)) {
137 d_printf("Encryption required and "
138 "share %s doesn't support "
139 "encryption.\n", sharename
);
143 if (c
->use_kerberos
) {
144 status
= cli_gss_smb_encryption_start(c
);
146 status
= cli_raw_ntlm_smb_encryption_start(c
,
152 if (!NT_STATUS_IS_OK(status
)) {
153 d_printf("Encryption required and "
154 "setup failed with error %s.\n",
163 static struct cli_state
*open_nbt_connection(void)
165 struct nmb_name called
, calling
;
166 struct sockaddr_storage ss
;
170 make_nmb_name(&calling
, myname
, 0x0);
171 make_nmb_name(&called
, host
, 0x20);
175 if (!(c
= cli_initialise())) {
176 printf("Failed initialize cli_struct to connect with %s\n", host
);
180 c
->port
= port_to_use
;
182 status
= cli_connect(c
, host
, &ss
);
183 if (!NT_STATUS_IS_OK(status
)) {
184 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
188 c
->use_kerberos
= use_kerberos
;
190 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
191 if (use_oplocks
) c
->use_oplocks
= True
;
192 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
194 if (!cli_session_request(c
, &calling
, &called
)) {
196 * Well, that failed, try *SMBSERVER ...
197 * However, we must reconnect as well ...
199 status
= cli_connect(c
, host
, &ss
);
200 if (!NT_STATUS_IS_OK(status
)) {
201 printf("Failed to connect with %s. Error %s\n", host
, nt_errstr(status
) );
205 make_nmb_name(&called
, "*SMBSERVER", 0x20);
206 if (!cli_session_request(c
, &calling
, &called
)) {
207 printf("%s rejected the session\n",host
);
208 printf("We tried with a called name of %s & %s\n",
218 /* Insert a NULL at the first separator of the given path and return a pointer
219 * to the remainder of the string.
222 terminate_path_at_separator(char * path
)
230 if ((p
= strchr_m(path
, '/'))) {
235 if ((p
= strchr_m(path
, '\\'))) {
245 parse a //server/share type UNC name
247 bool smbcli_parse_unc(const char *unc_name
, TALLOC_CTX
*mem_ctx
,
248 char **hostname
, char **sharename
)
252 *hostname
= *sharename
= NULL
;
254 if (strncmp(unc_name
, "\\\\", 2) &&
255 strncmp(unc_name
, "//", 2)) {
259 *hostname
= talloc_strdup(mem_ctx
, &unc_name
[2]);
260 p
= terminate_path_at_separator(*hostname
);
263 *sharename
= talloc_strdup(mem_ctx
, p
);
264 terminate_path_at_separator(*sharename
);
267 if (*hostname
&& *sharename
) {
271 TALLOC_FREE(*hostname
);
272 TALLOC_FREE(*sharename
);
276 static bool torture_open_connection_share(struct cli_state
**c
,
277 const char *hostname
,
278 const char *sharename
)
285 flags
|= CLI_FULL_CONNECTION_USE_KERBEROS
;
287 flags
|= CLI_FULL_CONNECTION_OPLOCKS
;
288 if (use_level_II_oplocks
)
289 flags
|= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS
;
291 status
= cli_full_connection(c
, myname
,
292 hostname
, NULL
, port_to_use
,
295 password
, flags
, Undefined
, &retry
);
296 if (!NT_STATUS_IS_OK(status
)) {
297 printf("failed to open share connection: //%s/%s port:%d - %s\n",
298 hostname
, sharename
, port_to_use
, nt_errstr(status
));
302 (*c
)->timeout
= 120000; /* set a really long timeout (2 minutes) */
305 return force_cli_encryption(*c
,
311 bool torture_open_connection(struct cli_state
**c
, int conn_index
)
313 char **unc_list
= NULL
;
314 int num_unc_names
= 0;
317 if (use_multishare_conn
==True
) {
319 unc_list
= file_lines_load(multishare_conn_fname
, &num_unc_names
, 0, NULL
);
320 if (!unc_list
|| num_unc_names
<= 0) {
321 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname
);
325 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
327 printf("Failed to parse UNC name %s\n",
328 unc_list
[conn_index
% num_unc_names
]);
329 TALLOC_FREE(unc_list
);
333 result
= torture_open_connection_share(c
, h
, s
);
335 /* h, s were copied earlier */
336 TALLOC_FREE(unc_list
);
340 return torture_open_connection_share(c
, host
, share
);
343 bool torture_cli_session_setup2(struct cli_state
*cli
, uint16
*new_vuid
)
345 uint16 old_vuid
= cli
->vuid
;
346 fstring old_user_name
;
347 size_t passlen
= strlen(password
);
351 fstrcpy(old_user_name
, cli
->user_name
);
353 ret
= NT_STATUS_IS_OK(cli_session_setup(cli
, username
,
357 *new_vuid
= cli
->vuid
;
358 cli
->vuid
= old_vuid
;
359 status
= cli_set_username(cli
, old_user_name
);
360 if (!NT_STATUS_IS_OK(status
)) {
367 bool torture_close_connection(struct cli_state
*c
)
372 status
= cli_tdis(c
);
373 if (!NT_STATUS_IS_OK(status
)) {
374 printf("tdis failed (%s)\n", nt_errstr(status
));
384 /* check if the server produced the expected error code */
385 static bool check_error(int line
, struct cli_state
*c
,
386 uint8 eclass
, uint32 ecode
, NTSTATUS nterr
)
388 if (cli_is_dos_error(c
)) {
392 /* Check DOS error */
394 cli_dos_error(c
, &cclass
, &num
);
396 if (eclass
!= cclass
|| ecode
!= num
) {
397 printf("unexpected error code class=%d code=%d\n",
398 (int)cclass
, (int)num
);
399 printf(" expected %d/%d %s (line=%d)\n",
400 (int)eclass
, (int)ecode
, nt_errstr(nterr
), line
);
409 status
= cli_nt_error(c
);
411 if (NT_STATUS_V(nterr
) != NT_STATUS_V(status
)) {
412 printf("unexpected error code %s\n", nt_errstr(status
));
413 printf(" expected %s (line=%d)\n", nt_errstr(nterr
), line
);
422 static bool wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
424 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
425 if (!check_error(__LINE__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
431 static bool rw_torture(struct cli_state
*c
)
433 const char *lockfname
= "\\torture.lck";
437 pid_t pid2
, pid
= getpid();
443 memset(buf
, '\0', sizeof(buf
));
445 status
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
447 if (!NT_STATUS_IS_OK(status
)) {
448 status
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
, &fnum2
);
450 if (!NT_STATUS_IS_OK(status
)) {
451 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
455 for (i
=0;i
<torture_numops
;i
++) {
456 unsigned n
= (unsigned)sys_random()%10;
458 printf("%d\r", i
); fflush(stdout
);
460 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
462 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
466 if (!NT_STATUS_IS_OK(cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
, &fnum
))) {
467 printf("open failed (%s)\n", cli_errstr(c
));
472 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
473 printf("write failed (%s)\n", cli_errstr(c
));
478 if (cli_write(c
, fnum
, 0, (char *)buf
,
479 sizeof(pid
)+(j
*sizeof(buf
)),
480 sizeof(buf
)) != sizeof(buf
)) {
481 printf("write failed (%s)\n", cli_errstr(c
));
488 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
489 printf("read failed (%s)\n", cli_errstr(c
));
494 printf("data corruption!\n");
498 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
499 printf("close failed (%s)\n", cli_errstr(c
));
503 if (!NT_STATUS_IS_OK(cli_unlink(c
, fname
, aSYSTEM
| aHIDDEN
))) {
504 printf("unlink failed (%s)\n", cli_errstr(c
));
508 if (!NT_STATUS_IS_OK(cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int)))) {
509 printf("unlock failed (%s)\n", cli_errstr(c
));
515 cli_unlink(c
, lockfname
, aSYSTEM
| aHIDDEN
);
522 static bool run_torture(int dummy
)
524 struct cli_state
*cli
;
529 cli_sockopt(cli
, sockops
);
531 ret
= rw_torture(cli
);
533 if (!torture_close_connection(cli
)) {
540 static bool rw_torture3(struct cli_state
*c
, char *lockfname
)
542 uint16_t fnum
= (uint16_t)-1;
547 unsigned countprev
= 0;
553 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
555 SIVAL(buf
, i
, sys_random());
560 if (!NT_STATUS_IS_OK(cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
561 DENY_NONE
, &fnum
))) {
562 printf("first open read/write of %s failed (%s)\n",
563 lockfname
, cli_errstr(c
));
569 for (i
= 0; i
< 500 && fnum
== (uint16_t)-1; i
++)
571 status
= cli_open(c
, lockfname
, O_RDONLY
,
573 if (!NT_STATUS_IS_OK(status
)) {
578 if (!NT_STATUS_IS_OK(status
)) {
579 printf("second open read-only of %s failed (%s)\n",
580 lockfname
, cli_errstr(c
));
586 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
588 if (count
>= countprev
) {
589 printf("%d %8d\r", i
, count
);
592 countprev
+= (sizeof(buf
) / 20);
597 sent
= ((unsigned)sys_random()%(20))+ 1;
598 if (sent
> sizeof(buf
) - count
)
600 sent
= sizeof(buf
) - count
;
603 if (cli_write(c
, fnum
, 0, buf
+count
, count
, (size_t)sent
) != sent
) {
604 printf("write failed (%s)\n", cli_errstr(c
));
610 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
614 printf("read failed offset:%d size:%ld (%s)\n",
615 count
, (unsigned long)sizeof(buf
)-count
,
622 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
624 printf("read/write compare failed\n");
625 printf("offset: %d req %ld recvd %ld\n", count
, (unsigned long)sizeof(buf
)-count
, (unsigned long)sent
);
634 if (!NT_STATUS_IS_OK(cli_close(c
, fnum
))) {
635 printf("close failed (%s)\n", cli_errstr(c
));
642 static bool rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
644 const char *lockfname
= "\\torture2.lck";
653 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
654 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
657 if (!NT_STATUS_IS_OK(cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
658 DENY_NONE
, &fnum1
))) {
659 printf("first open read/write of %s failed (%s)\n",
660 lockfname
, cli_errstr(c1
));
663 if (!NT_STATUS_IS_OK(cli_open(c2
, lockfname
, O_RDONLY
,
664 DENY_NONE
, &fnum2
))) {
665 printf("second open read-only of %s failed (%s)\n",
666 lockfname
, cli_errstr(c2
));
667 cli_close(c1
, fnum1
);
671 for (i
=0;i
<torture_numops
;i
++)
673 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
675 printf("%d\r", i
); fflush(stdout
);
678 generate_random_buffer((unsigned char *)buf
, buf_size
);
680 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
681 printf("write failed (%s)\n", cli_errstr(c1
));
686 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
687 printf("read failed (%s)\n", cli_errstr(c2
));
688 printf("read %d, expected %ld\n", (int)bytes_read
,
689 (unsigned long)buf_size
);
694 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
696 printf("read/write compare failed\n");
702 if (!NT_STATUS_IS_OK(cli_close(c2
, fnum2
))) {
703 printf("close failed (%s)\n", cli_errstr(c2
));
706 if (!NT_STATUS_IS_OK(cli_close(c1
, fnum1
))) {
707 printf("close failed (%s)\n", cli_errstr(c1
));
711 if (!NT_STATUS_IS_OK(cli_unlink(c1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
712 printf("unlink failed (%s)\n", cli_errstr(c1
));
719 static bool run_readwritetest(int dummy
)
721 struct cli_state
*cli1
, *cli2
;
722 bool test1
, test2
= False
;
724 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
727 cli_sockopt(cli1
, sockops
);
728 cli_sockopt(cli2
, sockops
);
730 printf("starting readwritetest\n");
732 test1
= rw_torture2(cli1
, cli2
);
733 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
736 test2
= rw_torture2(cli1
, cli1
);
737 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
740 if (!torture_close_connection(cli1
)) {
744 if (!torture_close_connection(cli2
)) {
748 return (test1
&& test2
);
751 static bool run_readwritemulti(int dummy
)
753 struct cli_state
*cli
;
758 cli_sockopt(cli
, sockops
);
760 printf("run_readwritemulti: fname %s\n", randomfname
);
761 test
= rw_torture3(cli
, randomfname
);
763 if (!torture_close_connection(cli
)) {
770 static bool run_readwritelarge(int dummy
)
772 static struct cli_state
*cli1
;
774 const char *lockfname
= "\\large.dat";
779 if (!torture_open_connection(&cli1
, 0)) {
782 cli_sockopt(cli1
, sockops
);
783 memset(buf
,'\0',sizeof(buf
));
785 cli1
->max_xmit
= 128*1024;
787 printf("starting readwritelarge\n");
789 cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
);
791 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
792 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
796 cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
798 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
799 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
803 if (fsize
== sizeof(buf
))
804 printf("readwritelarge test 1 succeeded (size = %lx)\n",
805 (unsigned long)fsize
);
807 printf("readwritelarge test 1 failed (size = %lx)\n",
808 (unsigned long)fsize
);
812 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
813 printf("close failed (%s)\n", cli_errstr(cli1
));
817 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, lockfname
, aSYSTEM
| aHIDDEN
))) {
818 printf("unlink failed (%s)\n", cli_errstr(cli1
));
822 if (!NT_STATUS_IS_OK(cli_open(cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
, &fnum1
))) {
823 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(cli1
));
827 cli1
->max_xmit
= 4*1024;
829 cli_smbwrite(cli1
, fnum1
, buf
, 0, sizeof(buf
));
831 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
832 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
836 if (fsize
== sizeof(buf
))
837 printf("readwritelarge test 2 succeeded (size = %lx)\n",
838 (unsigned long)fsize
);
840 printf("readwritelarge test 2 failed (size = %lx)\n",
841 (unsigned long)fsize
);
846 /* ToDo - set allocation. JRA */
847 if(!cli_set_allocation_size(cli1
, fnum1
, 0)) {
848 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1
));
851 if (!cli_qfileinfo(cli1
, fnum1
, NULL
, &fsize
, NULL
, NULL
, NULL
, NULL
, NULL
)) {
852 printf("qfileinfo failed (%s)\n", cli_errstr(cli1
));
856 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize
);
859 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
860 printf("close failed (%s)\n", cli_errstr(cli1
));
864 if (!torture_close_connection(cli1
)) {
873 #define ival(s) strtol(s, NULL, 0)
875 /* run a test that simulates an approximate netbench client load */
876 static bool run_netbench(int client
)
878 struct cli_state
*cli
;
883 const char *params
[20];
890 cli_sockopt(cli
, sockops
);
894 slprintf(cname
,sizeof(cname
)-1, "client%d", client
);
896 f
= fopen(client_txt
, "r");
903 while (fgets(line
, sizeof(line
)-1, f
)) {
907 line
[strlen(line
)-1] = 0;
909 /* printf("[%d] %s\n", line_count, line); */
911 all_string_sub(line
,"client1", cname
, sizeof(line
));
913 /* parse the command parameters */
914 params
[0] = strtok_r(line
, " ", &saveptr
);
916 while (params
[i
]) params
[++i
] = strtok_r(NULL
, " ", &saveptr
);
922 if (!strncmp(params
[0],"SMB", 3)) {
923 printf("ERROR: You are using a dbench 1 load file\n");
927 if (!strcmp(params
[0],"NTCreateX")) {
928 nb_createx(params
[1], ival(params
[2]), ival(params
[3]),
930 } else if (!strcmp(params
[0],"Close")) {
931 nb_close(ival(params
[1]));
932 } else if (!strcmp(params
[0],"Rename")) {
933 nb_rename(params
[1], params
[2]);
934 } else if (!strcmp(params
[0],"Unlink")) {
935 nb_unlink(params
[1]);
936 } else if (!strcmp(params
[0],"Deltree")) {
937 nb_deltree(params
[1]);
938 } else if (!strcmp(params
[0],"Rmdir")) {
940 } else if (!strcmp(params
[0],"QUERY_PATH_INFORMATION")) {
941 nb_qpathinfo(params
[1]);
942 } else if (!strcmp(params
[0],"QUERY_FILE_INFORMATION")) {
943 nb_qfileinfo(ival(params
[1]));
944 } else if (!strcmp(params
[0],"QUERY_FS_INFORMATION")) {
945 nb_qfsinfo(ival(params
[1]));
946 } else if (!strcmp(params
[0],"FIND_FIRST")) {
947 nb_findfirst(params
[1]);
948 } else if (!strcmp(params
[0],"WriteX")) {
949 nb_writex(ival(params
[1]),
950 ival(params
[2]), ival(params
[3]), ival(params
[4]));
951 } else if (!strcmp(params
[0],"ReadX")) {
952 nb_readx(ival(params
[1]),
953 ival(params
[2]), ival(params
[3]), ival(params
[4]));
954 } else if (!strcmp(params
[0],"Flush")) {
955 nb_flush(ival(params
[1]));
957 printf("Unknown operation %s\n", params
[0]);
965 if (!torture_close_connection(cli
)) {
973 /* run a test that simulates an approximate netbench client load */
974 static bool run_nbench(int dummy
)
983 signal(SIGALRM
, nb_alarm
);
985 t
= create_procs(run_netbench
, &correct
);
988 printf("\nThroughput %g MB/sec\n",
989 1.0e-6 * nbio_total() / t
);
995 This test checks for two things:
997 1) correct support for retaining locks over a close (ie. the server
998 must not use posix semantics)
999 2) support for lock timeouts
1001 static bool run_locktest1(int dummy
)
1003 struct cli_state
*cli1
, *cli2
;
1004 const char *fname
= "\\lockt1.lck";
1005 uint16_t fnum1
, fnum2
, fnum3
;
1007 unsigned lock_timeout
;
1009 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1012 cli_sockopt(cli1
, sockops
);
1013 cli_sockopt(cli2
, sockops
);
1015 printf("starting locktest1\n");
1017 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1019 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1020 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1023 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1024 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1027 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1028 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1032 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1033 printf("lock1 failed (%s)\n", cli_errstr(cli1
));
1038 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1039 printf("lock2 succeeded! This is a locking bug\n");
1042 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1043 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1047 lock_timeout
= (1 + (random() % 20));
1048 printf("Testing lock timeout with timeout=%u\n", lock_timeout
);
1050 if (cli_lock(cli2
, fnum3
, 0, 4, lock_timeout
* 1000, WRITE_LOCK
)) {
1051 printf("lock3 succeeded! This is a locking bug\n");
1054 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1055 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1059 if (ABS(t2
- t1
) < lock_timeout
-1) {
1060 printf("error: This server appears not to support timed lock requests\n");
1063 printf("server slept for %u seconds for a %u second timeout\n",
1064 (unsigned int)(t2
-t1
), lock_timeout
);
1066 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
1067 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1071 if (cli_lock(cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1072 printf("lock4 succeeded! This is a locking bug\n");
1075 if (!check_error(__LINE__
, cli2
, ERRDOS
, ERRlock
,
1076 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1079 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1080 printf("close2 failed (%s)\n", cli_errstr(cli1
));
1084 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum3
))) {
1085 printf("close3 failed (%s)\n", cli_errstr(cli2
));
1089 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1090 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1095 if (!torture_close_connection(cli1
)) {
1099 if (!torture_close_connection(cli2
)) {
1103 printf("Passed locktest1\n");
1108 this checks to see if a secondary tconx can use open files from an
1111 static bool run_tcon_test(int dummy
)
1113 static struct cli_state
*cli
;
1114 const char *fname
= "\\tcontest.tmp";
1116 uint16 cnum1
, cnum2
, cnum3
;
1117 uint16 vuid1
, vuid2
;
1122 memset(buf
, '\0', sizeof(buf
));
1124 if (!torture_open_connection(&cli
, 0)) {
1127 cli_sockopt(cli
, sockops
);
1129 printf("starting tcontest\n");
1131 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1133 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1134 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1141 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) != 4) {
1142 printf("initial write failed (%s)", cli_errstr(cli
));
1146 status
= cli_tcon_andx(cli
, share
, "?????",
1147 password
, strlen(password
)+1);
1148 if (!NT_STATUS_IS_OK(status
)) {
1149 printf("%s refused 2nd tree connect (%s)\n", host
,
1156 cnum3
= MAX(cnum1
, cnum2
) + 1; /* any invalid number */
1157 vuid2
= cli
->vuid
+ 1;
1159 /* try a write with the wrong tid */
1162 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1163 printf("* server allows write with wrong TID\n");
1166 printf("server fails write with wrong TID : %s\n", cli_errstr(cli
));
1170 /* try a write with an invalid tid */
1173 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1174 printf("* server allows write with invalid TID\n");
1177 printf("server fails write with invalid TID : %s\n", cli_errstr(cli
));
1180 /* try a write with an invalid vuid */
1184 if (cli_write(cli
, fnum1
, 0, buf
, 130, 4) == 4) {
1185 printf("* server allows write with invalid VUID\n");
1188 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli
));
1194 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1195 printf("close failed (%s)\n", cli_errstr(cli
));
1201 status
= cli_tdis(cli
);
1202 if (!NT_STATUS_IS_OK(status
)) {
1203 printf("secondary tdis failed (%s)\n", nt_errstr(status
));
1209 if (!torture_close_connection(cli
)) {
1218 checks for old style tcon support
1220 static bool run_tcon2_test(int dummy
)
1222 static struct cli_state
*cli
;
1223 uint16 cnum
, max_xmit
;
1227 if (!torture_open_connection(&cli
, 0)) {
1230 cli_sockopt(cli
, sockops
);
1232 printf("starting tcon2 test\n");
1234 if (asprintf(&service
, "\\\\%s\\%s", host
, share
) == -1) {
1238 status
= cli_raw_tcon(cli
, service
, password
, "?????", &max_xmit
, &cnum
);
1240 if (!NT_STATUS_IS_OK(status
)) {
1241 printf("tcon2 failed : %s\n", cli_errstr(cli
));
1243 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1244 (int)max_xmit
, (int)cnum
, SVAL(cli
->inbuf
, smb_tid
));
1247 if (!torture_close_connection(cli
)) {
1251 printf("Passed tcon2 test\n");
1255 static bool tcon_devtest(struct cli_state
*cli
,
1256 const char *myshare
, const char *devtype
,
1257 const char *return_devtype
,
1258 NTSTATUS expected_error
)
1263 status
= cli_tcon_andx(cli
, myshare
, devtype
,
1264 password
, strlen(password
)+1);
1266 if (NT_STATUS_IS_OK(expected_error
)) {
1267 if (NT_STATUS_IS_OK(status
)) {
1268 if (strcmp(cli
->dev
, return_devtype
) == 0) {
1271 printf("tconX to share %s with type %s "
1272 "succeeded but returned the wrong "
1273 "device type (got [%s] but should have got [%s])\n",
1274 myshare
, devtype
, cli
->dev
, return_devtype
);
1278 printf("tconX to share %s with type %s "
1279 "should have succeeded but failed\n",
1285 if (NT_STATUS_IS_OK(status
)) {
1286 printf("tconx to share %s with type %s "
1287 "should have failed but succeeded\n",
1291 if (NT_STATUS_EQUAL(cli_nt_error(cli
),
1295 printf("Returned unexpected error\n");
1304 checks for correct tconX support
1306 static bool run_tcon_devtype_test(int dummy
)
1308 static struct cli_state
*cli1
= NULL
;
1314 status
= cli_full_connection(&cli1
, myname
,
1315 host
, NULL
, port_to_use
,
1317 username
, workgroup
,
1318 password
, flags
, Undefined
, &retry
);
1320 if (!NT_STATUS_IS_OK(status
)) {
1321 printf("could not open connection\n");
1325 if (!tcon_devtest(cli1
, "IPC$", "A:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1328 if (!tcon_devtest(cli1
, "IPC$", "?????", "IPC", NT_STATUS_OK
))
1331 if (!tcon_devtest(cli1
, "IPC$", "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1334 if (!tcon_devtest(cli1
, "IPC$", "IPC", "IPC", NT_STATUS_OK
))
1337 if (!tcon_devtest(cli1
, "IPC$", "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1340 if (!tcon_devtest(cli1
, share
, "A:", "A:", NT_STATUS_OK
))
1343 if (!tcon_devtest(cli1
, share
, "?????", "A:", NT_STATUS_OK
))
1346 if (!tcon_devtest(cli1
, share
, "LPT:", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1349 if (!tcon_devtest(cli1
, share
, "IPC", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1352 if (!tcon_devtest(cli1
, share
, "FOOBA", NULL
, NT_STATUS_BAD_DEVICE_TYPE
))
1358 printf("Passed tcondevtest\n");
1365 This test checks that
1367 1) the server supports multiple locking contexts on the one SMB
1368 connection, distinguished by PID.
1370 2) the server correctly fails overlapping locks made by the same PID (this
1371 goes against POSIX behaviour, which is why it is tricky to implement)
1373 3) the server denies unlock requests by an incorrect client PID
1375 static bool run_locktest2(int dummy
)
1377 static struct cli_state
*cli
;
1378 const char *fname
= "\\lockt2.lck";
1379 uint16_t fnum1
, fnum2
, fnum3
;
1380 bool correct
= True
;
1382 if (!torture_open_connection(&cli
, 0)) {
1386 cli_sockopt(cli
, sockops
);
1388 printf("starting locktest2\n");
1390 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
1394 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1395 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
1399 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1400 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1406 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum3
))) {
1407 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(cli
));
1413 if (!cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1414 printf("lock1 failed (%s)\n", cli_errstr(cli
));
1418 if (cli_lock(cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1419 printf("WRITE lock1 succeeded! This is a locking bug\n");
1422 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1423 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1426 if (cli_lock(cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1427 printf("WRITE lock2 succeeded! This is a locking bug\n");
1430 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1431 NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1434 if (cli_lock(cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1435 printf("READ lock2 succeeded! This is a locking bug\n");
1438 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
,
1439 NT_STATUS_FILE_LOCK_CONFLICT
)) return False
;
1442 if (!cli_lock(cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1443 printf("lock at 100 failed (%s)\n", cli_errstr(cli
));
1446 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 100, 4))) {
1447 printf("unlock at 100 succeeded! This is a locking bug\n");
1451 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 4))) {
1452 printf("unlock1 succeeded! This is a locking bug\n");
1455 if (!check_error(__LINE__
, cli
,
1457 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1460 if (NT_STATUS_IS_OK(cli_unlock(cli
, fnum1
, 0, 8))) {
1461 printf("unlock2 succeeded! This is a locking bug\n");
1464 if (!check_error(__LINE__
, cli
,
1466 NT_STATUS_RANGE_NOT_LOCKED
)) return False
;
1469 if (cli_lock(cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1470 printf("lock3 succeeded! This is a locking bug\n");
1473 if (!check_error(__LINE__
, cli
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
1478 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum1
))) {
1479 printf("close1 failed (%s)\n", cli_errstr(cli
));
1483 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum2
))) {
1484 printf("close2 failed (%s)\n", cli_errstr(cli
));
1488 if (!NT_STATUS_IS_OK(cli_close(cli
, fnum3
))) {
1489 printf("close3 failed (%s)\n", cli_errstr(cli
));
1493 if (!torture_close_connection(cli
)) {
1497 printf("locktest2 finished\n");
1504 This test checks that
1506 1) the server supports the full offset range in lock requests
1508 static bool run_locktest3(int dummy
)
1510 static struct cli_state
*cli1
, *cli2
;
1511 const char *fname
= "\\lockt3.lck";
1512 uint16_t fnum1
, fnum2
;
1515 bool correct
= True
;
1517 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1519 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1522 cli_sockopt(cli1
, sockops
);
1523 cli_sockopt(cli2
, sockops
);
1525 printf("starting locktest3\n");
1527 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1529 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
1530 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
1533 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
1534 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
1538 for (offset
=i
=0;i
<torture_numops
;i
++) {
1540 if (!cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1541 printf("lock1 %d failed (%s)\n",
1547 if (!cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1548 printf("lock2 %d failed (%s)\n",
1555 for (offset
=i
=0;i
<torture_numops
;i
++) {
1558 if (cli_lock(cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1559 printf("error: lock1 %d succeeded!\n", i
);
1563 if (cli_lock(cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1564 printf("error: lock2 %d succeeded!\n", i
);
1568 if (cli_lock(cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1569 printf("error: lock3 %d succeeded!\n", i
);
1573 if (cli_lock(cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1574 printf("error: lock4 %d succeeded!\n", i
);
1579 for (offset
=i
=0;i
<torture_numops
;i
++) {
1582 if (!NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, offset
-1, 1))) {
1583 printf("unlock1 %d failed (%s)\n",
1589 if (!NT_STATUS_IS_OK(cli_unlock(cli2
, fnum2
, offset
-2, 1))) {
1590 printf("unlock2 %d failed (%s)\n",
1597 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
1598 printf("close1 failed (%s)\n", cli_errstr(cli1
));
1602 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
1603 printf("close2 failed (%s)\n", cli_errstr(cli2
));
1607 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
1608 printf("unlink failed (%s)\n", cli_errstr(cli1
));
1612 if (!torture_close_connection(cli1
)) {
1616 if (!torture_close_connection(cli2
)) {
1620 printf("finished locktest3\n");
1625 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1626 printf("** "); correct = False; \
1630 looks at overlapping locks
1632 static bool run_locktest4(int dummy
)
1634 static struct cli_state
*cli1
, *cli2
;
1635 const char *fname
= "\\lockt4.lck";
1636 uint16_t fnum1
, fnum2
, f
;
1639 bool correct
= True
;
1641 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1645 cli_sockopt(cli1
, sockops
);
1646 cli_sockopt(cli2
, sockops
);
1648 printf("starting locktest4\n");
1650 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1652 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1653 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1655 memset(buf
, 0, sizeof(buf
));
1657 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1658 printf("Failed to create file\n");
1663 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1664 cli_lock(cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1665 EXPECTED(ret
, False
);
1666 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1668 ret
= cli_lock(cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1669 cli_lock(cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1670 EXPECTED(ret
, True
);
1671 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1673 ret
= cli_lock(cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1674 cli_lock(cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1675 EXPECTED(ret
, False
);
1676 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1678 ret
= cli_lock(cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1679 cli_lock(cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1680 EXPECTED(ret
, True
);
1681 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1683 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1684 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1685 EXPECTED(ret
, False
);
1686 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1688 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1689 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1690 EXPECTED(ret
, True
);
1691 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1693 ret
= cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1694 cli_lock(cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1695 EXPECTED(ret
, True
);
1696 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1698 ret
= cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1699 cli_lock(cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1700 EXPECTED(ret
, False
);
1701 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1703 ret
= cli_lock(cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1704 cli_lock(cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1705 EXPECTED(ret
, False
);
1706 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1708 ret
= cli_lock(cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1709 cli_lock(cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1710 EXPECTED(ret
, True
);
1711 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1713 ret
= (cli_setpid(cli1
, 1), cli_lock(cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1714 (cli_setpid(cli1
, 2), cli_lock(cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1715 EXPECTED(ret
, False
);
1716 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1718 ret
= cli_lock(cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1719 cli_lock(cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1720 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 110, 6));
1721 EXPECTED(ret
, False
);
1722 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1725 ret
= cli_lock(cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1726 (cli_read(cli2
, fnum2
, buf
, 120, 4) == 4);
1727 EXPECTED(ret
, False
);
1728 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1730 ret
= cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1731 (cli_write(cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1732 EXPECTED(ret
, False
);
1733 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1736 ret
= cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1737 cli_lock(cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1738 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4)) &&
1739 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 140, 4));
1740 EXPECTED(ret
, True
);
1741 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1744 ret
= cli_lock(cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1745 cli_lock(cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1746 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4)) &&
1747 (cli_read(cli2
, fnum2
, buf
, 150, 4) == 4) &&
1748 !(cli_write(cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1749 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 150, 4));
1750 EXPECTED(ret
, True
);
1751 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1753 ret
= cli_lock(cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1754 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 160, 4)) &&
1755 (cli_write(cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1756 (cli_read(cli2
, fnum2
, buf
, 160, 4) == 4);
1757 EXPECTED(ret
, True
);
1758 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1760 ret
= cli_lock(cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1761 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 170, 4)) &&
1762 (cli_write(cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1763 (cli_read(cli2
, fnum2
, buf
, 170, 4) == 4);
1764 EXPECTED(ret
, True
);
1765 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1767 ret
= cli_lock(cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1768 cli_lock(cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1769 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 190, 4)) &&
1770 !(cli_write(cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1771 (cli_read(cli2
, fnum2
, buf
, 190, 4) == 4);
1772 EXPECTED(ret
, True
);
1773 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1775 cli_close(cli1
, fnum1
);
1776 cli_close(cli2
, fnum2
);
1777 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1778 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &f
);
1779 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1780 cli_lock(cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1781 NT_STATUS_IS_OK(cli_close(cli1
, fnum1
)) &&
1782 NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
)) &&
1783 cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1785 cli_close(cli1
, fnum1
);
1786 EXPECTED(ret
, True
);
1787 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1790 cli_close(cli1
, fnum1
);
1791 cli_close(cli2
, fnum2
);
1792 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1793 torture_close_connection(cli1
);
1794 torture_close_connection(cli2
);
1796 printf("finished locktest4\n");
1801 looks at lock upgrade/downgrade.
1803 static bool run_locktest5(int dummy
)
1805 static struct cli_state
*cli1
, *cli2
;
1806 const char *fname
= "\\lockt5.lck";
1807 uint16_t fnum1
, fnum2
, fnum3
;
1810 bool correct
= True
;
1812 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
1816 cli_sockopt(cli1
, sockops
);
1817 cli_sockopt(cli2
, sockops
);
1819 printf("starting locktest5\n");
1821 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1823 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1824 cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
);
1825 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum3
);
1827 memset(buf
, 0, sizeof(buf
));
1829 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1830 printf("Failed to create file\n");
1835 /* Check for NT bug... */
1836 ret
= cli_lock(cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1837 cli_lock(cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1838 cli_close(cli1
, fnum1
);
1839 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1840 ret
= cli_lock(cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1841 EXPECTED(ret
, True
);
1842 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1843 cli_close(cli1
, fnum1
);
1844 cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
1845 cli_unlock(cli1
, fnum3
, 0, 1);
1847 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1848 cli_lock(cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1849 EXPECTED(ret
, True
);
1850 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1852 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1853 EXPECTED(ret
, False
);
1855 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1857 /* Unlock the process 2 lock. */
1858 cli_unlock(cli2
, fnum2
, 0, 4);
1860 ret
= cli_lock(cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1861 EXPECTED(ret
, False
);
1863 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1865 /* Unlock the process 1 fnum3 lock. */
1866 cli_unlock(cli1
, fnum3
, 0, 4);
1868 /* Stack 2 more locks here. */
1869 ret
= cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1870 cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1872 EXPECTED(ret
, True
);
1873 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
1875 /* Unlock the first process lock, then check this was the WRITE lock that was
1878 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
1879 cli_lock(cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1881 EXPECTED(ret
, True
);
1882 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
1884 /* Unlock the process 2 lock. */
1885 cli_unlock(cli2
, fnum2
, 0, 4);
1887 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1889 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 1, 1)) &&
1890 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4)) &&
1891 NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
1893 EXPECTED(ret
, True
);
1894 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
1896 /* Ensure the next unlock fails. */
1897 ret
= NT_STATUS_IS_OK(cli_unlock(cli1
, fnum1
, 0, 4));
1898 EXPECTED(ret
, False
);
1899 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
1901 /* Ensure connection 2 can get a write lock. */
1902 ret
= cli_lock(cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1903 EXPECTED(ret
, True
);
1905 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
1909 cli_close(cli1
, fnum1
);
1910 cli_close(cli2
, fnum2
);
1911 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1912 if (!torture_close_connection(cli1
)) {
1915 if (!torture_close_connection(cli2
)) {
1919 printf("finished locktest5\n");
1925 tries the unusual lockingX locktype bits
1927 static bool run_locktest6(int dummy
)
1929 static struct cli_state
*cli
;
1930 const char *fname
[1] = { "\\lock6.txt" };
1935 if (!torture_open_connection(&cli
, 0)) {
1939 cli_sockopt(cli
, sockops
);
1941 printf("starting locktest6\n");
1944 printf("Testing %s\n", fname
[i
]);
1946 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
1948 cli_open(cli
, fname
[i
], O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
);
1949 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE
);
1950 cli_close(cli
, fnum
);
1951 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status
));
1953 cli_open(cli
, fname
[i
], O_RDWR
, DENY_NONE
, &fnum
);
1954 status
= cli_locktype(cli
, fnum
, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK
);
1955 cli_close(cli
, fnum
);
1956 printf("CANCEL_LOCK gave %s\n", nt_errstr(status
));
1958 cli_unlink(cli
, fname
[i
], aSYSTEM
| aHIDDEN
);
1961 torture_close_connection(cli
);
1963 printf("finished locktest6\n");
1967 static bool run_locktest7(int dummy
)
1969 struct cli_state
*cli1
;
1970 const char *fname
= "\\lockt7.lck";
1973 bool correct
= False
;
1975 if (!torture_open_connection(&cli1
, 0)) {
1979 cli_sockopt(cli1
, sockops
);
1981 printf("starting locktest7\n");
1983 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
1985 cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
);
1987 memset(buf
, 0, sizeof(buf
));
1989 if (cli_write(cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1990 printf("Failed to create file\n");
1994 cli_setpid(cli1
, 1);
1996 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, READ_LOCK
)) {
1997 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2000 printf("pid1 successfully locked range 130:4 for READ\n");
2003 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2004 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2007 printf("pid1 successfully read the range 130:4\n");
2010 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2011 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2012 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2013 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2017 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2021 cli_setpid(cli1
, 2);
2023 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2024 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2026 printf("pid2 successfully read the range 130:4\n");
2029 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2030 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2031 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2032 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2036 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2040 cli_setpid(cli1
, 1);
2041 cli_unlock(cli1
, fnum1
, 130, 4);
2043 if (!cli_lock(cli1
, fnum1
, 130, 4, 0, WRITE_LOCK
)) {
2044 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1
));
2047 printf("pid1 successfully locked range 130:4 for WRITE\n");
2050 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2051 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2054 printf("pid1 successfully read the range 130:4\n");
2057 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2058 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2061 printf("pid1 successfully wrote to the range 130:4\n");
2064 cli_setpid(cli1
, 2);
2066 if (cli_read(cli1
, fnum1
, buf
, 130, 4) != 4) {
2067 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1
));
2068 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2069 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2073 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2077 if (cli_write(cli1
, fnum1
, 0, buf
, 130, 4) != 4) {
2078 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1
));
2079 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT
)) {
2080 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2084 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2088 cli_unlock(cli1
, fnum1
, 130, 0);
2092 cli_close(cli1
, fnum1
);
2093 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2094 torture_close_connection(cli1
);
2096 printf("finished locktest7\n");
2101 * This demonstrates a problem with our use of GPFS share modes: A file
2102 * descriptor sitting in the pending close queue holding a GPFS share mode
2103 * blocks opening a file another time. Happens with Word 2007 temp files.
2104 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2105 * open is denied with NT_STATUS_SHARING_VIOLATION.
2108 static bool run_locktest8(int dummy
)
2110 struct cli_state
*cli1
;
2111 const char *fname
= "\\lockt8.lck";
2112 uint16_t fnum1
, fnum2
;
2114 bool correct
= False
;
2117 if (!torture_open_connection(&cli1
, 0)) {
2121 cli_sockopt(cli1
, sockops
);
2123 printf("starting locktest8\n");
2125 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2127 status
= cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_WRITE
,
2129 if (!NT_STATUS_IS_OK(status
)) {
2130 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2134 memset(buf
, 0, sizeof(buf
));
2136 status
= cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum2
);
2137 if (!NT_STATUS_IS_OK(status
)) {
2138 d_fprintf(stderr
, "cli_open second time returned %s\n",
2143 if (!cli_lock(cli1
, fnum2
, 1, 1, 0, READ_LOCK
)) {
2144 printf("Unable to apply read lock on range 1:1, error was "
2145 "%s\n", cli_errstr(cli1
));
2149 status
= cli_close(cli1
, fnum1
);
2150 if (!NT_STATUS_IS_OK(status
)) {
2151 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2155 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
);
2156 if (!NT_STATUS_IS_OK(status
)) {
2157 d_fprintf(stderr
, "cli_open third time returned %s\n",
2165 cli_close(cli1
, fnum1
);
2166 cli_close(cli1
, fnum2
);
2167 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2168 torture_close_connection(cli1
);
2170 printf("finished locktest8\n");
2175 * This test is designed to be run in conjunction with
2176 * external NFS or POSIX locks taken in the filesystem.
2177 * It checks that the smbd server will block until the
2178 * lock is released and then acquire it. JRA.
2181 static bool got_alarm
;
2182 static int alarm_fd
;
2184 static void alarm_handler(int dummy
)
2189 static void alarm_handler_parent(int dummy
)
2194 static void do_local_lock(int read_fd
, int write_fd
)
2199 const char *local_pathname
= NULL
;
2202 local_pathname
= talloc_asprintf(talloc_tos(),
2203 "%s/lockt9.lck", local_path
);
2204 if (!local_pathname
) {
2205 printf("child: alloc fail\n");
2209 unlink(local_pathname
);
2210 fd
= open(local_pathname
, O_RDWR
|O_CREAT
, 0666);
2212 printf("child: open of %s failed %s.\n",
2213 local_pathname
, strerror(errno
));
2217 /* Now take a fcntl lock. */
2218 lock
.l_type
= F_WRLCK
;
2219 lock
.l_whence
= SEEK_SET
;
2222 lock
.l_pid
= getpid();
2224 ret
= fcntl(fd
,F_SETLK
,&lock
);
2226 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2227 local_pathname
, strerror(errno
));
2230 printf("child: got lock 0:4 on file %s.\n",
2235 CatchSignal(SIGALRM
, alarm_handler
);
2237 /* Signal the parent. */
2238 if (write(write_fd
, &c
, 1) != 1) {
2239 printf("child: start signal fail %s.\n",
2246 /* Wait for the parent to be ready. */
2247 if (read(read_fd
, &c
, 1) != 1) {
2248 printf("child: reply signal fail %s.\n",
2256 printf("child: released lock 0:4 on file %s.\n",
2262 static bool run_locktest9(int dummy
)
2264 struct cli_state
*cli1
;
2265 const char *fname
= "\\lockt9.lck";
2267 bool correct
= False
;
2268 int pipe_in
[2], pipe_out
[2];
2272 struct timeval start
;
2276 printf("starting locktest9\n");
2278 if (local_path
== NULL
) {
2279 d_fprintf(stderr
, "locktest9 must be given a local path via -l <localpath>\n");
2283 if (pipe(pipe_in
) == -1 || pipe(pipe_out
) == -1) {
2288 if (child_pid
== -1) {
2292 if (child_pid
== 0) {
2294 do_local_lock(pipe_out
[0], pipe_in
[1]);
2304 ret
= read(pipe_in
[0], &c
, 1);
2306 d_fprintf(stderr
, "failed to read start signal from child. %s\n",
2311 if (!torture_open_connection(&cli1
, 0)) {
2315 cli_sockopt(cli1
, sockops
);
2317 status
= cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
,
2319 if (!NT_STATUS_IS_OK(status
)) {
2320 d_fprintf(stderr
, "cli_open returned %s\n", cli_errstr(cli1
));
2324 /* Ensure the child has the lock. */
2325 if (cli_lock(cli1
, fnum
, 0, 4, 0, WRITE_LOCK
)) {
2326 d_fprintf(stderr
, "Got the lock on range 0:4 - this should not happen !\n");
2329 d_printf("Child has the lock.\n");
2332 /* Tell the child to wait 5 seconds then exit. */
2333 ret
= write(pipe_out
[1], &c
, 1);
2335 d_fprintf(stderr
, "failed to send exit signal to child. %s\n",
2340 /* Wait 20 seconds for the lock. */
2341 alarm_fd
= cli1
->fd
;
2342 CatchSignal(SIGALRM
, alarm_handler_parent
);
2345 start
= timeval_current();
2347 if (!cli_lock(cli1
, fnum
, 0, 4, -1, WRITE_LOCK
)) {
2348 d_fprintf(stderr
, "Unable to apply write lock on range 0:4, error was "
2349 "%s\n", cli_errstr(cli1
));
2354 seconds
= timeval_elapsed(&start
);
2356 printf("Parent got the lock after %.2f seconds.\n",
2359 status
= cli_close(cli1
, fnum
);
2360 if (!NT_STATUS_IS_OK(status
)) {
2361 d_fprintf(stderr
, "cli_close(fnum1) %s\n", cli_errstr(cli1
));
2368 cli_close(cli1
, fnum
);
2369 torture_close_connection(cli1
);
2373 printf("finished locktest9\n");
2378 test whether fnums and tids open on one VC are available on another (a major
2381 static bool run_fdpasstest(int dummy
)
2383 struct cli_state
*cli1
, *cli2
;
2384 const char *fname
= "\\fdpass.tst";
2388 if (!torture_open_connection(&cli1
, 0) || !torture_open_connection(&cli2
, 1)) {
2391 cli_sockopt(cli1
, sockops
);
2392 cli_sockopt(cli2
, sockops
);
2394 printf("starting fdpasstest\n");
2396 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2398 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2399 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
2403 if (cli_write(cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2404 printf("write failed (%s)\n", cli_errstr(cli1
));
2408 cli2
->vuid
= cli1
->vuid
;
2409 cli2
->cnum
= cli1
->cnum
;
2410 cli2
->pid
= cli1
->pid
;
2412 if (cli_read(cli2
, fnum1
, buf
, 0, 13) == 13) {
2413 printf("read succeeded! nasty security hole [%s]\n",
2418 cli_close(cli1
, fnum1
);
2419 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
2421 torture_close_connection(cli1
);
2422 torture_close_connection(cli2
);
2424 printf("finished fdpasstest\n");
2428 static bool run_fdsesstest(int dummy
)
2430 struct cli_state
*cli
;
2435 const char *fname
= "\\fdsess.tst";
2436 const char *fname1
= "\\fdsess1.tst";
2442 if (!torture_open_connection(&cli
, 0))
2444 cli_sockopt(cli
, sockops
);
2446 if (!torture_cli_session_setup2(cli
, &new_vuid
))
2449 saved_cnum
= cli
->cnum
;
2450 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli
, share
, "?????", "", 1)))
2452 new_cnum
= cli
->cnum
;
2453 cli
->cnum
= saved_cnum
;
2455 printf("starting fdsesstest\n");
2457 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2458 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2460 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
2461 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2465 if (cli_write(cli
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
2466 printf("write failed (%s)\n", cli_errstr(cli
));
2470 saved_vuid
= cli
->vuid
;
2471 cli
->vuid
= new_vuid
;
2473 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2474 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2478 /* Try to open a file with different vuid, samba cnum. */
2479 if (NT_STATUS_IS_OK(cli_open(cli
, fname1
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum2
))) {
2480 printf("create with different vuid, same cnum succeeded.\n");
2481 cli_close(cli
, fnum2
);
2482 cli_unlink(cli
, fname1
, aSYSTEM
| aHIDDEN
);
2484 printf("create with different vuid, same cnum failed.\n");
2485 printf("This will cause problems with service clients.\n");
2489 cli
->vuid
= saved_vuid
;
2491 /* Try with same vuid, different cnum. */
2492 cli
->cnum
= new_cnum
;
2494 if (cli_read(cli
, fnum1
, buf
, 0, 13) == 13) {
2495 printf("read succeeded with different cnum![%s]\n",
2500 cli
->cnum
= saved_cnum
;
2501 cli_close(cli
, fnum1
);
2502 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2504 torture_close_connection(cli
);
2506 printf("finished fdsesstest\n");
2511 This test checks that
2513 1) the server does not allow an unlink on a file that is open
2515 static bool run_unlinktest(int dummy
)
2517 struct cli_state
*cli
;
2518 const char *fname
= "\\unlink.tst";
2520 bool correct
= True
;
2522 if (!torture_open_connection(&cli
, 0)) {
2526 cli_sockopt(cli
, sockops
);
2528 printf("starting unlink test\n");
2530 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2534 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
2535 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2539 if (NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2540 printf("error: server allowed unlink on an open file\n");
2543 correct
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadshare
,
2544 NT_STATUS_SHARING_VIOLATION
);
2547 cli_close(cli
, fnum
);
2548 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2550 if (!torture_close_connection(cli
)) {
2554 printf("unlink test finished\n");
2561 test how many open files this server supports on the one socket
2563 static bool run_maxfidtest(int dummy
)
2565 struct cli_state
*cli
;
2566 const char *ftemplate
= "\\maxfid.%d.%d";
2568 uint16_t fnums
[0x11000];
2571 bool correct
= True
;
2576 printf("failed to connect\n");
2580 cli_sockopt(cli
, sockops
);
2582 for (i
=0; i
<0x11000; i
++) {
2583 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2584 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2585 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
, &fnums
[i
]))) {
2586 printf("open of %s failed (%s)\n",
2587 fname
, cli_errstr(cli
));
2588 printf("maximum fnum is %d\n", i
);
2596 printf("cleaning up\n");
2598 slprintf(fname
,sizeof(fname
)-1,ftemplate
, i
,(int)getpid());
2599 cli_close(cli
, fnums
[i
]);
2600 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
2601 printf("unlink of %s failed (%s)\n",
2602 fname
, cli_errstr(cli
));
2609 printf("maxfid test finished\n");
2610 if (!torture_close_connection(cli
)) {
2616 /* generate a random buffer */
2617 static void rand_buf(char *buf
, int len
)
2620 *buf
= (char)sys_random();
2625 /* send smb negprot commands, not reading the response */
2626 static bool run_negprot_nowait(int dummy
)
2629 static struct cli_state
*cli
;
2630 bool correct
= True
;
2632 printf("starting negprot nowait test\n");
2634 if (!(cli
= open_nbt_connection())) {
2638 for (i
=0;i
<50000;i
++) {
2639 cli_negprot_sendsync(cli
);
2642 if (!torture_close_connection(cli
)) {
2646 printf("finished negprot nowait test\n");
2652 /* send random IPC commands */
2653 static bool run_randomipc(int dummy
)
2655 char *rparam
= NULL
;
2657 unsigned int rdrcnt
,rprcnt
;
2659 int api
, param_len
, i
;
2660 struct cli_state
*cli
;
2661 bool correct
= True
;
2664 printf("starting random ipc test\n");
2666 if (!torture_open_connection(&cli
, 0)) {
2670 for (i
=0;i
<count
;i
++) {
2671 api
= sys_random() % 500;
2672 param_len
= (sys_random() % 64);
2674 rand_buf(param
, param_len
);
2679 param
, param_len
, 8,
2680 NULL
, 0, BUFFER_SIZE
,
2684 printf("%d/%d\r", i
,count
);
2687 printf("%d/%d\n", i
, count
);
2689 if (!torture_close_connection(cli
)) {
2693 printf("finished random ipc test\n");
2700 static void browse_callback(const char *sname
, uint32 stype
,
2701 const char *comment
, void *state
)
2703 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
2709 This test checks the browse list code
2712 static bool run_browsetest(int dummy
)
2714 static struct cli_state
*cli
;
2715 bool correct
= True
;
2717 printf("starting browse test\n");
2719 if (!torture_open_connection(&cli
, 0)) {
2723 printf("domain list:\n");
2724 cli_NetServerEnum(cli
, cli
->server_domain
,
2725 SV_TYPE_DOMAIN_ENUM
,
2726 browse_callback
, NULL
);
2728 printf("machine list:\n");
2729 cli_NetServerEnum(cli
, cli
->server_domain
,
2731 browse_callback
, NULL
);
2733 if (!torture_close_connection(cli
)) {
2737 printf("browse test finished\n");
2745 This checks how the getatr calls works
2747 static bool run_attrtest(int dummy
)
2749 struct cli_state
*cli
;
2752 const char *fname
= "\\attrib123456789.tst";
2753 bool correct
= True
;
2755 printf("starting attrib test\n");
2757 if (!torture_open_connection(&cli
, 0)) {
2761 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2762 cli_open(cli
, fname
,
2763 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2764 cli_close(cli
, fnum
);
2765 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2766 printf("getatr failed (%s)\n", cli_errstr(cli
));
2770 if (abs(t
- time(NULL
)) > 60*60*24*10) {
2771 printf("ERROR: SMBgetatr bug. time is %s",
2777 t2
= t
-60*60*24; /* 1 day ago */
2779 if (!NT_STATUS_IS_OK(cli_setatr(cli
, fname
, 0, t2
))) {
2780 printf("setatr failed (%s)\n", cli_errstr(cli
));
2784 if (!NT_STATUS_IS_OK(cli_getatr(cli
, fname
, NULL
, NULL
, &t
))) {
2785 printf("getatr failed (%s)\n", cli_errstr(cli
));
2790 printf("ERROR: getatr/setatr bug. times are\n%s",
2792 printf("%s", ctime(&t2
));
2796 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2798 if (!torture_close_connection(cli
)) {
2802 printf("attrib test finished\n");
2809 This checks a couple of trans2 calls
2811 static bool run_trans2test(int dummy
)
2813 struct cli_state
*cli
;
2816 time_t c_time
, a_time
, m_time
;
2817 struct timespec c_time_ts
, a_time_ts
, m_time_ts
, w_time_ts
, m_time2_ts
;
2818 const char *fname
= "\\trans2.tst";
2819 const char *dname
= "\\trans2";
2820 const char *fname2
= "\\trans2\\trans2.tst";
2822 bool correct
= True
;
2826 printf("starting trans2 test\n");
2828 if (!torture_open_connection(&cli
, 0)) {
2832 status
= cli_get_fs_attr_info(cli
, &fs_attr
);
2833 if (!NT_STATUS_IS_OK(status
)) {
2834 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2839 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2840 cli_open(cli
, fname
,
2841 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2842 if (!cli_qfileinfo(cli
, fnum
, NULL
, &size
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2843 &m_time_ts
, NULL
)) {
2844 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli
));
2848 if (!cli_qfilename(cli
, fnum
, pname
, sizeof(pname
))) {
2849 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli
));
2853 if (strcmp(pname
, fname
)) {
2854 printf("qfilename gave different name? [%s] [%s]\n",
2859 cli_close(cli
, fnum
);
2863 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2864 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
,
2865 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
))) {
2866 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
2869 cli_close(cli
, fnum
);
2871 if (!cli_qpathinfo(cli
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
)) {
2872 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli
));
2875 if (c_time
!= m_time
) {
2876 printf("create time=%s", ctime(&c_time
));
2877 printf("modify time=%s", ctime(&m_time
));
2878 printf("This system appears to have sticky create times\n");
2880 if (a_time
% (60*60) == 0) {
2881 printf("access time=%s", ctime(&a_time
));
2882 printf("This system appears to set a midnight access time\n");
2886 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
2887 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time
));
2893 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2894 cli_open(cli
, fname
,
2895 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2896 cli_close(cli
, fnum
);
2897 if (!cli_qpathinfo2(cli
, fname
, &c_time_ts
, &a_time_ts
, &w_time_ts
,
2898 &m_time_ts
, &size
, NULL
, NULL
)) {
2899 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2902 if (w_time_ts
.tv_sec
< 60*60*24*2) {
2903 printf("write time=%s", ctime(&w_time_ts
.tv_sec
));
2904 printf("This system appears to set a initial 0 write time\n");
2909 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
2912 /* check if the server updates the directory modification time
2913 when creating a new file */
2914 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, dname
))) {
2915 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli
));
2919 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2920 &m_time_ts
, &size
, NULL
, NULL
)) {
2921 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2925 cli_open(cli
, fname2
,
2926 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
, &fnum
);
2927 cli_write(cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
2928 cli_close(cli
, fnum
);
2929 if (!cli_qpathinfo2(cli
, "\\trans2\\", &c_time_ts
, &a_time_ts
, &w_time_ts
,
2930 &m_time2_ts
, &size
, NULL
, NULL
)) {
2931 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli
));
2934 if (memcmp(&m_time_ts
, &m_time2_ts
, sizeof(struct timespec
))
2936 printf("This system does not update directory modification times\n");
2940 cli_unlink(cli
, fname2
, aSYSTEM
| aHIDDEN
);
2941 cli_rmdir(cli
, dname
);
2943 if (!torture_close_connection(cli
)) {
2947 printf("trans2 test finished\n");
2953 This checks new W2K calls.
2956 static bool new_trans(struct cli_state
*pcli
, int fnum
, int level
)
2960 bool correct
= True
;
2962 if (!cli_qfileinfo_test(pcli
, fnum
, level
, &buf
, &len
)) {
2963 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
, cli_errstr(pcli
));
2966 printf("qfileinfo: level %d, len = %u\n", level
, len
);
2967 dump_data(0, (uint8
*)buf
, len
);
2974 static bool run_w2ktest(int dummy
)
2976 struct cli_state
*cli
;
2978 const char *fname
= "\\w2ktest\\w2k.tst";
2980 bool correct
= True
;
2982 printf("starting w2k test\n");
2984 if (!torture_open_connection(&cli
, 0)) {
2988 cli_open(cli
, fname
,
2989 O_RDWR
| O_CREAT
, DENY_NONE
, &fnum
);
2991 for (level
= 1004; level
< 1040; level
++) {
2992 new_trans(cli
, fnum
, level
);
2995 cli_close(cli
, fnum
);
2997 if (!torture_close_connection(cli
)) {
3001 printf("w2k test finished\n");
3008 this is a harness for some oplock tests
3010 static bool run_oplock1(int dummy
)
3012 struct cli_state
*cli1
;
3013 const char *fname
= "\\lockt1.lck";
3015 bool correct
= True
;
3017 printf("starting oplock test 1\n");
3019 if (!torture_open_connection(&cli1
, 0)) {
3023 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3025 cli_sockopt(cli1
, sockops
);
3027 cli1
->use_oplocks
= True
;
3029 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3030 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3034 cli1
->use_oplocks
= False
;
3036 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3037 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3039 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3040 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3044 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3045 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3049 if (!torture_close_connection(cli1
)) {
3053 printf("finished oplock test 1\n");
3058 static bool run_oplock2(int dummy
)
3060 struct cli_state
*cli1
, *cli2
;
3061 const char *fname
= "\\lockt2.lck";
3062 uint16_t fnum1
, fnum2
;
3063 int saved_use_oplocks
= use_oplocks
;
3065 bool correct
= True
;
3066 volatile bool *shared_correct
;
3068 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3069 *shared_correct
= True
;
3071 use_level_II_oplocks
= True
;
3074 printf("starting oplock test 2\n");
3076 if (!torture_open_connection(&cli1
, 0)) {
3077 use_level_II_oplocks
= False
;
3078 use_oplocks
= saved_use_oplocks
;
3082 cli1
->use_oplocks
= True
;
3083 cli1
->use_level_II_oplocks
= True
;
3085 if (!torture_open_connection(&cli2
, 1)) {
3086 use_level_II_oplocks
= False
;
3087 use_oplocks
= saved_use_oplocks
;
3091 cli2
->use_oplocks
= True
;
3092 cli2
->use_level_II_oplocks
= True
;
3094 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3096 cli_sockopt(cli1
, sockops
);
3097 cli_sockopt(cli2
, sockops
);
3099 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
3100 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3104 /* Don't need the globals any more. */
3105 use_level_II_oplocks
= False
;
3106 use_oplocks
= saved_use_oplocks
;
3110 if (!NT_STATUS_IS_OK(cli_open(cli2
, fname
, O_RDWR
, DENY_NONE
, &fnum2
))) {
3111 printf("second open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3112 *shared_correct
= False
;
3118 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3119 printf("close2 failed (%s)\n", cli_errstr(cli1
));
3120 *shared_correct
= False
;
3128 /* Ensure cli1 processes the break. Empty file should always return 0
3131 if (cli_read(cli1
, fnum1
, buf
, 0, 4) != 0) {
3132 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1
));
3136 /* Should now be at level II. */
3137 /* Test if sending a write locks causes a break to none. */
3139 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3140 printf("lock failed (%s)\n", cli_errstr(cli1
));
3144 cli_unlock(cli1
, fnum1
, 0, 4);
3148 if (!cli_lock(cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3149 printf("lock failed (%s)\n", cli_errstr(cli1
));
3153 cli_unlock(cli1
, fnum1
, 0, 4);
3157 cli_read(cli1
, fnum1
, buf
, 0, 4);
3160 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3161 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1
));
3166 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3167 printf("close1 failed (%s)\n", cli_errstr(cli1
));
3173 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
))) {
3174 printf("unlink failed (%s)\n", cli_errstr(cli1
));
3178 if (!torture_close_connection(cli1
)) {
3182 if (!*shared_correct
) {
3186 printf("finished oplock test 2\n");
3191 /* handler for oplock 3 tests */
3192 static NTSTATUS
oplock3_handler(struct cli_state
*cli
, uint16_t fnum
, unsigned char level
)
3194 printf("got oplock break fnum=%d level=%d\n",
3196 return cli_oplock_ack(cli
, fnum
, level
);
3199 static bool run_oplock3(int dummy
)
3201 struct cli_state
*cli
;
3202 const char *fname
= "\\oplockt3.dat";
3204 char buf
[4] = "abcd";
3205 bool correct
= True
;
3206 volatile bool *shared_correct
;
3208 shared_correct
= (volatile bool *)shm_setup(sizeof(bool));
3209 *shared_correct
= True
;
3211 printf("starting oplock test 3\n");
3216 use_level_II_oplocks
= True
;
3217 if (!torture_open_connection(&cli
, 0)) {
3218 *shared_correct
= False
;
3222 /* try to trigger a oplock break in parent */
3223 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3224 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3230 use_level_II_oplocks
= True
;
3231 if (!torture_open_connection(&cli
, 1)) { /* other is forked */
3234 cli_oplock_handler(cli
, oplock3_handler
);
3235 cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
);
3236 cli_write(cli
, fnum
, 0, buf
, 0, 4);
3237 cli_close(cli
, fnum
);
3238 cli_open(cli
, fname
, O_RDWR
, DENY_NONE
, &fnum
);
3239 cli
->timeout
= 20000;
3240 cli_receive_smb(cli
);
3241 printf("finished oplock test 3\n");
3243 return (correct
&& *shared_correct
);
3245 /* What are we looking for here? What's sucess and what's FAILURE? */
3251 Test delete on close semantics.
3253 static bool run_deletetest(int dummy
)
3255 struct cli_state
*cli1
= NULL
;
3256 struct cli_state
*cli2
= NULL
;
3257 const char *fname
= "\\delete.file";
3258 uint16_t fnum1
= (uint16_t)-1;
3259 uint16_t fnum2
= (uint16_t)-1;
3260 bool correct
= True
;
3262 printf("starting delete test\n");
3264 if (!torture_open_connection(&cli1
, 0)) {
3268 cli_sockopt(cli1
, sockops
);
3270 /* Test 1 - this should delete the file on close. */
3272 cli_setatr(cli1
, fname
, 0, 0);
3273 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3275 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3276 0, FILE_OVERWRITE_IF
,
3277 FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3278 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3285 uint32
*accinfo
= NULL
;
3287 cli_qfileinfo_test(cli1
, fnum1
, SMB_FILE_ACCESS_INFORMATION
, (char **)&accinfo
, &len
);
3289 printf("access mode = 0x%lx\n", *accinfo
);
3294 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3295 printf("[1] close failed (%s)\n", cli_errstr(cli1
));
3300 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
, DENY_NONE
, &fnum1
))) {
3301 printf("[1] open of %s succeeded (should fail)\n", fname
);
3306 printf("first delete on close test succeeded.\n");
3308 /* Test 2 - this should delete the file on close. */
3310 cli_setatr(cli1
, fname
, 0, 0);
3311 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3313 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
,
3314 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
,
3315 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3316 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3321 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3322 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3327 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3328 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3333 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3334 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3335 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3336 printf("[2] close failed (%s)\n", cli_errstr(cli1
));
3340 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3342 printf("second delete on close test succeeded.\n");
3345 cli_setatr(cli1
, fname
, 0, 0);
3346 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3348 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3349 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3350 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3355 /* This should fail with a sharing violation - open for delete is only compatible
3356 with SHARE_DELETE. */
3358 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3359 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3360 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
3365 /* This should succeed. */
3367 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3368 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3369 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3374 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3375 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3380 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3381 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1
));
3386 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3387 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1
));
3392 /* This should fail - file should no longer be there. */
3394 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3395 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
3396 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3397 printf("[3] close failed (%s)\n", cli_errstr(cli1
));
3399 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3403 printf("third delete on close test succeeded.\n");
3406 cli_setatr(cli1
, fname
, 0, 0);
3407 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3409 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3410 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3411 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3416 /* This should succeed. */
3417 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3418 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0, 0, &fnum2
))) {
3419 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3424 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3425 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1
));
3430 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3431 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1
));
3436 /* This should fail - no more opens once delete on close set. */
3437 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
,
3438 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3439 FILE_OPEN
, 0, 0, &fnum2
))) {
3440 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
3444 printf("fourth delete on close test succeeded.\n");
3446 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3447 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1
));
3453 cli_setatr(cli1
, fname
, 0, 0);
3454 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3456 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum1
))) {
3457 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3462 /* This should fail - only allowed on NT opens with DELETE access. */
3464 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3465 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3470 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3471 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1
));
3476 printf("fifth delete on close test succeeded.\n");
3479 cli_setatr(cli1
, fname
, 0, 0);
3480 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3482 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3483 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3484 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3485 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3490 /* This should fail - only allowed on NT opens with DELETE access. */
3492 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3493 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3498 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3499 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1
));
3504 printf("sixth delete on close test succeeded.\n");
3507 cli_setatr(cli1
, fname
, 0, 0);
3508 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3510 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3511 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3512 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3517 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3518 printf("[7] setting delete_on_close on file failed !\n");
3523 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, false))) {
3524 printf("[7] unsetting delete_on_close on file failed !\n");
3529 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3530 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3535 /* This next open should succeed - we reset the flag. */
3537 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3538 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3543 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3544 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1
));
3549 printf("seventh delete on close test succeeded.\n");
3552 cli_setatr(cli1
, fname
, 0, 0);
3553 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3555 if (!torture_open_connection(&cli2
, 1)) {
3556 printf("[8] failed to open second connection.\n");
3561 cli_sockopt(cli1
, sockops
);
3563 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3564 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3565 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3566 printf("[8] open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3571 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3572 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3573 FILE_OPEN
, 0, 0, &fnum2
))) {
3574 printf("[8] open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
3579 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum1
, true))) {
3580 printf("[8] setting delete_on_close on file failed !\n");
3585 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3586 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1
));
3591 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
3592 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2
));
3597 /* This should fail.. */
3598 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3599 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
3603 printf("eighth delete on close test succeeded.\n");
3605 /* This should fail - we need to set DELETE_ACCESS. */
3606 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,FILE_READ_DATA
|FILE_WRITE_DATA
,
3607 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3608 printf("[9] open of %s succeeded should have failed!\n", fname
);
3613 printf("ninth delete on close test succeeded.\n");
3615 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
3616 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, FILE_DELETE_ON_CLOSE
, 0, &fnum1
))) {
3617 printf("[10] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3622 /* This should delete the file. */
3623 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3624 printf("[10] close failed (%s)\n", cli_errstr(cli1
));
3629 /* This should fail.. */
3630 if (NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_NONE
, &fnum1
))) {
3631 printf("[10] open of %s succeeded should have been deleted on close !\n", fname
);
3635 printf("tenth delete on close test succeeded.\n");
3637 cli_setatr(cli1
, fname
, 0, 0);
3638 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3640 /* What error do we get when attempting to open a read-only file with
3643 /* Create a readonly file. */
3644 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
,
3645 FILE_ATTRIBUTE_READONLY
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3646 printf("[11] open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
3651 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3652 printf("[11] close failed (%s)\n", cli_errstr(cli1
));
3657 /* Now try open for delete access. */
3658 if (NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
|DELETE_ACCESS
,
3659 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
3660 FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3661 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname
);
3662 cli_close(cli1
, fnum1
);
3666 NTSTATUS nterr
= cli_nt_error(cli1
);
3667 if (!NT_STATUS_EQUAL(nterr
,NT_STATUS_ACCESS_DENIED
)) {
3668 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname
, nt_errstr(nterr
));
3672 printf("eleventh delete on close test succeeded.\n");
3676 printf("finished delete test\n");
3679 /* FIXME: This will crash if we aborted before cli2 got
3680 * intialized, because these functions don't handle
3681 * uninitialized connections. */
3683 if (fnum1
!= (uint16_t)-1) cli_close(cli1
, fnum1
);
3684 if (fnum2
!= (uint16_t)-1) cli_close(cli1
, fnum2
);
3685 cli_setatr(cli1
, fname
, 0, 0);
3686 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3688 if (cli1
&& !torture_close_connection(cli1
)) {
3691 if (cli2
&& !torture_close_connection(cli2
)) {
3699 print out server properties
3701 static bool run_properties(int dummy
)
3703 struct cli_state
*cli
;
3704 bool correct
= True
;
3706 printf("starting properties test\n");
3710 if (!torture_open_connection(&cli
, 0)) {
3714 cli_sockopt(cli
, sockops
);
3716 d_printf("Capabilities 0x%08x\n", cli
->capabilities
);
3718 if (!torture_close_connection(cli
)) {
3727 /* FIRST_DESIRED_ACCESS 0xf019f */
3728 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3729 FILE_READ_EA| /* 0xf */ \
3730 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3731 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3732 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3733 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3734 /* SECOND_DESIRED_ACCESS 0xe0080 */
3735 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3736 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3737 WRITE_OWNER_ACCESS /* 0xe0000 */
3740 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3741 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3743 WRITE_OWNER_ACCESS /* */
3747 Test ntcreate calls made by xcopy
3749 static bool run_xcopy(int dummy
)
3751 static struct cli_state
*cli1
;
3752 const char *fname
= "\\test.txt";
3753 bool correct
= True
;
3754 uint16_t fnum1
, fnum2
;
3756 printf("starting xcopy test\n");
3758 if (!torture_open_connection(&cli1
, 0)) {
3762 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3763 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
3764 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
3765 0x4044, 0, &fnum1
))) {
3766 printf("First open failed - %s\n", cli_errstr(cli1
));
3770 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0,
3771 SECOND_DESIRED_ACCESS
, 0,
3772 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
3773 0x200000, 0, &fnum2
))) {
3774 printf("second open failed - %s\n", cli_errstr(cli1
));
3778 if (!torture_close_connection(cli1
)) {
3786 Test rename on files open with share delete and no share delete.
3788 static bool run_rename(int dummy
)
3790 static struct cli_state
*cli1
;
3791 const char *fname
= "\\test.txt";
3792 const char *fname1
= "\\test1.txt";
3793 bool correct
= True
;
3798 printf("starting rename test\n");
3800 if (!torture_open_connection(&cli1
, 0)) {
3804 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3805 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3806 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3807 FILE_SHARE_READ
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3808 printf("First open failed - %s\n", cli_errstr(cli1
));
3812 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3813 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1
));
3815 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3819 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3820 printf("close - 1 failed (%s)\n", cli_errstr(cli1
));
3824 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3825 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3826 status
= cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3828 FILE_SHARE_DELETE
|FILE_SHARE_NONE
,
3830 FILE_SHARE_DELETE
|FILE_SHARE_READ
,
3832 FILE_OVERWRITE_IF
, 0, 0, &fnum1
);
3833 if (!NT_STATUS_IS_OK(status
)) {
3834 printf("Second open failed - %s\n", cli_errstr(cli1
));
3838 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3839 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1
));
3842 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3845 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3846 printf("close - 2 failed (%s)\n", cli_errstr(cli1
));
3850 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3851 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3853 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, READ_CONTROL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3854 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3855 printf("Third open failed - %s\n", cli_errstr(cli1
));
3864 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3865 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum2
))) {
3866 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3869 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1
, fnum2
, true))) {
3870 printf("[8] setting delete_on_close on file failed !\n");
3874 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum2
))) {
3875 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3881 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3882 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1
));
3885 printf("Third rename succeeded (SHARE_NONE)\n");
3888 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3889 printf("close - 3 failed (%s)\n", cli_errstr(cli1
));
3893 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3894 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3898 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3899 FILE_SHARE_READ
| FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3900 printf("Fourth open failed - %s\n", cli_errstr(cli1
));
3904 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3905 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1
));
3907 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3911 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3912 printf("close - 4 failed (%s)\n", cli_errstr(cli1
));
3916 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3917 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3921 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3922 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
3923 printf("Fifth open failed - %s\n", cli_errstr(cli1
));
3927 if (!NT_STATUS_IS_OK(cli_rename(cli1
, fname
, fname1
))) {
3928 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3932 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1
));
3936 * Now check if the first name still exists ...
3939 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3940 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3941 printf("Opening original file after rename of open file fails: %s\n",
3945 printf("Opening original file after rename of open file works ...\n");
3946 (void)cli_close(cli1, fnum2);
3950 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
3951 printf("close - 5 failed (%s)\n", cli_errstr(cli1
));
3955 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3956 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname1
, &attr
, NULL
, NULL
))) {
3957 printf("getatr on file %s failed - %s ! \n",
3962 if (attr
!= FILE_ATTRIBUTE_ARCHIVE
) {
3963 printf("Renamed file %s has wrong attr 0x%x "
3964 "(should be 0x%x)\n",
3967 (unsigned int)FILE_ATTRIBUTE_ARCHIVE
);
3970 printf("Renamed file %s has archive bit set\n", fname1
);
3974 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
3975 cli_unlink(cli1
, fname1
, aSYSTEM
| aHIDDEN
);
3977 if (!torture_close_connection(cli1
)) {
3984 static bool run_pipe_number(int dummy
)
3986 struct cli_state
*cli1
;
3987 const char *pipe_name
= "\\SPOOLSS";
3991 printf("starting pipenumber test\n");
3992 if (!torture_open_connection(&cli1
, 0)) {
3996 cli_sockopt(cli1
, sockops
);
3998 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, pipe_name
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
3999 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN_IF
, 0, 0, &fnum
))) {
4000 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, cli_errstr(cli1
));
4004 printf("\r%6d", num_pipes
);
4007 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
4008 torture_close_connection(cli1
);
4013 Test open mode returns on read-only files.
4015 static bool run_opentest(int dummy
)
4017 static struct cli_state
*cli1
;
4018 static struct cli_state
*cli2
;
4019 const char *fname
= "\\readonly.file";
4020 uint16_t fnum1
, fnum2
;
4023 bool correct
= True
;
4026 printf("starting open test\n");
4028 if (!torture_open_connection(&cli1
, 0)) {
4032 cli_setatr(cli1
, fname
, 0, 0);
4033 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4035 cli_sockopt(cli1
, sockops
);
4037 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4038 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4042 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4043 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4047 if (!NT_STATUS_IS_OK(cli_setatr(cli1
, fname
, aRONLY
, 0))) {
4048 printf("cli_setatr failed (%s)\n", cli_errstr(cli1
));
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 ERRnoaccess, not ERRbadshare. */
4058 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4060 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRnoaccess
,
4061 NT_STATUS_ACCESS_DENIED
)) {
4062 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4065 printf("finished open test 1\n");
4067 cli_close(cli1
, fnum1
);
4069 /* Now try not readonly and ensure ERRbadshare is returned. */
4071 cli_setatr(cli1
, fname
, 0, 0);
4073 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
, DENY_WRITE
, &fnum1
))) {
4074 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4078 /* This will fail - but the error should be ERRshare. */
4079 cli_open(cli1
, fname
, O_RDWR
, DENY_ALL
, &fnum2
);
4081 if (check_error(__LINE__
, cli1
, ERRDOS
, ERRbadshare
,
4082 NT_STATUS_SHARING_VIOLATION
)) {
4083 printf("correct error code ERRDOS/ERRbadshare returned\n");
4086 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4087 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4091 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4093 printf("finished open test 2\n");
4095 /* Test truncate open disposition on file opened for read. */
4097 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum1
))) {
4098 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4102 /* write 20 bytes. */
4104 memset(buf
, '\0', 20);
4106 if (cli_write(cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4107 printf("write failed (%s)\n", cli_errstr(cli1
));
4111 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4112 printf("(3) close1 failed (%s)\n", cli_errstr(cli1
));
4116 /* Ensure size == 20. */
4117 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4118 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4123 printf("(3) file size != 20\n");
4127 /* Now test if we can truncate a file opened for readonly. */
4129 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
, &fnum1
))) {
4130 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4134 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4135 printf("close2 failed (%s)\n", cli_errstr(cli1
));
4139 /* Ensure size == 0. */
4140 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, NULL
, &fsize
, NULL
))) {
4141 printf("(3) getatr failed (%s)\n", cli_errstr(cli1
));
4146 printf("(3) file size != 0\n");
4149 printf("finished open test 3\n");
4151 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4154 printf("testing ctemp\n");
4155 if (!NT_STATUS_IS_OK(cli_ctemp(cli1
, talloc_tos(), "\\", &fnum1
, &tmp_path
))) {
4156 printf("ctemp failed (%s)\n", cli_errstr(cli1
));
4159 printf("ctemp gave path %s\n", tmp_path
);
4160 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4161 printf("close of temp failed (%s)\n", cli_errstr(cli1
));
4163 if (!NT_STATUS_IS_OK(cli_unlink(cli1
, tmp_path
, aSYSTEM
| aHIDDEN
))) {
4164 printf("unlink of temp failed (%s)\n", cli_errstr(cli1
));
4167 /* Test the non-io opens... */
4169 if (!torture_open_connection(&cli2
, 1)) {
4173 cli_setatr(cli2
, fname
, 0, 0);
4174 cli_unlink(cli2
, fname
, aSYSTEM
| aHIDDEN
);
4176 cli_sockopt(cli2
, sockops
);
4178 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4180 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4181 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4182 printf("test 1 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4186 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4187 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4188 printf("test 1 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4192 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4193 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4196 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4197 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4201 printf("non-io open test #1 passed.\n");
4203 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4205 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4207 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4208 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4209 printf("test 2 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4213 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4214 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4215 printf("test 2 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4219 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4220 printf("test 1 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4223 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4224 printf("test 1 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4228 printf("non-io open test #2 passed.\n");
4230 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4232 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4234 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4235 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4236 printf("test 3 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4240 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4241 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4242 printf("test 3 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4246 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4247 printf("test 3 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4250 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4251 printf("test 3 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4255 printf("non-io open test #3 passed.\n");
4257 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4259 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4261 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4262 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4263 printf("test 4 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4267 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4268 FILE_SHARE_NONE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4269 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4273 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4275 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4276 printf("test 4 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4280 printf("non-io open test #4 passed.\n");
4282 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4284 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4286 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4287 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4288 printf("test 5 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4293 FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4294 printf("test 5 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4298 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4299 printf("test 5 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4303 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4304 printf("test 5 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4308 printf("non-io open test #5 passed.\n");
4310 printf("TEST #6 testing 1 non-io open, one io open\n");
4312 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4314 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4315 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4316 printf("test 6 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4320 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4321 FILE_SHARE_READ
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4322 printf("test 6 open 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4326 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4327 printf("test 6 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4331 if (!NT_STATUS_IS_OK(cli_close(cli2
, fnum2
))) {
4332 printf("test 6 close 2 of %s failed (%s)\n", fname
, cli_errstr(cli2
));
4336 printf("non-io open test #6 passed.\n");
4338 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4340 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4342 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
4343 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4344 printf("test 7 open 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4348 if (NT_STATUS_IS_OK(cli_ntcreate(cli2
, fname
, 0, DELETE_ACCESS
|FILE_READ_ATTRIBUTES
, FILE_ATTRIBUTE_NORMAL
,
4349 FILE_SHARE_READ
|FILE_SHARE_DELETE
, FILE_OPEN_IF
, 0, 0, &fnum2
))) {
4350 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname
, cli_errstr(cli2
));
4354 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname
, cli_errstr(cli2
), "sharing violation");
4356 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4357 printf("test 7 close 1 of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4361 printf("non-io open test #7 passed.\n");
4363 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4365 if (!torture_close_connection(cli1
)) {
4368 if (!torture_close_connection(cli2
)) {
4375 NTSTATUS
torture_setup_unix_extensions(struct cli_state
*cli
)
4377 uint16 major
, minor
;
4378 uint32 caplow
, caphigh
;
4381 if (!SERVER_HAS_UNIX_CIFS(cli
)) {
4382 printf("Server doesn't support UNIX CIFS extensions.\n");
4383 return NT_STATUS_NOT_SUPPORTED
;
4386 status
= cli_unix_extensions_version(cli
, &major
, &minor
, &caplow
,
4388 if (!NT_STATUS_IS_OK(status
)) {
4389 printf("Server didn't return UNIX CIFS extensions: %s\n",
4394 status
= cli_set_unix_extensions_capabilities(cli
, major
, minor
,
4396 if (!NT_STATUS_IS_OK(status
)) {
4397 printf("Server doesn't support setting UNIX CIFS extensions: "
4398 "%s.\n", nt_errstr(status
));
4402 return NT_STATUS_OK
;
4406 Test POSIX open /mkdir calls.
4408 static bool run_simple_posix_open_test(int dummy
)
4410 static struct cli_state
*cli1
;
4411 const char *fname
= "posix:file";
4412 const char *hname
= "posix:hlink";
4413 const char *sname
= "posix:symlink";
4414 const char *dname
= "posix:dir";
4417 uint16_t fnum1
= (uint16_t)-1;
4418 SMB_STRUCT_STAT sbuf
;
4419 bool correct
= false;
4422 printf("Starting simple POSIX open test\n");
4424 if (!torture_open_connection(&cli1
, 0)) {
4428 cli_sockopt(cli1
, sockops
);
4430 status
= torture_setup_unix_extensions(cli1
);
4431 if (!NT_STATUS_IS_OK(status
)) {
4435 cli_setatr(cli1
, fname
, 0, 0);
4436 cli_posix_unlink(cli1
, fname
);
4437 cli_setatr(cli1
, dname
, 0, 0);
4438 cli_posix_rmdir(cli1
, dname
);
4439 cli_setatr(cli1
, hname
, 0, 0);
4440 cli_posix_unlink(cli1
, hname
);
4441 cli_setatr(cli1
, sname
, 0, 0);
4442 cli_posix_unlink(cli1
, sname
);
4444 /* Create a directory. */
4445 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1
, dname
, 0777))) {
4446 printf("POSIX mkdir of %s failed (%s)\n", dname
, cli_errstr(cli1
));
4450 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4451 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4455 /* Test ftruncate - set file size. */
4456 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 1000))) {
4457 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4461 /* Ensure st_size == 1000 */
4462 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1
, fname
, &sbuf
))) {
4463 printf("stat failed (%s)\n", cli_errstr(cli1
));
4467 if (sbuf
.st_ex_size
!= 1000) {
4468 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf
.st_ex_size
);
4472 /* Test ftruncate - set file size back to zero. */
4473 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1
, fnum1
, 0))) {
4474 printf("ftruncate failed (%s)\n", cli_errstr(cli1
));
4478 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4479 printf("close failed (%s)\n", cli_errstr(cli1
));
4483 /* Now open the file again for read only. */
4484 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4485 printf("POSIX open of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4489 /* Now unlink while open. */
4490 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1
, fname
))) {
4491 printf("POSIX unlink of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4495 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4496 printf("close(2) failed (%s)\n", cli_errstr(cli1
));
4500 /* Ensure the file has gone. */
4501 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDONLY
, 0, &fnum1
))) {
4502 printf("POSIX open of %s succeeded, should have been deleted.\n", fname
);
4506 /* What happens when we try and POSIX open a directory ? */
4507 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, dname
, O_RDONLY
, 0, &fnum1
))) {
4508 printf("POSIX open of directory %s succeeded, should have failed.\n", fname
);
4511 if (!check_error(__LINE__
, cli1
, ERRDOS
, EISDIR
,
4512 NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4517 /* Create the file. */
4518 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, 0600, &fnum1
))) {
4519 printf("POSIX create of %s failed (%s)\n", fname
, cli_errstr(cli1
));
4523 /* Write some data into it. */
4524 if (cli_write(cli1
, fnum1
, 0, "TEST DATA\n", 0, 10) != 10) {
4525 printf("cli_write failed: %s\n", cli_errstr(cli1
));
4529 cli_close(cli1
, fnum1
);
4531 /* Now create a hardlink. */
4532 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1
, fname
, hname
))) {
4533 printf("POSIX hardlink of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4537 /* Now create a symlink. */
4538 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1
, fname
, sname
))) {
4539 printf("POSIX symlink of %s failed (%s)\n", sname
, cli_errstr(cli1
));
4543 /* Open the hardlink for read. */
4544 if (!NT_STATUS_IS_OK(cli_posix_open(cli1
, hname
, O_RDONLY
, 0, &fnum1
))) {
4545 printf("POSIX open of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4549 if (cli_read(cli1
, fnum1
, buf
, 0, 10) != 10) {
4550 printf("POSIX read of %s failed (%s)\n", hname
, cli_errstr(cli1
));
4554 if (memcmp(buf
, "TEST DATA\n", 10)) {
4555 printf("invalid data read from hardlink\n");
4559 /* Do a POSIX lock/unlock. */
4560 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1
, fnum1
, 0, 100, true, READ_LOCK
))) {
4561 printf("POSIX lock failed %s\n", cli_errstr(cli1
));
4565 /* Punch a hole in the locked area. */
4566 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1
, fnum1
, 10, 80))) {
4567 printf("POSIX unlock failed %s\n", cli_errstr(cli1
));
4571 cli_close(cli1
, fnum1
);
4573 /* Open the symlink for read - this should fail. A POSIX
4574 client should not be doing opens on a symlink. */
4575 if (NT_STATUS_IS_OK(cli_posix_open(cli1
, sname
, O_RDONLY
, 0, &fnum1
))) {
4576 printf("POSIX open of %s succeeded (should have failed)\n", sname
);
4579 if (!check_error(__LINE__
, cli1
, ERRDOS
, ERRbadpath
,
4580 NT_STATUS_OBJECT_PATH_NOT_FOUND
)) {
4581 printf("POSIX open of %s should have failed "
4582 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4583 "failed with %s instead.\n",
4584 sname
, cli_errstr(cli1
));
4589 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1
, sname
, namebuf
, sizeof(namebuf
)))) {
4590 printf("POSIX readlink on %s failed (%s)\n", sname
, cli_errstr(cli1
));
4594 if (strcmp(namebuf
, fname
) != 0) {
4595 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4596 sname
, fname
, namebuf
);
4600 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1
, dname
))) {
4601 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1
));
4605 printf("Simple POSIX open test passed\n");
4610 if (fnum1
!= (uint16_t)-1) {
4611 cli_close(cli1
, fnum1
);
4612 fnum1
= (uint16_t)-1;
4615 cli_setatr(cli1
, sname
, 0, 0);
4616 cli_posix_unlink(cli1
, sname
);
4617 cli_setatr(cli1
, hname
, 0, 0);
4618 cli_posix_unlink(cli1
, hname
);
4619 cli_setatr(cli1
, fname
, 0, 0);
4620 cli_posix_unlink(cli1
, fname
);
4621 cli_setatr(cli1
, dname
, 0, 0);
4622 cli_posix_rmdir(cli1
, dname
);
4624 if (!torture_close_connection(cli1
)) {
4632 static uint32 open_attrs_table
[] = {
4633 FILE_ATTRIBUTE_NORMAL
,
4634 FILE_ATTRIBUTE_ARCHIVE
,
4635 FILE_ATTRIBUTE_READONLY
,
4636 FILE_ATTRIBUTE_HIDDEN
,
4637 FILE_ATTRIBUTE_SYSTEM
,
4639 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
,
4640 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
,
4641 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
,
4642 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4643 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4644 FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4646 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
,
4647 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
,
4648 FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
|FILE_ATTRIBUTE_SYSTEM
,
4649 FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_SYSTEM
,
4652 struct trunc_open_results
{
4659 static struct trunc_open_results attr_results
[] = {
4660 { 0, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4661 { 1, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4662 { 2, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4663 { 16, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_NORMAL
, FILE_ATTRIBUTE_ARCHIVE
},
4664 { 17, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_ARCHIVE
},
4665 { 18, FILE_ATTRIBUTE_ARCHIVE
, FILE_ATTRIBUTE_READONLY
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
},
4666 { 51, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4667 { 54, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4668 { 56, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4669 { 68, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4670 { 71, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4671 { 73, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
},
4672 { 99, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
,FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4673 { 102, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4674 { 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
},
4675 { 116, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4676 { 119, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4677 { 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
},
4678 { 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
},
4679 { 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
},
4680 { 227, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4681 { 230, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_HIDDEN
},
4682 { 232, FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_HIDDEN
},
4683 { 244, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4684 { 247, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_SYSTEM
},
4685 { 249, FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
|FILE_ATTRIBUTE_SYSTEM
}
4688 static bool run_openattrtest(int dummy
)
4690 static struct cli_state
*cli1
;
4691 const char *fname
= "\\openattr.file";
4693 bool correct
= True
;
4695 unsigned int i
, j
, k
, l
;
4697 printf("starting open attr test\n");
4699 if (!torture_open_connection(&cli1
, 0)) {
4703 cli_sockopt(cli1
, sockops
);
4705 for (k
= 0, i
= 0; i
< sizeof(open_attrs_table
)/sizeof(uint32
); i
++) {
4706 cli_setatr(cli1
, fname
, 0, 0);
4707 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4708 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_WRITE_DATA
, open_attrs_table
[i
],
4709 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0, 0, &fnum1
))) {
4710 printf("open %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4714 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4715 printf("close %d (1) of %s failed (%s)\n", i
, fname
, cli_errstr(cli1
));
4719 for (j
= 0; j
< sizeof(open_attrs_table
)/sizeof(uint32
); j
++) {
4720 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1
, fname
, 0, FILE_READ_DATA
|FILE_WRITE_DATA
, open_attrs_table
[j
],
4721 FILE_SHARE_NONE
, FILE_OVERWRITE
, 0, 0, &fnum1
))) {
4722 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4723 if (attr_results
[l
].num
== k
) {
4724 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4725 k
, open_attrs_table
[i
],
4726 open_attrs_table
[j
],
4727 fname
, NT_STATUS_V(cli_nt_error(cli1
)), cli_errstr(cli1
));
4731 if (NT_STATUS_V(cli_nt_error(cli1
)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED
)) {
4732 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4733 k
, open_attrs_table
[i
], open_attrs_table
[j
],
4738 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k
, open_attrs_table
[i
], open_attrs_table
[j
]);
4744 if (!NT_STATUS_IS_OK(cli_close(cli1
, fnum1
))) {
4745 printf("close %d (2) of %s failed (%s)\n", j
, fname
, cli_errstr(cli1
));
4749 if (!NT_STATUS_IS_OK(cli_getatr(cli1
, fname
, &attr
, NULL
, NULL
))) {
4750 printf("getatr(2) failed (%s)\n", cli_errstr(cli1
));
4755 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4756 k
, open_attrs_table
[i
], open_attrs_table
[j
], attr
);
4759 for (l
= 0; l
< sizeof(attr_results
)/sizeof(struct trunc_open_results
); l
++) {
4760 if (attr_results
[l
].num
== k
) {
4761 if (attr
!= attr_results
[l
].result_attr
||
4762 open_attrs_table
[i
] != attr_results
[l
].init_attr
||
4763 open_attrs_table
[j
] != attr_results
[l
].trunc_attr
) {
4764 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4765 open_attrs_table
[i
],
4766 open_attrs_table
[j
],
4768 attr_results
[l
].result_attr
);
4778 cli_setatr(cli1
, fname
, 0, 0);
4779 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
4781 printf("open attr test %s.\n", correct
? "passed" : "failed");
4783 if (!torture_close_connection(cli1
)) {
4789 static void list_fn(const char *mnt
, file_info
*finfo
, const char *name
, void *state
)
4795 test directory listing speed
4797 static bool run_dirtest(int dummy
)
4800 static struct cli_state
*cli
;
4802 struct timeval core_start
;
4803 bool correct
= True
;
4805 printf("starting directory test\n");
4807 if (!torture_open_connection(&cli
, 0)) {
4811 cli_sockopt(cli
, sockops
);
4814 for (i
=0;i
<torture_numops
;i
++) {
4816 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4817 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
, &fnum
))) {
4818 fprintf(stderr
,"Failed to open %s\n", fname
);
4821 cli_close(cli
, fnum
);
4824 core_start
= timeval_current();
4826 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
4827 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
4828 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
4830 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start
));
4833 for (i
=0;i
<torture_numops
;i
++) {
4835 slprintf(fname
, sizeof(fname
), "\\%x", (int)random());
4836 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4839 if (!torture_close_connection(cli
)) {
4843 printf("finished dirtest\n");
4848 static void del_fn(const char *mnt
, file_info
*finfo
, const char *mask
, void *state
)
4850 struct cli_state
*pcli
= (struct cli_state
*)state
;
4852 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\%s", finfo
->name
);
4854 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
4857 if (finfo
->mode
& aDIR
) {
4858 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
4859 printf("del_fn: failed to rmdir %s\n,", fname
);
4861 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
4862 printf("del_fn: failed to unlink %s\n,", fname
);
4868 sees what IOCTLs are supported
4870 bool torture_ioctl_test(int dummy
)
4872 static struct cli_state
*cli
;
4873 uint16_t device
, function
;
4875 const char *fname
= "\\ioctl.dat";
4879 if (!torture_open_connection(&cli
, 0)) {
4883 printf("starting ioctl test\n");
4885 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
4887 if (!NT_STATUS_IS_OK(cli_open(cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4888 printf("open of %s failed (%s)\n", fname
, cli_errstr(cli
));
4892 status
= cli_raw_ioctl(cli
, fnum
, 0x2d0000 | (0x0420<<2), &blob
);
4893 printf("ioctl device info: %s\n", nt_errstr(status
));
4895 status
= cli_raw_ioctl(cli
, fnum
, IOCTL_QUERY_JOB_INFO
, &blob
);
4896 printf("ioctl job info: %s\n", nt_errstr(status
));
4898 for (device
=0;device
<0x100;device
++) {
4899 printf("testing device=0x%x\n", device
);
4900 for (function
=0;function
<0x100;function
++) {
4901 uint32 code
= (device
<<16) | function
;
4903 status
= cli_raw_ioctl(cli
, fnum
, code
, &blob
);
4905 if (NT_STATUS_IS_OK(status
)) {
4906 printf("ioctl 0x%x OK : %d bytes\n", (int)code
,
4908 data_blob_free(&blob
);
4913 if (!torture_close_connection(cli
)) {
4922 tries varients of chkpath
4924 bool torture_chkpath_test(int dummy
)
4926 static struct cli_state
*cli
;
4930 if (!torture_open_connection(&cli
, 0)) {
4934 printf("starting chkpath test\n");
4936 /* cleanup from an old run */
4937 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4938 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
4939 cli_rmdir(cli
, "\\chkpath.dir");
4941 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir"))) {
4942 printf("mkdir1 failed : %s\n", cli_errstr(cli
));
4946 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\chkpath.dir\\dir2"))) {
4947 printf("mkdir2 failed : %s\n", cli_errstr(cli
));
4951 if (!NT_STATUS_IS_OK(cli_open(cli
, "\\chkpath.dir\\foo.txt", O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
4952 printf("open1 failed (%s)\n", cli_errstr(cli
));
4955 cli_close(cli
, fnum
);
4957 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir"))) {
4958 printf("chkpath1 failed: %s\n", cli_errstr(cli
));
4962 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dir2"))) {
4963 printf("chkpath2 failed: %s\n", cli_errstr(cli
));
4967 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\foo.txt"))) {
4968 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4969 NT_STATUS_NOT_A_DIRECTORY
);
4971 printf("* chkpath on a file should fail\n");
4975 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\bar.txt"))) {
4976 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadfile
,
4977 NT_STATUS_OBJECT_NAME_NOT_FOUND
);
4979 printf("* chkpath on a non existant file should fail\n");
4983 if (!NT_STATUS_IS_OK(cli_chkpath(cli
, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4984 ret
= check_error(__LINE__
, cli
, ERRDOS
, ERRbadpath
,
4985 NT_STATUS_OBJECT_PATH_NOT_FOUND
);
4987 printf("* chkpath on a non existent component should fail\n");
4991 cli_rmdir(cli
, "\\chkpath.dir\\dir2");
4992 cli_unlink(cli
, "\\chkpath.dir\\*", aSYSTEM
| aHIDDEN
);
4993 cli_rmdir(cli
, "\\chkpath.dir");
4995 if (!torture_close_connection(cli
)) {
5002 static bool run_eatest(int dummy
)
5004 static struct cli_state
*cli
;
5005 const char *fname
= "\\eatest.txt";
5006 bool correct
= True
;
5010 struct ea_struct
*ea_list
= NULL
;
5011 TALLOC_CTX
*mem_ctx
= talloc_init("eatest");
5013 printf("starting eatest\n");
5015 if (!torture_open_connection(&cli
, 0)) {
5016 talloc_destroy(mem_ctx
);
5020 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
5021 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0,
5022 FIRST_DESIRED_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5023 FILE_SHARE_NONE
, FILE_OVERWRITE_IF
,
5024 0x4044, 0, &fnum
))) {
5025 printf("open failed - %s\n", cli_errstr(cli
));
5026 talloc_destroy(mem_ctx
);
5030 for (i
= 0; i
< 10; i
++) {
5031 fstring ea_name
, ea_val
;
5033 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
);
5034 memset(ea_val
, (char)i
+1, i
+1);
5035 if (!cli_set_ea_fnum(cli
, fnum
, ea_name
, ea_val
, i
+1)) {
5036 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5037 talloc_destroy(mem_ctx
);
5042 cli_close(cli
, fnum
);
5043 for (i
= 0; i
< 10; i
++) {
5044 fstring ea_name
, ea_val
;
5046 slprintf(ea_name
, sizeof(ea_name
), "EA_%d", i
+10);
5047 memset(ea_val
, (char)i
+1, i
+1);
5048 if (!cli_set_ea_path(cli
, fname
, ea_name
, ea_val
, i
+1)) {
5049 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5050 talloc_destroy(mem_ctx
);
5055 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
5056 printf("ea_get list failed - %s\n", cli_errstr(cli
));
5060 printf("num_eas = %d\n", (int)num_eas
);
5062 if (num_eas
!= 20) {
5063 printf("Should be 20 EA's stored... failing.\n");
5067 for (i
= 0; i
< num_eas
; i
++) {
5068 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5069 dump_data(0, ea_list
[i
].value
.data
,
5070 ea_list
[i
].value
.length
);
5073 /* Setting EA's to zero length deletes them. Test this */
5074 printf("Now deleting all EA's - case indepenent....\n");
5077 cli_set_ea_path(cli
, fname
, "", "", 0);
5079 for (i
= 0; i
< 20; i
++) {
5081 slprintf(ea_name
, sizeof(ea_name
), "ea_%d", i
);
5082 if (!cli_set_ea_path(cli
, fname
, ea_name
, "", 0)) {
5083 printf("ea_set of name %s failed - %s\n", ea_name
, cli_errstr(cli
));
5084 talloc_destroy(mem_ctx
);
5090 if (!cli_get_ea_list_path(cli
, fname
, mem_ctx
, &num_eas
, &ea_list
)) {
5091 printf("ea_get list failed - %s\n", cli_errstr(cli
));
5095 printf("num_eas = %d\n", (int)num_eas
);
5096 for (i
= 0; i
< num_eas
; i
++) {
5097 printf("%d: ea_name = %s. Val = ", i
, ea_list
[i
].name
);
5098 dump_data(0, ea_list
[i
].value
.data
,
5099 ea_list
[i
].value
.length
);
5103 printf("deleting EA's failed.\n");
5107 /* Try and delete a non existant EA. */
5108 if (!cli_set_ea_path(cli
, fname
, "foo", "", 0)) {
5109 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli
));
5113 talloc_destroy(mem_ctx
);
5114 if (!torture_close_connection(cli
)) {
5121 static bool run_dirtest1(int dummy
)
5124 static struct cli_state
*cli
;
5127 bool correct
= True
;
5129 printf("starting directory test\n");
5131 if (!torture_open_connection(&cli
, 0)) {
5135 cli_sockopt(cli
, sockops
);
5137 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5138 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5139 cli_rmdir(cli
, "\\LISTDIR");
5140 cli_mkdir(cli
, "\\LISTDIR");
5142 /* Create 1000 files and 1000 directories. */
5143 for (i
=0;i
<1000;i
++) {
5145 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\f%d", i
);
5146 if (!NT_STATUS_IS_OK(cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_ARCHIVE
,
5147 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5148 fprintf(stderr
,"Failed to open %s\n", fname
);
5151 cli_close(cli
, fnum
);
5153 for (i
=0;i
<1000;i
++) {
5155 slprintf(fname
, sizeof(fname
), "\\LISTDIR\\d%d", i
);
5156 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, fname
))) {
5157 fprintf(stderr
,"Failed to open %s\n", fname
);
5162 /* Now ensure that doing an old list sees both files and directories. */
5163 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", aDIR
, list_fn
, NULL
);
5164 printf("num_seen = %d\n", num_seen
);
5165 /* We should see 100 files + 1000 directories + . and .. */
5166 if (num_seen
!= 2002)
5169 /* Ensure if we have the "must have" bits we only see the
5172 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aDIR
<<8)|aDIR
, list_fn
, NULL
);
5173 printf("num_seen = %d\n", num_seen
);
5174 if (num_seen
!= 1002)
5177 num_seen
= cli_list_old(cli
, "\\LISTDIR\\*", (aARCH
<<8)|aDIR
, list_fn
, NULL
);
5178 printf("num_seen = %d\n", num_seen
);
5179 if (num_seen
!= 1000)
5182 /* Delete everything. */
5183 cli_list(cli
, "\\LISTDIR\\*", 0, del_fn
, cli
);
5184 cli_list(cli
, "\\LISTDIR\\*", aDIR
, del_fn
, cli
);
5185 cli_rmdir(cli
, "\\LISTDIR");
5188 printf("Matched %d\n", cli_list(cli
, "a*.*", 0, list_fn
, NULL
));
5189 printf("Matched %d\n", cli_list(cli
, "b*.*", 0, list_fn
, NULL
));
5190 printf("Matched %d\n", cli_list(cli
, "xyzabc", 0, list_fn
, NULL
));
5193 if (!torture_close_connection(cli
)) {
5197 printf("finished dirtest1\n");
5202 static bool run_error_map_extract(int dummy
) {
5204 static struct cli_state
*c_dos
;
5205 static struct cli_state
*c_nt
;
5210 uint32 flgs2
, errnum
;
5217 /* NT-Error connection */
5219 if (!(c_nt
= open_nbt_connection())) {
5223 c_nt
->use_spnego
= False
;
5225 status
= cli_negprot(c_nt
);
5227 if (!NT_STATUS_IS_OK(status
)) {
5228 printf("%s rejected the NT-error negprot (%s)\n", host
,
5234 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt
, "", "", 0, "", 0,
5236 printf("%s rejected the NT-error initial session setup (%s)\n",host
, cli_errstr(c_nt
));
5240 /* DOS-Error connection */
5242 if (!(c_dos
= open_nbt_connection())) {
5246 c_dos
->use_spnego
= False
;
5247 c_dos
->force_dos_errors
= True
;
5249 status
= cli_negprot(c_dos
);
5250 if (!NT_STATUS_IS_OK(status
)) {
5251 printf("%s rejected the DOS-error negprot (%s)\n", host
,
5253 cli_shutdown(c_dos
);
5257 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos
, "", "", 0, "", 0,
5259 printf("%s rejected the DOS-error initial session setup (%s)\n",host
, cli_errstr(c_dos
));
5263 for (error
=(0xc0000000 | 0x1); error
< (0xc0000000| 0xFFF); error
++) {
5264 fstr_sprintf(user
, "%X", error
);
5266 if (NT_STATUS_IS_OK(cli_session_setup(c_nt
, user
,
5267 password
, strlen(password
),
5268 password
, strlen(password
),
5270 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5273 flgs2
= SVAL(c_nt
->inbuf
,smb_flg2
);
5275 /* Case #1: 32-bit NT errors */
5276 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5277 nt_status
= NT_STATUS(IVAL(c_nt
->inbuf
,smb_rcls
));
5279 printf("/** Dos error on NT connection! (%s) */\n",
5281 nt_status
= NT_STATUS(0xc0000000);
5284 if (NT_STATUS_IS_OK(cli_session_setup(c_dos
, user
,
5285 password
, strlen(password
),
5286 password
, strlen(password
),
5288 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5290 flgs2
= SVAL(c_dos
->inbuf
,smb_flg2
), errnum
;
5292 /* Case #1: 32-bit NT errors */
5293 if (flgs2
& FLAGS2_32_BIT_ERROR_CODES
) {
5294 printf("/** NT error on DOS connection! (%s) */\n",
5296 errnum
= errclass
= 0;
5298 cli_dos_error(c_dos
, &errclass
, &errnum
);
5301 if (NT_STATUS_V(nt_status
) != error
) {
5302 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5303 get_nt_error_c_code(NT_STATUS(error
)),
5304 get_nt_error_c_code(nt_status
));
5307 printf("\t{%s,\t%s,\t%s},\n",
5308 smb_dos_err_class(errclass
),
5309 smb_dos_err_name(errclass
, errnum
),
5310 get_nt_error_c_code(NT_STATUS(error
)));
5315 static bool run_sesssetup_bench(int dummy
)
5317 static struct cli_state
*c
;
5318 const char *fname
= "\\file.dat";
5323 if (!torture_open_connection(&c
, 0)) {
5327 if (!NT_STATUS_IS_OK(cli_ntcreate(
5328 c
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5329 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
5330 FILE_DELETE_ON_CLOSE
, 0, &fnum
))) {
5331 d_printf("open %s failed: %s\n", fname
, cli_errstr(c
));
5335 for (i
=0; i
<torture_numops
; i
++) {
5336 status
= cli_session_setup(
5338 password
, strlen(password
),
5339 password
, strlen(password
),
5341 if (!NT_STATUS_IS_OK(status
)) {
5342 d_printf("(%s) cli_session_setup failed: %s\n",
5343 __location__
, nt_errstr(status
));
5347 d_printf("\r%d ", (int)c
->vuid
);
5349 status
= cli_ulogoff(c
);
5350 if (!NT_STATUS_IS_OK(status
)) {
5351 d_printf("(%s) cli_ulogoff failed: %s\n",
5352 __location__
, nt_errstr(status
));
5361 static bool subst_test(const char *str
, const char *user
, const char *domain
,
5362 uid_t uid
, gid_t gid
, const char *expected
)
5367 subst
= talloc_sub_specified(talloc_tos(), str
, user
, domain
, uid
, gid
);
5369 if (strcmp(subst
, expected
) != 0) {
5370 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5371 "[%s]\n", str
, user
, domain
, (int)uid
, (int)gid
, subst
,
5380 static void chain1_open_completion(struct tevent_req
*req
)
5384 status
= cli_open_recv(req
, &fnum
);
5387 d_printf("cli_open_recv returned %s: %d\n",
5389 NT_STATUS_IS_OK(status
) ? fnum
: -1);
5392 static void chain1_write_completion(struct tevent_req
*req
)
5396 status
= cli_write_andx_recv(req
, &written
);
5399 d_printf("cli_write_andx_recv returned %s: %d\n",
5401 NT_STATUS_IS_OK(status
) ? (int)written
: -1);
5404 static void chain1_close_completion(struct tevent_req
*req
)
5407 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5409 status
= cli_close_recv(req
);
5414 d_printf("cli_close returned %s\n", nt_errstr(status
));
5417 static bool run_chain1(int dummy
)
5419 struct cli_state
*cli1
;
5420 struct event_context
*evt
= event_context_init(NULL
);
5421 struct tevent_req
*reqs
[3], *smbreqs
[3];
5423 const char *str
= "foobar";
5426 printf("starting chain1 test\n");
5427 if (!torture_open_connection(&cli1
, 0)) {
5431 cli_sockopt(cli1
, sockops
);
5433 reqs
[0] = cli_open_create(talloc_tos(), evt
, cli1
, "\\test",
5434 O_CREAT
|O_RDWR
, 0, &smbreqs
[0]);
5435 if (reqs
[0] == NULL
) return false;
5436 tevent_req_set_callback(reqs
[0], chain1_open_completion
, NULL
);
5439 reqs
[1] = cli_write_andx_create(talloc_tos(), evt
, cli1
, 0, 0,
5440 (uint8_t *)str
, 0, strlen(str
)+1,
5441 smbreqs
, 1, &smbreqs
[1]);
5442 if (reqs
[1] == NULL
) return false;
5443 tevent_req_set_callback(reqs
[1], chain1_write_completion
, NULL
);
5445 reqs
[2] = cli_close_create(talloc_tos(), evt
, cli1
, 0, &smbreqs
[2]);
5446 if (reqs
[2] == NULL
) return false;
5447 tevent_req_set_callback(reqs
[2], chain1_close_completion
, &done
);
5449 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5450 if (!NT_STATUS_IS_OK(status
)) {
5455 event_loop_once(evt
);
5458 torture_close_connection(cli1
);
5462 static void chain2_sesssetup_completion(struct tevent_req
*req
)
5465 status
= cli_session_setup_guest_recv(req
);
5466 d_printf("sesssetup returned %s\n", nt_errstr(status
));
5469 static void chain2_tcon_completion(struct tevent_req
*req
)
5471 bool *done
= (bool *)tevent_req_callback_data_void(req
);
5473 status
= cli_tcon_andx_recv(req
);
5474 d_printf("tcon_and_x returned %s\n", nt_errstr(status
));
5478 static bool run_chain2(int dummy
)
5480 struct cli_state
*cli1
;
5481 struct event_context
*evt
= event_context_init(NULL
);
5482 struct tevent_req
*reqs
[2], *smbreqs
[2];
5486 printf("starting chain2 test\n");
5487 status
= cli_start_connection(&cli1
, global_myname(), host
, NULL
,
5488 port_to_use
, Undefined
, 0, NULL
);
5489 if (!NT_STATUS_IS_OK(status
)) {
5493 cli_sockopt(cli1
, sockops
);
5495 reqs
[0] = cli_session_setup_guest_create(talloc_tos(), evt
, cli1
,
5497 if (reqs
[0] == NULL
) return false;
5498 tevent_req_set_callback(reqs
[0], chain2_sesssetup_completion
, NULL
);
5500 reqs
[1] = cli_tcon_andx_create(talloc_tos(), evt
, cli1
, "IPC$",
5501 "?????", NULL
, 0, &smbreqs
[1]);
5502 if (reqs
[1] == NULL
) return false;
5503 tevent_req_set_callback(reqs
[1], chain2_tcon_completion
, &done
);
5505 status
= cli_smb_chain_send(smbreqs
, ARRAY_SIZE(smbreqs
));
5506 if (!NT_STATUS_IS_OK(status
)) {
5511 event_loop_once(evt
);
5514 torture_close_connection(cli1
);
5519 struct torture_createdel_state
{
5520 struct tevent_context
*ev
;
5521 struct cli_state
*cli
;
5524 static void torture_createdel_created(struct tevent_req
*subreq
);
5525 static void torture_createdel_closed(struct tevent_req
*subreq
);
5527 static struct tevent_req
*torture_createdel_send(TALLOC_CTX
*mem_ctx
,
5528 struct tevent_context
*ev
,
5529 struct cli_state
*cli
,
5532 struct tevent_req
*req
, *subreq
;
5533 struct torture_createdel_state
*state
;
5535 req
= tevent_req_create(mem_ctx
, &state
,
5536 struct torture_createdel_state
);
5543 subreq
= cli_ntcreate_send(
5544 state
, ev
, cli
, name
, 0,
5545 FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
5546 FILE_ATTRIBUTE_NORMAL
,
5547 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
5548 FILE_OPEN_IF
, FILE_DELETE_ON_CLOSE
, 0);
5550 if (tevent_req_nomem(subreq
, req
)) {
5551 return tevent_req_post(req
, ev
);
5553 tevent_req_set_callback(subreq
, torture_createdel_created
, req
);
5557 static void torture_createdel_created(struct tevent_req
*subreq
)
5559 struct tevent_req
*req
= tevent_req_callback_data(
5560 subreq
, struct tevent_req
);
5561 struct torture_createdel_state
*state
= tevent_req_data(
5562 req
, struct torture_createdel_state
);
5566 status
= cli_ntcreate_recv(subreq
, &fnum
);
5567 TALLOC_FREE(subreq
);
5568 if (!NT_STATUS_IS_OK(status
)) {
5569 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5570 nt_errstr(status
)));
5571 tevent_req_nterror(req
, status
);
5575 subreq
= cli_close_send(state
, state
->ev
, state
->cli
, fnum
);
5576 if (tevent_req_nomem(subreq
, req
)) {
5579 tevent_req_set_callback(subreq
, torture_createdel_closed
, req
);
5582 static void torture_createdel_closed(struct tevent_req
*subreq
)
5584 struct tevent_req
*req
= tevent_req_callback_data(
5585 subreq
, struct tevent_req
);
5588 status
= cli_close_recv(subreq
);
5589 if (!NT_STATUS_IS_OK(status
)) {
5590 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status
)));
5591 tevent_req_nterror(req
, status
);
5594 tevent_req_done(req
);
5597 static NTSTATUS
torture_createdel_recv(struct tevent_req
*req
)
5599 return tevent_req_simple_recv_ntstatus(req
);
5602 struct torture_createdels_state
{
5603 struct tevent_context
*ev
;
5604 struct cli_state
*cli
;
5605 const char *base_name
;
5609 struct tevent_req
**reqs
;
5612 static void torture_createdels_done(struct tevent_req
*subreq
);
5614 static struct tevent_req
*torture_createdels_send(TALLOC_CTX
*mem_ctx
,
5615 struct tevent_context
*ev
,
5616 struct cli_state
*cli
,
5617 const char *base_name
,
5621 struct tevent_req
*req
;
5622 struct torture_createdels_state
*state
;
5625 req
= tevent_req_create(mem_ctx
, &state
,
5626 struct torture_createdels_state
);
5632 state
->base_name
= talloc_strdup(state
, base_name
);
5633 if (tevent_req_nomem(state
->base_name
, req
)) {
5634 return tevent_req_post(req
, ev
);
5636 state
->num_files
= MAX(num_parallel
, num_files
);
5638 state
->received
= 0;
5640 state
->reqs
= talloc_array(state
, struct tevent_req
*, num_parallel
);
5641 if (tevent_req_nomem(state
->reqs
, req
)) {
5642 return tevent_req_post(req
, ev
);
5645 for (i
=0; i
<num_parallel
; i
++) {
5648 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5650 if (tevent_req_nomem(name
, req
)) {
5651 return tevent_req_post(req
, ev
);
5653 state
->reqs
[i
] = torture_createdel_send(
5654 state
->reqs
, state
->ev
, state
->cli
, name
);
5655 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5656 return tevent_req_post(req
, ev
);
5658 name
= talloc_move(state
->reqs
[i
], &name
);
5659 tevent_req_set_callback(state
->reqs
[i
],
5660 torture_createdels_done
, req
);
5666 static void torture_createdels_done(struct tevent_req
*subreq
)
5668 struct tevent_req
*req
= tevent_req_callback_data(
5669 subreq
, struct tevent_req
);
5670 struct torture_createdels_state
*state
= tevent_req_data(
5671 req
, struct torture_createdels_state
);
5672 size_t num_parallel
= talloc_array_length(state
->reqs
);
5677 status
= torture_createdel_recv(subreq
);
5678 if (!NT_STATUS_IS_OK(status
)){
5679 DEBUG(10, ("torture_createdel_recv returned %s\n",
5680 nt_errstr(status
)));
5681 TALLOC_FREE(subreq
);
5682 tevent_req_nterror(req
, status
);
5686 for (i
=0; i
<num_parallel
; i
++) {
5687 if (subreq
== state
->reqs
[i
]) {
5691 if (i
== num_parallel
) {
5692 DEBUG(10, ("received something we did not send\n"));
5693 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
5696 TALLOC_FREE(state
->reqs
[i
]);
5698 if (state
->sent
>= state
->num_files
) {
5699 tevent_req_done(req
);
5703 name
= talloc_asprintf(state
, "%s%8.8d", state
->base_name
,
5705 if (tevent_req_nomem(name
, req
)) {
5708 state
->reqs
[i
] = torture_createdel_send(state
->reqs
, state
->ev
,
5710 if (tevent_req_nomem(state
->reqs
[i
], req
)) {
5713 name
= talloc_move(state
->reqs
[i
], &name
);
5714 tevent_req_set_callback(state
->reqs
[i
], torture_createdels_done
, req
);
5718 static NTSTATUS
torture_createdels_recv(struct tevent_req
*req
)
5720 return tevent_req_simple_recv_ntstatus(req
);
5723 struct swallow_notify_state
{
5724 struct tevent_context
*ev
;
5725 struct cli_state
*cli
;
5727 uint32_t completion_filter
;
5729 bool (*fn
)(uint32_t action
, const char *name
, void *priv
);
5733 static void swallow_notify_done(struct tevent_req
*subreq
);
5735 static struct tevent_req
*swallow_notify_send(TALLOC_CTX
*mem_ctx
,
5736 struct tevent_context
*ev
,
5737 struct cli_state
*cli
,
5739 uint32_t completion_filter
,
5741 bool (*fn
)(uint32_t action
,
5746 struct tevent_req
*req
, *subreq
;
5747 struct swallow_notify_state
*state
;
5749 req
= tevent_req_create(mem_ctx
, &state
,
5750 struct swallow_notify_state
);
5757 state
->completion_filter
= completion_filter
;
5758 state
->recursive
= recursive
;
5762 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5763 0xffff, state
->completion_filter
,
5765 if (tevent_req_nomem(subreq
, req
)) {
5766 return tevent_req_post(req
, ev
);
5768 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5772 static void swallow_notify_done(struct tevent_req
*subreq
)
5774 struct tevent_req
*req
= tevent_req_callback_data(
5775 subreq
, struct tevent_req
);
5776 struct swallow_notify_state
*state
= tevent_req_data(
5777 req
, struct swallow_notify_state
);
5779 uint32_t i
, num_changes
;
5780 struct notify_change
*changes
;
5782 status
= cli_notify_recv(subreq
, state
, &num_changes
, &changes
);
5783 TALLOC_FREE(subreq
);
5784 if (!NT_STATUS_IS_OK(status
)) {
5785 DEBUG(10, ("cli_notify_recv returned %s\n",
5786 nt_errstr(status
)));
5787 tevent_req_nterror(req
, status
);
5791 for (i
=0; i
<num_changes
; i
++) {
5792 state
->fn(changes
[i
].action
, changes
[i
].name
, state
->priv
);
5794 TALLOC_FREE(changes
);
5796 subreq
= cli_notify_send(state
, state
->ev
, state
->cli
, state
->fnum
,
5797 0xffff, state
->completion_filter
,
5799 if (tevent_req_nomem(subreq
, req
)) {
5802 tevent_req_set_callback(subreq
, swallow_notify_done
, req
);
5805 static bool print_notifies(uint32_t action
, const char *name
, void *priv
)
5807 if (DEBUGLEVEL
> 5) {
5808 d_printf("%d %s\n", (int)action
, name
);
5813 static void notify_bench_done(struct tevent_req
*req
)
5815 int *num_finished
= (int *)tevent_req_callback_data_void(req
);
5819 static bool run_notify_bench(int dummy
)
5821 const char *dname
= "\\notify-bench";
5822 struct tevent_context
*ev
;
5825 struct tevent_req
*req1
;
5826 struct tevent_req
*req2
= NULL
;
5827 int i
, num_unc_names
;
5828 int num_finished
= 0;
5830 printf("starting notify-bench test\n");
5832 if (use_multishare_conn
) {
5834 unc_list
= file_lines_load(multishare_conn_fname
,
5835 &num_unc_names
, 0, NULL
);
5836 if (!unc_list
|| num_unc_names
<= 0) {
5837 d_printf("Failed to load unc names list from '%s'\n",
5838 multishare_conn_fname
);
5841 TALLOC_FREE(unc_list
);
5846 ev
= tevent_context_init(talloc_tos());
5848 d_printf("tevent_context_init failed\n");
5852 for (i
=0; i
<num_unc_names
; i
++) {
5853 struct cli_state
*cli
;
5856 base_fname
= talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5858 if (base_fname
== NULL
) {
5862 if (!torture_open_connection(&cli
, i
)) {
5866 status
= cli_ntcreate(cli
, dname
, 0,
5867 MAXIMUM_ALLOWED_ACCESS
,
5868 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
|
5870 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, 0,
5873 if (!NT_STATUS_IS_OK(status
)) {
5874 d_printf("Could not create %s: %s\n", dname
,
5879 req1
= swallow_notify_send(talloc_tos(), ev
, cli
, dnum
,
5880 FILE_NOTIFY_CHANGE_FILE_NAME
|
5881 FILE_NOTIFY_CHANGE_DIR_NAME
|
5882 FILE_NOTIFY_CHANGE_ATTRIBUTES
|
5883 FILE_NOTIFY_CHANGE_LAST_WRITE
,
5884 false, print_notifies
, NULL
);
5886 d_printf("Could not create notify request\n");
5890 req2
= torture_createdels_send(talloc_tos(), ev
, cli
,
5891 base_fname
, 10, torture_numops
);
5893 d_printf("Could not create createdels request\n");
5896 TALLOC_FREE(base_fname
);
5898 tevent_req_set_callback(req2
, notify_bench_done
,
5902 while (num_finished
< num_unc_names
) {
5904 ret
= tevent_loop_once(ev
);
5906 d_printf("tevent_loop_once failed\n");
5911 if (!tevent_req_poll(req2
, ev
)) {
5912 d_printf("tevent_req_poll failed\n");
5915 status
= torture_createdels_recv(req2
);
5916 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status
));
5921 static bool run_mangle1(int dummy
)
5923 struct cli_state
*cli
;
5924 const char *fname
= "this_is_a_long_fname_to_be_mangled.txt";
5928 time_t change_time
, access_time
, write_time
;
5932 printf("starting mangle1 test\n");
5933 if (!torture_open_connection(&cli
, 0)) {
5937 cli_sockopt(cli
, sockops
);
5939 if (!NT_STATUS_IS_OK(cli_ntcreate(
5940 cli
, fname
, 0, GENERIC_ALL_ACCESS
|DELETE_ACCESS
,
5941 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0, 0, &fnum
))) {
5942 d_printf("open %s failed: %s\n", fname
, cli_errstr(cli
));
5945 cli_close(cli
, fnum
);
5947 status
= cli_qpathinfo_alt_name(cli
, fname
, alt_name
);
5948 if (!NT_STATUS_IS_OK(status
)) {
5949 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5953 d_printf("alt_name: %s\n", alt_name
);
5955 if (!NT_STATUS_IS_OK(cli_open(cli
, alt_name
, O_RDONLY
, DENY_NONE
, &fnum
))) {
5956 d_printf("cli_open(%s) failed: %s\n", alt_name
,
5960 cli_close(cli
, fnum
);
5962 if (!cli_qpathinfo(cli
, alt_name
, &change_time
, &access_time
,
5963 &write_time
, &size
, &mode
)) {
5964 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name
,
5972 static size_t null_source(uint8_t *buf
, size_t n
, void *priv
)
5974 size_t *to_pull
= (size_t *)priv
;
5975 size_t thistime
= *to_pull
;
5977 thistime
= MIN(thistime
, n
);
5978 if (thistime
== 0) {
5982 memset(buf
, 0, thistime
);
5983 *to_pull
-= thistime
;
5987 static bool run_windows_write(int dummy
)
5989 struct cli_state
*cli1
;
5993 const char *fname
= "\\writetest.txt";
5994 struct timeval start_time
;
5998 printf("starting windows_write test\n");
5999 if (!torture_open_connection(&cli1
, 0)) {
6003 if (!NT_STATUS_IS_OK(cli_open(cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
, &fnum
))) {
6004 printf("open failed (%s)\n", cli_errstr(cli1
));
6008 cli_sockopt(cli1
, sockops
);
6010 start_time
= timeval_current();
6012 for (i
=0; i
<torture_numops
; i
++) {
6014 off_t start
= i
* torture_blocksize
;
6016 size_t to_pull
= torture_blocksize
- 1;
6018 if (cli_write(cli1
, fnum
, 0, &c
,
6019 start
+ torture_blocksize
- 1, 1) != 1) {
6020 printf("cli_write failed: %s\n", cli_errstr(cli1
));
6024 status
= cli_push(cli1
, fnum
, 0, i
* torture_blocksize
, torture_blocksize
,
6025 null_source
, &to_pull
);
6026 if (!NT_STATUS_IS_OK(status
)) {
6027 printf("cli_push returned: %s\n", nt_errstr(status
));
6032 seconds
= timeval_elapsed(&start_time
);
6033 kbytes
= (double)torture_blocksize
* torture_numops
;
6036 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes
,
6037 (double)seconds
, (int)(kbytes
/seconds
));
6041 cli_close(cli1
, fnum
);
6042 cli_unlink(cli1
, fname
, aSYSTEM
| aHIDDEN
);
6043 torture_close_connection(cli1
);
6047 static bool run_cli_echo(int dummy
)
6049 struct cli_state
*cli
;
6052 printf("starting cli_echo test\n");
6053 if (!torture_open_connection(&cli
, 0)) {
6056 cli_sockopt(cli
, sockops
);
6058 status
= cli_echo(cli
, 5, data_blob_const("hello", 5));
6060 d_printf("cli_echo returned %s\n", nt_errstr(status
));
6062 torture_close_connection(cli
);
6063 return NT_STATUS_IS_OK(status
);
6066 static bool run_uid_regression_test(int dummy
)
6068 static struct cli_state
*cli
;
6071 bool correct
= True
;
6074 printf("starting uid regression test\n");
6076 if (!torture_open_connection(&cli
, 0)) {
6080 cli_sockopt(cli
, sockops
);
6082 /* Ok - now save then logoff our current user. */
6083 old_vuid
= cli
->vuid
;
6085 status
= cli_ulogoff(cli
);
6086 if (!NT_STATUS_IS_OK(status
)) {
6087 d_printf("(%s) cli_ulogoff failed: %s\n",
6088 __location__
, nt_errstr(status
));
6093 cli
->vuid
= old_vuid
;
6095 /* Try an operation. */
6096 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\uid_reg_test"))) {
6097 /* We expect bad uid. */
6098 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRbaduid
,
6099 NT_STATUS_NO_SUCH_USER
)) {
6104 old_cnum
= cli
->cnum
;
6106 /* Now try a SMBtdis with the invald vuid set to zero. */
6109 /* This should succeed. */
6110 status
= cli_tdis(cli
);
6112 if (NT_STATUS_IS_OK(status
)) {
6113 printf("First tdis with invalid vuid should succeed.\n");
6115 printf("First tdis failed (%s)\n", nt_errstr(status
));
6118 cli
->vuid
= old_vuid
;
6119 cli
->cnum
= old_cnum
;
6121 /* This should fail. */
6122 status
= cli_tdis(cli
);
6123 if (NT_STATUS_IS_OK(status
)) {
6124 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6126 /* Should be bad tid. */
6127 if (!check_error(__LINE__
, cli
, ERRSRV
, ERRinvnid
,
6128 NT_STATUS_NETWORK_NAME_DELETED
)) {
6133 cli_rmdir(cli
, "\\uid_reg_test");
6142 static const char *illegal_chars
= "*\\/?<>|\":";
6143 static char force_shortname_chars
[] = " +,.[];=\177";
6145 static void shortname_del_fn(const char *mnt
, file_info
*finfo
, const char *mask
, void *state
)
6147 struct cli_state
*pcli
= (struct cli_state
*)state
;
6149 slprintf(fname
, sizeof(fname
), "\\shortname\\%s", finfo
->name
);
6151 if (strcmp(finfo
->name
, ".") == 0 || strcmp(finfo
->name
, "..") == 0)
6154 if (finfo
->mode
& aDIR
) {
6155 if (!NT_STATUS_IS_OK(cli_rmdir(pcli
, fname
)))
6156 printf("del_fn: failed to rmdir %s\n,", fname
);
6158 if (!NT_STATUS_IS_OK(cli_unlink(pcli
, fname
, aSYSTEM
| aHIDDEN
)))
6159 printf("del_fn: failed to unlink %s\n,", fname
);
6168 static void shortname_list_fn(const char *mnt
, file_info
*finfo
, const char *name
, void *state
)
6170 struct sn_state
*s
= (struct sn_state
*)state
;
6174 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6175 i
, finfo
->name
, finfo
->short_name
);
6178 if (strchr(force_shortname_chars
, i
)) {
6179 if (!finfo
->short_name
[0]) {
6180 /* Shortname not created when it should be. */
6181 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6182 __location__
, finfo
->name
, i
);
6185 } else if (finfo
->short_name
[0]){
6186 /* Shortname created when it should not be. */
6187 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6188 __location__
, finfo
->short_name
, finfo
->name
);
6193 static bool run_shortname_test(int dummy
)
6195 static struct cli_state
*cli
;
6196 bool correct
= True
;
6201 printf("starting shortname test\n");
6203 if (!torture_open_connection(&cli
, 0)) {
6207 cli_sockopt(cli
, sockops
);
6209 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6210 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6211 cli_rmdir(cli
, "\\shortname");
6213 if (!NT_STATUS_IS_OK(cli_mkdir(cli
, "\\shortname"))) {
6214 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6215 __location__
, cli_errstr(cli
));
6220 strlcpy(fname
, "\\shortname\\", sizeof(fname
));
6221 strlcat(fname
, "test .txt", sizeof(fname
));
6225 for (i
= 32; i
< 128; i
++) {
6227 uint16_t fnum
= (uint16_t)-1;
6231 if (strchr(illegal_chars
, i
)) {
6236 status
= cli_ntcreate(cli
, fname
, 0, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
6237 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0, 0, &fnum
);
6238 if (!NT_STATUS_IS_OK(status
)) {
6239 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6240 __location__
, fname
, cli_errstr(cli
));
6244 cli_close(cli
, fnum
);
6245 if (cli_list(cli
, "\\shortname\\test*.*", 0, shortname_list_fn
, &s
) != 1) {
6246 d_printf("(%s) failed to list %s: %s\n",
6247 __location__
, fname
, cli_errstr(cli
));
6251 if (!NT_STATUS_IS_OK(cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
))) {
6252 d_printf("(%s) failed to delete %s: %s\n",
6253 __location__
, fname
, cli_errstr(cli
));
6266 cli_list(cli
, "\\shortname\\*", 0, shortname_del_fn
, cli
);
6267 cli_list(cli
, "\\shortname\\*", aDIR
, shortname_del_fn
, cli
);
6268 cli_rmdir(cli
, "\\shortname");
6269 torture_close_connection(cli
);
6273 static void pagedsearch_cb(struct tevent_req
*req
)
6276 struct tldap_message
*msg
;
6279 rc
= tldap_search_paged_recv(req
, talloc_tos(), &msg
);
6280 if (rc
!= TLDAP_SUCCESS
) {
6281 d_printf("tldap_search_paged_recv failed: %s\n",
6282 tldap_err2string(rc
));
6285 if (tldap_msg_type(msg
) != TLDAP_RES_SEARCH_ENTRY
) {
6289 if (!tldap_entry_dn(msg
, &dn
)) {
6290 d_printf("tldap_entry_dn failed\n");
6293 d_printf("%s\n", dn
);
6297 static bool run_tldap(int dummy
)
6299 struct tldap_context
*ld
;
6302 struct sockaddr_storage addr
;
6303 struct tevent_context
*ev
;
6304 struct tevent_req
*req
;
6308 if (!resolve_name(host
, &addr
, 0, false)) {
6309 d_printf("could not find host %s\n", host
);
6312 status
= open_socket_out(&addr
, 389, 9999, &fd
);
6313 if (!NT_STATUS_IS_OK(status
)) {
6314 d_printf("open_socket_out failed: %s\n", nt_errstr(status
));
6318 ld
= tldap_context_create(talloc_tos(), fd
);
6321 d_printf("tldap_context_create failed\n");
6325 rc
= tldap_fetch_rootdse(ld
);
6326 if (rc
!= TLDAP_SUCCESS
) {
6327 d_printf("tldap_fetch_rootdse failed: %s\n",
6328 tldap_errstr(talloc_tos(), ld
, rc
));
6332 basedn
= tldap_talloc_single_attribute(
6333 tldap_rootdse(ld
), "defaultNamingContext", talloc_tos());
6334 if (basedn
== NULL
) {
6335 d_printf("no defaultNamingContext\n");
6338 d_printf("defaultNamingContext: %s\n", basedn
);
6340 ev
= tevent_context_init(talloc_tos());
6342 d_printf("tevent_context_init failed\n");
6346 req
= tldap_search_paged_send(talloc_tos(), ev
, ld
, basedn
,
6347 TLDAP_SCOPE_SUB
, "(objectclass=*)",
6349 NULL
, 0, NULL
, 0, 0, 0, 0, 5);
6351 d_printf("tldap_search_paged_send failed\n");
6354 tevent_req_set_callback(req
, pagedsearch_cb
, NULL
);
6356 tevent_req_poll(req
, ev
);
6360 /* test search filters against rootDSE */
6361 filter
= "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6362 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6364 rc
= tldap_search(ld
, "", TLDAP_SCOPE_BASE
, filter
,
6365 NULL
, 0, 0, NULL
, 0, NULL
, 0, 0, 0, 0,
6366 talloc_tos(), NULL
, NULL
);
6367 if (rc
!= TLDAP_SUCCESS
) {
6368 d_printf("tldap_search with complex filter failed: %s\n",
6369 tldap_errstr(talloc_tos(), ld
, rc
));
6377 /* Torture test to ensure no regression of :
6378 https://bugzilla.samba.org/show_bug.cgi?id=7084
6381 static bool run_dir_createtime(int dummy
)
6383 struct cli_state
*cli
;
6384 const char *dname
= "\\testdir";
6385 const char *fname
= "\\testdir\\testfile";
6387 struct timespec create_time
;
6388 struct timespec create_time1
;
6392 if (!torture_open_connection(&cli
, 0)) {
6396 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6397 cli_rmdir(cli
, dname
);
6399 status
= cli_mkdir(cli
, dname
);
6400 if (!NT_STATUS_IS_OK(status
)) {
6401 printf("mkdir failed: %s\n", nt_errstr(status
));
6405 if (!cli_qpathinfo2(cli
,
6414 status
= cli_nt_error(cli
);
6415 printf("cli_qpathinfo2 returned %s\n",
6420 /* Sleep 3 seconds, then create a file. */
6423 status
= cli_open(cli
, fname
, O_RDWR
| O_CREAT
| O_EXCL
,
6425 if (!NT_STATUS_IS_OK(status
)) {
6426 printf("cli_open failed: %s\n", nt_errstr(status
));
6430 if (!cli_qpathinfo2(cli
,
6439 status
= cli_nt_error(cli
);
6440 printf("cli_qpathinfo2 (2) returned %s\n",
6445 if (timespec_compare(&create_time1
, &create_time
)) {
6446 printf("run_dir_createtime: create time was updated (error)\n");
6448 printf("run_dir_createtime: create time was not updated (correct)\n");
6454 cli_unlink(cli
, fname
, aSYSTEM
| aHIDDEN
);
6455 cli_rmdir(cli
, dname
);
6456 if (!torture_close_connection(cli
)) {
6463 static bool run_streamerror(int dummy
)
6465 struct cli_state
*cli
;
6466 const char *dname
= "\\testdir";
6467 const char *streamname
=
6468 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6470 time_t change_time
, access_time
, write_time
;
6472 uint16_t mode
, fnum
;
6475 if (!torture_open_connection(&cli
, 0)) {
6479 cli_unlink(cli
, "\\testdir\\*", aSYSTEM
| aHIDDEN
);
6480 cli_rmdir(cli
, dname
);
6482 status
= cli_mkdir(cli
, dname
);
6483 if (!NT_STATUS_IS_OK(status
)) {
6484 printf("mkdir failed: %s\n", nt_errstr(status
));
6488 cli_qpathinfo(cli
, streamname
, &change_time
, &access_time
, &write_time
,
6490 status
= cli_nt_error(cli
);
6492 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6493 printf("pathinfo returned %s, expected "
6494 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6499 status
= cli_ntcreate(cli
, streamname
, 0x16,
6500 FILE_READ_DATA
|FILE_READ_EA
|
6501 FILE_READ_ATTRIBUTES
|READ_CONTROL_ACCESS
,
6502 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
,
6503 FILE_OPEN
, 0, 0, &fnum
);
6505 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
6506 printf("ntcreate returned %s, expected "
6507 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6513 cli_rmdir(cli
, dname
);
6517 static bool run_local_substitute(int dummy
)
6521 ok
&= subst_test("%U", "bla", "", -1, -1, "bla");
6522 ok
&= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6523 ok
&= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6524 ok
&= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6525 ok
&= subst_test("%g", "", "", -1, 0, gidtoname(0));
6526 ok
&= subst_test("%G", "", "", -1, 0, gidtoname(0));
6527 ok
&= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6528 ok
&= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6530 /* Different captialization rules in sub_basic... */
6532 ok
&= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6538 static bool run_local_base64(int dummy
)
6543 for (i
=1; i
<2000; i
++) {
6544 DATA_BLOB blob1
, blob2
;
6547 blob1
.data
= talloc_array(talloc_tos(), uint8_t, i
);
6549 generate_random_buffer(blob1
.data
, blob1
.length
);
6551 b64
= base64_encode_data_blob(talloc_tos(), blob1
);
6553 d_fprintf(stderr
, "base64_encode_data_blob failed "
6554 "for %d bytes\n", i
);
6557 blob2
= base64_decode_data_blob(b64
);
6560 if (data_blob_cmp(&blob1
, &blob2
)) {
6561 d_fprintf(stderr
, "data_blob_cmp failed for %d "
6565 TALLOC_FREE(blob1
.data
);
6566 data_blob_free(&blob2
);
6571 static bool run_local_gencache(int dummy
)
6577 if (!gencache_set("foo", "bar", time(NULL
) + 1000)) {
6578 d_printf("%s: gencache_set() failed\n", __location__
);
6582 if (!gencache_get("foo", NULL
, NULL
)) {
6583 d_printf("%s: gencache_get() failed\n", __location__
);
6587 if (!gencache_get("foo", &val
, &tm
)) {
6588 d_printf("%s: gencache_get() failed\n", __location__
);
6592 if (strcmp(val
, "bar") != 0) {
6593 d_printf("%s: gencache_get() returned %s, expected %s\n",
6594 __location__
, val
, "bar");
6601 if (!gencache_del("foo")) {
6602 d_printf("%s: gencache_del() failed\n", __location__
);
6605 if (gencache_del("foo")) {
6606 d_printf("%s: second gencache_del() succeeded\n",
6611 if (gencache_get("foo", &val
, &tm
)) {
6612 d_printf("%s: gencache_get() on deleted entry "
6613 "succeeded\n", __location__
);
6617 blob
= data_blob_string_const_null("bar");
6618 tm
= time(NULL
) + 60;
6620 if (!gencache_set_data_blob("foo", &blob
, tm
)) {
6621 d_printf("%s: gencache_set_data_blob() failed\n", __location__
);
6625 if (!gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6626 d_printf("%s: gencache_get_data_blob() failed\n", __location__
);
6630 if (strcmp((const char *)blob
.data
, "bar") != 0) {
6631 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6632 __location__
, (const char *)blob
.data
, "bar");
6633 data_blob_free(&blob
);
6637 data_blob_free(&blob
);
6639 if (!gencache_del("foo")) {
6640 d_printf("%s: gencache_del() failed\n", __location__
);
6643 if (gencache_del("foo")) {
6644 d_printf("%s: second gencache_del() succeeded\n",
6649 if (gencache_get_data_blob("foo", &blob
, NULL
, NULL
)) {
6650 d_printf("%s: gencache_get_data_blob() on deleted entry "
6651 "succeeded\n", __location__
);
6658 static bool rbt_testval(struct db_context
*db
, const char *key
,
6661 struct db_record
*rec
;
6662 TDB_DATA data
= string_tdb_data(value
);
6666 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6668 d_fprintf(stderr
, "fetch_locked failed\n");
6671 status
= rec
->store(rec
, data
, 0);
6672 if (!NT_STATUS_IS_OK(status
)) {
6673 d_fprintf(stderr
, "store failed: %s\n", nt_errstr(status
));
6678 rec
= db
->fetch_locked(db
, db
, string_tdb_data(key
));
6680 d_fprintf(stderr
, "second fetch_locked failed\n");
6683 if ((rec
->value
.dsize
!= data
.dsize
)
6684 || (memcmp(rec
->value
.dptr
, data
.dptr
, data
.dsize
) != 0)) {
6685 d_fprintf(stderr
, "Got wrong data back\n");
6695 static bool run_local_rbtree(int dummy
)
6697 struct db_context
*db
;
6701 db
= db_open_rbt(NULL
);
6704 d_fprintf(stderr
, "db_open_rbt failed\n");
6708 for (i
=0; i
<1000; i
++) {
6711 if (asprintf(&key
, "key%ld", random()) == -1) {
6714 if (asprintf(&value
, "value%ld", random()) == -1) {
6719 if (!rbt_testval(db
, key
, value
)) {
6726 if (asprintf(&value
, "value%ld", random()) == -1) {
6731 if (!rbt_testval(db
, key
, value
)) {
6748 struct talloc_dict_test
{
6752 static int talloc_dict_traverse_fn(DATA_BLOB key
, void *data
, void *priv
)
6754 int *count
= (int *)priv
;
6759 static bool run_local_talloc_dict(int dummy
)
6761 struct talloc_dict
*dict
;
6762 struct talloc_dict_test
*t
;
6765 dict
= talloc_dict_init(talloc_tos());
6770 t
= talloc(talloc_tos(), struct talloc_dict_test
);
6777 if (!talloc_dict_set(dict
, data_blob_const(&key
, sizeof(key
)), t
)) {
6782 if (talloc_dict_traverse(dict
, talloc_dict_traverse_fn
, &count
) != 0) {
6795 static bool run_local_string_to_sid(int dummy
) {
6798 if (string_to_sid(&sid
, "S--1-5-32-545")) {
6799 printf("allowing S--1-5-32-545\n");
6802 if (string_to_sid(&sid
, "S-1-5-32-+545")) {
6803 printf("allowing S-1-5-32-+545\n");
6806 if (string_to_sid(&sid
, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6807 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6810 if (string_to_sid(&sid
, "S-1-5-32-545-abc")) {
6811 printf("allowing S-1-5-32-545-abc\n");
6814 if (!string_to_sid(&sid
, "S-1-5-32-545")) {
6815 printf("could not parse S-1-5-32-545\n");
6818 if (!sid_equal(&sid
, &global_sid_Builtin_Users
)) {
6819 printf("mis-parsed S-1-5-32-545 as %s\n",
6820 sid_string_tos(&sid
));
6826 /* Split a path name into filename and stream name components. Canonicalise
6827 * such that an implicit $DATA token is always explicit.
6829 * The "specification" of this function can be found in the
6830 * run_local_stream_name() function in torture.c, I've tried those
6831 * combinations against a W2k3 server.
6834 static NTSTATUS
split_ntfs_stream_name(TALLOC_CTX
*mem_ctx
, const char *fname
,
6835 char **pbase
, char **pstream
)
6838 char *stream
= NULL
;
6839 char *sname
; /* stream name */
6840 const char *stype
; /* stream type */
6842 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname
));
6844 sname
= strchr_m(fname
, ':');
6846 if (lp_posix_pathnames() || (sname
== NULL
)) {
6847 if (pbase
!= NULL
) {
6848 base
= talloc_strdup(mem_ctx
, fname
);
6849 NT_STATUS_HAVE_NO_MEMORY(base
);
6854 if (pbase
!= NULL
) {
6855 base
= talloc_strndup(mem_ctx
, fname
, PTR_DIFF(sname
, fname
));
6856 NT_STATUS_HAVE_NO_MEMORY(base
);
6861 stype
= strchr_m(sname
, ':');
6863 if (stype
== NULL
) {
6864 sname
= talloc_strdup(mem_ctx
, sname
);
6868 if (StrCaseCmp(stype
, ":$DATA") != 0) {
6870 * If there is an explicit stream type, so far we only
6871 * allow $DATA. Is there anything else allowed? -- vl
6873 DEBUG(10, ("[%s] is an invalid stream type\n", stype
));
6875 return NT_STATUS_OBJECT_NAME_INVALID
;
6877 sname
= talloc_strndup(mem_ctx
, sname
, PTR_DIFF(stype
, sname
));
6881 if (sname
== NULL
) {
6883 return NT_STATUS_NO_MEMORY
;
6886 if (sname
[0] == '\0') {
6888 * no stream name, so no stream
6893 if (pstream
!= NULL
) {
6894 stream
= talloc_asprintf(mem_ctx
, "%s:%s", sname
, stype
);
6895 if (stream
== NULL
) {
6898 return NT_STATUS_NO_MEMORY
;
6901 * upper-case the type field
6903 strupper_m(strchr_m(stream
, ':')+1);
6907 if (pbase
!= NULL
) {
6910 if (pstream
!= NULL
) {
6913 return NT_STATUS_OK
;
6916 static bool test_stream_name(const char *fname
, const char *expected_base
,
6917 const char *expected_stream
,
6918 NTSTATUS expected_status
)
6922 char *stream
= NULL
;
6924 status
= split_ntfs_stream_name(talloc_tos(), fname
, &base
, &stream
);
6925 if (!NT_STATUS_EQUAL(status
, expected_status
)) {
6929 if (!NT_STATUS_IS_OK(status
)) {
6933 if (base
== NULL
) goto error
;
6935 if (strcmp(expected_base
, base
) != 0) goto error
;
6937 if ((expected_stream
!= NULL
) && (stream
== NULL
)) goto error
;
6938 if ((expected_stream
== NULL
) && (stream
!= NULL
)) goto error
;
6940 if ((stream
!= NULL
) && (strcmp(expected_stream
, stream
) != 0))
6944 TALLOC_FREE(stream
);
6948 d_fprintf(stderr
, "test_stream(%s, %s, %s, %s)\n",
6949 fname
, expected_base
? expected_base
: "<NULL>",
6950 expected_stream
? expected_stream
: "<NULL>",
6951 nt_errstr(expected_status
));
6952 d_fprintf(stderr
, "-> base=%s, stream=%s, status=%s\n",
6953 base
? base
: "<NULL>", stream
? stream
: "<NULL>",
6956 TALLOC_FREE(stream
);
6960 static bool run_local_stream_name(int dummy
)
6964 ret
&= test_stream_name(
6965 "bla", "bla", NULL
, NT_STATUS_OK
);
6966 ret
&= test_stream_name(
6967 "bla::$DATA", "bla", NULL
, NT_STATUS_OK
);
6968 ret
&= test_stream_name(
6969 "bla:blub:", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6970 ret
&= test_stream_name(
6971 "bla::", NULL
, NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6972 ret
&= test_stream_name(
6973 "bla::123", "bla", NULL
, NT_STATUS_OBJECT_NAME_INVALID
);
6974 ret
&= test_stream_name(
6975 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK
);
6976 ret
&= test_stream_name(
6977 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK
);
6978 ret
&= test_stream_name(
6979 "bla:x", "bla", "x:$DATA", NT_STATUS_OK
);
6984 static bool data_blob_equal(DATA_BLOB a
, DATA_BLOB b
)
6986 if (a
.length
!= b
.length
) {
6987 printf("a.length=%d != b.length=%d\n",
6988 (int)a
.length
, (int)b
.length
);
6991 if (memcmp(a
.data
, b
.data
, a
.length
) != 0) {
6992 printf("a.data and b.data differ\n");
6998 static bool run_local_memcache(int dummy
)
7000 struct memcache
*cache
;
7002 DATA_BLOB d1
, d2
, d3
;
7003 DATA_BLOB v1
, v2
, v3
;
7005 TALLOC_CTX
*mem_ctx
;
7007 size_t size1
, size2
;
7010 cache
= memcache_init(NULL
, 100);
7012 if (cache
== NULL
) {
7013 printf("memcache_init failed\n");
7017 d1
= data_blob_const("d1", 2);
7018 d2
= data_blob_const("d2", 2);
7019 d3
= data_blob_const("d3", 2);
7021 k1
= data_blob_const("d1", 2);
7022 k2
= data_blob_const("d2", 2);
7024 memcache_add(cache
, STAT_CACHE
, k1
, d1
);
7025 memcache_add(cache
, GETWD_CACHE
, k2
, d2
);
7027 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v1
)) {
7028 printf("could not find k1\n");
7031 if (!data_blob_equal(d1
, v1
)) {
7035 if (!memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7036 printf("could not find k2\n");
7039 if (!data_blob_equal(d2
, v2
)) {
7043 memcache_add(cache
, STAT_CACHE
, k1
, d3
);
7045 if (!memcache_lookup(cache
, STAT_CACHE
, k1
, &v3
)) {
7046 printf("could not find replaced k1\n");
7049 if (!data_blob_equal(d3
, v3
)) {
7053 memcache_add(cache
, GETWD_CACHE
, k1
, d1
);
7055 if (memcache_lookup(cache
, GETWD_CACHE
, k2
, &v2
)) {
7056 printf("Did find k2, should have been purged\n");
7062 cache
= memcache_init(NULL
, 0);
7064 mem_ctx
= talloc_init("foo");
7066 str1
= talloc_strdup(mem_ctx
, "string1");
7067 str2
= talloc_strdup(mem_ctx
, "string2");
7069 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7070 data_blob_string_const("torture"), &str1
);
7071 size1
= talloc_total_size(cache
);
7073 memcache_add_talloc(cache
, SINGLETON_CACHE_TALLOC
,
7074 data_blob_string_const("torture"), &str2
);
7075 size2
= talloc_total_size(cache
);
7077 printf("size1=%d, size2=%d\n", (int)size1
, (int)size2
);
7079 if (size2
> size1
) {
7080 printf("memcache leaks memory!\n");
7090 static void wbclient_done(struct tevent_req
*req
)
7093 struct winbindd_response
*wb_resp
;
7094 int *i
= (int *)tevent_req_callback_data_void(req
);
7096 wbc_err
= wb_trans_recv(req
, req
, &wb_resp
);
7099 d_printf("wb_trans_recv %d returned %s\n", *i
, wbcErrorString(wbc_err
));
7102 static bool run_local_wbclient(int dummy
)
7104 struct event_context
*ev
;
7105 struct wb_context
**wb_ctx
;
7106 struct winbindd_request wb_req
;
7107 bool result
= false;
7110 BlockSignals(True
, SIGPIPE
);
7112 ev
= tevent_context_init_byname(talloc_tos(), "epoll");
7117 wb_ctx
= TALLOC_ARRAY(ev
, struct wb_context
*, nprocs
);
7118 if (wb_ctx
== NULL
) {
7122 ZERO_STRUCT(wb_req
);
7123 wb_req
.cmd
= WINBINDD_PING
;
7125 d_printf("nprocs=%d, numops=%d\n", (int)nprocs
, (int)torture_numops
);
7127 for (i
=0; i
<nprocs
; i
++) {
7128 wb_ctx
[i
] = wb_context_init(ev
, NULL
);
7129 if (wb_ctx
[i
] == NULL
) {
7132 for (j
=0; j
<torture_numops
; j
++) {
7133 struct tevent_req
*req
;
7134 req
= wb_trans_send(ev
, ev
, wb_ctx
[i
],
7135 (j
% 2) == 0, &wb_req
);
7139 tevent_req_set_callback(req
, wbclient_done
, &i
);
7145 while (i
< nprocs
* torture_numops
) {
7146 event_loop_once(ev
);
7155 static void getaddrinfo_finished(struct tevent_req
*req
)
7157 char *name
= (char *)tevent_req_callback_data_void(req
);
7158 struct addrinfo
*ainfo
;
7161 res
= getaddrinfo_recv(req
, &ainfo
);
7163 d_printf("gai(%s) returned %s\n", name
, gai_strerror(res
));
7166 d_printf("gai(%s) succeeded\n", name
);
7167 freeaddrinfo(ainfo
);
7170 static bool run_getaddrinfo_send(int dummy
)
7172 TALLOC_CTX
*frame
= talloc_stackframe();
7173 struct fncall_context
*ctx
;
7174 struct tevent_context
*ev
;
7175 bool result
= false;
7176 const char *names
[4] = { "www.samba.org", "notfound.samba.org",
7177 "www.slashdot.org", "heise.de" };
7178 struct tevent_req
*reqs
[4];
7181 ev
= event_context_init(frame
);
7186 ctx
= fncall_context_init(frame
, 4);
7188 for (i
=0; i
<ARRAY_SIZE(names
); i
++) {
7189 reqs
[i
] = getaddrinfo_send(frame
, ev
, ctx
, names
[i
], NULL
,
7191 if (reqs
[i
] == NULL
) {
7194 tevent_req_set_callback(reqs
[i
], getaddrinfo_finished
,
7198 for (i
=0; i
<ARRAY_SIZE(reqs
); i
++) {
7199 tevent_loop_once(ev
);
7208 static bool dbtrans_inc(struct db_context
*db
)
7210 struct db_record
*rec
;
7215 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7217 printf(__location__
"fetch_lock failed\n");
7221 if (rec
->value
.dsize
!= sizeof(uint32_t)) {
7222 printf(__location__
"value.dsize = %d\n",
7223 (int)rec
->value
.dsize
);
7227 val
= (uint32_t *)rec
->value
.dptr
;
7230 status
= rec
->store(rec
, make_tdb_data((uint8_t *)val
,
7233 if (!NT_STATUS_IS_OK(status
)) {
7234 printf(__location__
"store failed: %s\n",
7245 static bool run_local_dbtrans(int dummy
)
7247 struct db_context
*db
;
7248 struct db_record
*rec
;
7253 db
= db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT
,
7254 O_RDWR
|O_CREAT
, 0600);
7256 printf("Could not open transtest.db\n");
7260 res
= db
->transaction_start(db
);
7262 printf(__location__
"transaction_start failed\n");
7266 rec
= db
->fetch_locked(db
, db
, string_term_tdb_data("transtest"));
7268 printf(__location__
"fetch_lock failed\n");
7272 if (rec
->value
.dptr
== NULL
) {
7274 status
= rec
->store(
7275 rec
, make_tdb_data((uint8_t *)&initial
,
7278 if (!NT_STATUS_IS_OK(status
)) {
7279 printf(__location__
"store returned %s\n",
7287 res
= db
->transaction_commit(db
);
7289 printf(__location__
"transaction_commit failed\n");
7297 res
= db
->transaction_start(db
);
7299 printf(__location__
"transaction_start failed\n");
7303 if (!dbwrap_fetch_uint32(db
, "transtest", &val
)) {
7304 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7308 for (i
=0; i
<10; i
++) {
7309 if (!dbtrans_inc(db
)) {
7314 if (!dbwrap_fetch_uint32(db
, "transtest", &val2
)) {
7315 printf(__location__
"dbwrap_fetch_uint32 failed\n");
7319 if (val2
!= val
+ 10) {
7320 printf(__location__
"val=%d, val2=%d\n",
7321 (int)val
, (int)val2
);
7325 printf("val2=%d\r", val2
);
7327 res
= db
->transaction_commit(db
);
7329 printf(__location__
"transaction_commit failed\n");
7338 static double create_procs(bool (*fn
)(int), bool *result
)
7341 volatile pid_t
*child_status
;
7342 volatile bool *child_status_out
;
7345 struct timeval start
;
7349 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
7350 if (!child_status
) {
7351 printf("Failed to setup shared memory\n");
7355 child_status_out
= (volatile bool *)shm_setup(sizeof(bool)*nprocs
);
7356 if (!child_status_out
) {
7357 printf("Failed to setup result status shared memory\n");
7361 for (i
= 0; i
< nprocs
; i
++) {
7362 child_status
[i
] = 0;
7363 child_status_out
[i
] = True
;
7366 start
= timeval_current();
7368 for (i
=0;i
<nprocs
;i
++) {
7371 pid_t mypid
= getpid();
7372 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
7374 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
7377 if (torture_open_connection(¤t_cli
, i
)) break;
7379 printf("pid %d failed to start\n", (int)getpid());
7385 child_status
[i
] = getpid();
7387 while (child_status
[i
] && timeval_elapsed(&start
) < 5) smb_msleep(2);
7389 child_status_out
[i
] = fn(i
);
7396 for (i
=0;i
<nprocs
;i
++) {
7397 if (child_status
[i
]) synccount
++;
7399 if (synccount
== nprocs
) break;
7401 } while (timeval_elapsed(&start
) < 30);
7403 if (synccount
!= nprocs
) {
7404 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
7406 return timeval_elapsed(&start
);
7409 /* start the client load */
7410 start
= timeval_current();
7412 for (i
=0;i
<nprocs
;i
++) {
7413 child_status
[i
] = 0;
7416 printf("%d clients started\n", nprocs
);
7418 for (i
=0;i
<nprocs
;i
++) {
7419 while (waitpid(0, &status
, 0) == -1 && errno
== EINTR
) /* noop */ ;
7424 for (i
=0;i
<nprocs
;i
++) {
7425 if (!child_status_out
[i
]) {
7429 return timeval_elapsed(&start
);
7432 #define FLAG_MULTIPROC 1
7439 {"FDPASS", run_fdpasstest
, 0},
7440 {"LOCK1", run_locktest1
, 0},
7441 {"LOCK2", run_locktest2
, 0},
7442 {"LOCK3", run_locktest3
, 0},
7443 {"LOCK4", run_locktest4
, 0},
7444 {"LOCK5", run_locktest5
, 0},
7445 {"LOCK6", run_locktest6
, 0},
7446 {"LOCK7", run_locktest7
, 0},
7447 {"LOCK8", run_locktest8
, 0},
7448 {"LOCK9", run_locktest9
, 0},
7449 {"UNLINK", run_unlinktest
, 0},
7450 {"BROWSE", run_browsetest
, 0},
7451 {"ATTR", run_attrtest
, 0},
7452 {"TRANS2", run_trans2test
, 0},
7453 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
7454 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
7455 {"RANDOMIPC", run_randomipc
, 0},
7456 {"NEGNOWAIT", run_negprot_nowait
, 0},
7457 {"NBENCH", run_nbench
, 0},
7458 {"OPLOCK1", run_oplock1
, 0},
7459 {"OPLOCK2", run_oplock2
, 0},
7460 {"OPLOCK3", run_oplock3
, 0},
7461 {"DIR", run_dirtest
, 0},
7462 {"DIR1", run_dirtest1
, 0},
7463 {"DIR-CREATETIME", run_dir_createtime
, 0},
7464 {"DENY1", torture_denytest1
, 0},
7465 {"DENY2", torture_denytest2
, 0},
7466 {"TCON", run_tcon_test
, 0},
7467 {"TCONDEV", run_tcon_devtype_test
, 0},
7468 {"RW1", run_readwritetest
, 0},
7469 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
7470 {"RW3", run_readwritelarge
, 0},
7471 {"OPEN", run_opentest
, 0},
7472 {"POSIX", run_simple_posix_open_test
, 0},
7473 {"POSIX-APPEND", run_posix_append
, 0},
7474 { "UID-REGRESSION-TEST", run_uid_regression_test
, 0},
7475 { "SHORTNAME-TEST", run_shortname_test
, 0},
7477 {"OPENATTR", run_openattrtest
, 0},
7479 {"XCOPY", run_xcopy
, 0},
7480 {"RENAME", run_rename
, 0},
7481 {"DELETE", run_deletetest
, 0},
7482 {"PROPERTIES", run_properties
, 0},
7483 {"MANGLE", torture_mangle
, 0},
7484 {"MANGLE1", run_mangle1
, 0},
7485 {"W2K", run_w2ktest
, 0},
7486 {"TRANS2SCAN", torture_trans2_scan
, 0},
7487 {"NTTRANSSCAN", torture_nttrans_scan
, 0},
7488 {"UTABLE", torture_utable
, 0},
7489 {"CASETABLE", torture_casetable
, 0},
7490 {"ERRMAPEXTRACT", run_error_map_extract
, 0},
7491 {"PIPE_NUMBER", run_pipe_number
, 0},
7492 {"TCON2", run_tcon2_test
, 0},
7493 {"IOCTL", torture_ioctl_test
, 0},
7494 {"CHKPATH", torture_chkpath_test
, 0},
7495 {"FDSESS", run_fdsesstest
, 0},
7496 { "EATEST", run_eatest
, 0},
7497 { "SESSSETUP_BENCH", run_sesssetup_bench
, 0},
7498 { "CHAIN1", run_chain1
, 0},
7499 { "CHAIN2", run_chain2
, 0},
7500 { "WINDOWS-WRITE", run_windows_write
, 0},
7501 { "CLI_ECHO", run_cli_echo
, 0},
7502 { "GETADDRINFO", run_getaddrinfo_send
, 0},
7503 { "TLDAP", run_tldap
},
7504 { "STREAMERROR", run_streamerror
},
7505 { "NOTIFY-BENCH", run_notify_bench
},
7506 { "LOCAL-SUBSTITUTE", run_local_substitute
, 0},
7507 { "LOCAL-GENCACHE", run_local_gencache
, 0},
7508 { "LOCAL-TALLOC-DICT", run_local_talloc_dict
, 0},
7509 { "LOCAL-BASE64", run_local_base64
, 0},
7510 { "LOCAL-RBTREE", run_local_rbtree
, 0},
7511 { "LOCAL-MEMCACHE", run_local_memcache
, 0},
7512 { "LOCAL-STREAM-NAME", run_local_stream_name
, 0},
7513 { "LOCAL-WBCLIENT", run_local_wbclient
, 0},
7514 { "LOCAL-string_to_sid", run_local_string_to_sid
, 0},
7515 { "LOCAL-DBTRANS", run_local_dbtrans
, 0},
7520 /****************************************************************************
7521 run a specified test or "ALL"
7522 ****************************************************************************/
7523 static bool run_test(const char *name
)
7530 if (strequal(name
,"ALL")) {
7531 for (i
=0;torture_ops
[i
].name
;i
++) {
7532 run_test(torture_ops
[i
].name
);
7537 for (i
=0;torture_ops
[i
].name
;i
++) {
7538 fstr_sprintf(randomfname
, "\\XX%x",
7539 (unsigned)random());
7541 if (strequal(name
, torture_ops
[i
].name
)) {
7543 printf("Running %s\n", name
);
7544 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
7545 t
= create_procs(torture_ops
[i
].fn
, &result
);
7548 printf("TEST %s FAILED!\n", name
);
7551 struct timeval start
;
7552 start
= timeval_current();
7553 if (!torture_ops
[i
].fn(0)) {
7555 printf("TEST %s FAILED!\n", name
);
7557 t
= timeval_elapsed(&start
);
7559 printf("%s took %g secs\n\n", name
, t
);
7564 printf("Did not find a test named %s\n", name
);
7572 static void usage(void)
7576 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7577 printf("Please use samba4 torture.\n\n");
7579 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7581 printf("\t-d debuglevel\n");
7582 printf("\t-U user%%pass\n");
7583 printf("\t-k use kerberos\n");
7584 printf("\t-N numprocs\n");
7585 printf("\t-n my_netbios_name\n");
7586 printf("\t-W workgroup\n");
7587 printf("\t-o num_operations\n");
7588 printf("\t-O socket_options\n");
7589 printf("\t-m maximum protocol\n");
7590 printf("\t-L use oplocks\n");
7591 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7592 printf("\t-A showall\n");
7593 printf("\t-p port\n");
7594 printf("\t-s seed\n");
7595 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7598 printf("tests are:");
7599 for (i
=0;torture_ops
[i
].name
;i
++) {
7600 printf(" %s", torture_ops
[i
].name
);
7604 printf("default test is ALL\n");
7609 /****************************************************************************
7611 ****************************************************************************/
7612 int main(int argc
,char *argv
[])
7618 bool correct
= True
;
7619 TALLOC_CTX
*frame
= talloc_stackframe();
7620 int seed
= time(NULL
);
7624 #ifdef HAVE_SETBUFFER
7625 setbuffer(stdout
, NULL
, 0);
7630 setup_logging("smbtorture", true);
7632 if (is_default_dyn_CONFIGFILE()) {
7633 if(getenv("SMB_CONF_PATH")) {
7634 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7637 lp_load(get_dyn_CONFIGFILE(),True
,False
,False
,True
);
7644 for(p
= argv
[1]; *p
; p
++)
7648 if (strncmp(argv
[1], "//", 2)) {
7652 fstrcpy(host
, &argv
[1][2]);
7653 p
= strchr_m(&host
[2],'/');
7658 fstrcpy(share
, p
+1);
7660 fstrcpy(myname
, get_myname(talloc_tos()));
7662 fprintf(stderr
, "Failed to get my hostname.\n");
7666 if (*username
== 0 && getenv("LOGNAME")) {
7667 fstrcpy(username
,getenv("LOGNAME"));
7673 fstrcpy(workgroup
, lp_workgroup());
7675 while ((opt
= getopt(argc
, argv
, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF
) {
7678 port_to_use
= atoi(optarg
);
7681 seed
= atoi(optarg
);
7684 fstrcpy(workgroup
,optarg
);
7687 max_protocol
= interpret_protocol(optarg
, max_protocol
);
7690 nprocs
= atoi(optarg
);
7693 torture_numops
= atoi(optarg
);
7696 DEBUGLEVEL
= atoi(optarg
);
7705 local_path
= optarg
;
7708 torture_showall
= True
;
7711 fstrcpy(myname
, optarg
);
7714 client_txt
= optarg
;
7721 use_kerberos
= True
;
7723 d_printf("No kerberos support compiled in\n");
7729 fstrcpy(username
,optarg
);
7730 p
= strchr_m(username
,'%');
7733 fstrcpy(password
, p
+1);
7738 fstrcpy(multishare_conn_fname
, optarg
);
7739 use_multishare_conn
= True
;
7742 torture_blocksize
= atoi(optarg
);
7745 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
7750 d_printf("using seed %d\n", seed
);
7754 if(use_kerberos
&& !gotuser
) gotpass
= True
;
7757 p
= getpass("Password:");
7759 fstrcpy(password
, p
);
7764 printf("host=%s share=%s user=%s myname=%s\n",
7765 host
, share
, username
, myname
);
7767 if (argc
== optind
) {
7768 correct
= run_test("ALL");
7770 for (i
=optind
;i
<argc
;i
++) {
7771 if (!run_test(argv
[i
])) {