2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "talloc_dict.h"
34 #include "async_smb.h"
35 #include "libsmb/libsmb.h"
36 #include "libsmb/clirap.h"
38 #include "libsmb/nmblib.h"
39 #include "../lib/util/tevent_ntstatus.h"
41 #include "libsmb/read_smb.h"
46 fstring host, workgroup, share, password, username, myname;
47 static int max_protocol = PROTOCOL_NT1;
48 static const char *sockops="TCP_NODELAY";
50 static int port_to_use=0;
51 int torture_numops=100;
52 int torture_blocksize=1024*1024;
53 static int procnum; /* records process count number when forking */
54 static struct cli_state *current_cli;
55 static fstring randomfname;
56 static bool use_oplocks;
57 static bool use_level_II_oplocks;
58 static const char *client_txt = "client_oplocks.txt";
59 static bool use_kerberos;
60 static bool force_dos_errors;
61 static fstring multishare_conn_fname;
62 static bool use_multishare_conn = False;
63 static bool do_encrypt;
64 static const char *local_path = NULL;
65 static int signing_state = Undefined;
68 bool torture_showall = False;
70 static double create_procs(bool (*fn)(int), bool *result);
73 /* return a pointer to a anonymous shared memory segment of size "size"
74 which will persist across fork() but will disappear when all processes
77 The memory is not zeroed
79 This function uses system5 shared memory. It takes advantage of a property
80 that the memory is not destroyed if it is attached when the id is removed
82 void *shm_setup(int size)
88 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
90 printf("can't get shared memory\n");
93 shm_unlink("private");
94 if (ftruncate(shmid, size) == -1) {
95 printf("can't set shared memory size\n");
98 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
99 if (ret == MAP_FAILED) {
100 printf("can't map shared memory\n");
104 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
106 printf("can't get shared memory\n");
109 ret = (void *)shmat(shmid, 0, 0);
110 if (!ret || ret == (void *)-1) {
111 printf("can't attach to shared memory\n");
114 /* the following releases the ipc, but note that this process
115 and all its children will still have access to the memory, its
116 just that the shmid is no longer valid for other shm calls. This
117 means we don't leave behind lots of shm segments after we exit
119 See Stevens "advanced programming in unix env" for details
121 shmctl(shmid, IPC_RMID, 0);
127 /********************************************************************
128 Ensure a connection is encrypted.
129 ********************************************************************/
131 static bool force_cli_encryption(struct cli_state *c,
132 const char *sharename)
135 uint32 caplow, caphigh;
138 if (!SERVER_HAS_UNIX_CIFS(c)) {
139 d_printf("Encryption required and "
140 "server that doesn't support "
141 "UNIX extensions - failing connect\n");
145 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
147 if (!NT_STATUS_IS_OK(status)) {
148 d_printf("Encryption required and "
149 "can't get UNIX CIFS extensions "
150 "version from server: %s\n", nt_errstr(status));
154 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
155 d_printf("Encryption required and "
156 "share %s doesn't support "
157 "encryption.\n", sharename);
161 if (c->use_kerberos) {
162 status = cli_gss_smb_encryption_start(c);
164 status = cli_raw_ntlm_smb_encryption_start(c,
170 if (!NT_STATUS_IS_OK(status)) {
171 d_printf("Encryption required and "
172 "setup failed with error %s.\n",
181 static struct cli_state *open_nbt_connection(void)
188 flags |= CLI_FULL_CONNECTION_OPLOCKS;
191 if (use_level_II_oplocks) {
192 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
196 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
199 if (force_dos_errors) {
200 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
203 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
204 signing_state, flags, &c);
205 if (!NT_STATUS_IS_OK(status)) {
206 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
210 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
215 /****************************************************************************
216 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
217 ****************************************************************************/
219 static bool cli_bad_session_request(int fd,
220 struct nmb_name *calling, struct nmb_name *called)
229 uint8_t message_type;
232 frame = talloc_stackframe();
234 iov[0].iov_base = len_buf;
235 iov[0].iov_len = sizeof(len_buf);
237 /* put in the destination name */
239 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
241 if (iov[1].iov_base == NULL) {
244 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
245 talloc_get_size(iov[1].iov_base));
249 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
251 if (iov[2].iov_base == NULL) {
254 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
255 talloc_get_size(iov[2].iov_base));
257 /* Deliberately corrupt the name len (first byte) */
258 *((uint8_t *)iov[2].iov_base) = 100;
260 /* send a session request (RFC 1002) */
261 /* setup the packet length
262 * Remove four bytes from the length count, since the length
263 * field in the NBT Session Service header counts the number
264 * of bytes which follow. The cli_send_smb() function knows
265 * about this and accounts for those four bytes.
269 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
270 SCVAL(len_buf,0,0x81);
272 len = write_data_iov(fd, iov, 3);
276 len = read_smb(fd, talloc_tos(), &inbuf, &err);
282 message_type = CVAL(inbuf, 0);
283 if (message_type != 0x83) {
284 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
289 if (smb_len(inbuf) != 1) {
290 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
291 (int)smb_len(inbuf));
295 error = CVAL(inbuf, 4);
297 d_fprintf(stderr, "Expected error 0x82, got %d\n",
308 /* Insert a NULL at the first separator of the given path and return a pointer
309 * to the remainder of the string.
312 terminate_path_at_separator(char * path)
320 if ((p = strchr_m(path, '/'))) {
325 if ((p = strchr_m(path, '\\'))) {
335 parse a //server/share type UNC name
337 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
338 char **hostname, char **sharename)
342 *hostname = *sharename = NULL;
344 if (strncmp(unc_name, "\\\\", 2) &&
345 strncmp(unc_name, "//", 2)) {
349 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
350 p = terminate_path_at_separator(*hostname);
353 *sharename = talloc_strdup(mem_ctx, p);
354 terminate_path_at_separator(*sharename);
357 if (*hostname && *sharename) {
361 TALLOC_FREE(*hostname);
362 TALLOC_FREE(*sharename);
366 static bool torture_open_connection_share(struct cli_state **c,
367 const char *hostname,
368 const char *sharename)
374 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
376 flags |= CLI_FULL_CONNECTION_OPLOCKS;
377 if (use_level_II_oplocks)
378 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
380 status = cli_full_connection(c, myname,
381 hostname, NULL, port_to_use,
384 password, flags, signing_state);
385 if (!NT_STATUS_IS_OK(status)) {
386 printf("failed to open share connection: //%s/%s port:%d - %s\n",
387 hostname, sharename, port_to_use, nt_errstr(status));
391 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
394 return force_cli_encryption(*c,
400 bool torture_open_connection(struct cli_state **c, int conn_index)
402 char **unc_list = NULL;
403 int num_unc_names = 0;
406 if (use_multishare_conn==True) {
408 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
409 if (!unc_list || num_unc_names <= 0) {
410 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
414 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
416 printf("Failed to parse UNC name %s\n",
417 unc_list[conn_index % num_unc_names]);
418 TALLOC_FREE(unc_list);
422 result = torture_open_connection_share(c, h, s);
424 /* h, s were copied earlier */
425 TALLOC_FREE(unc_list);
429 return torture_open_connection_share(c, host, share);
432 bool torture_init_connection(struct cli_state **pcli)
434 struct cli_state *cli;
436 cli = open_nbt_connection();
445 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
447 uint16_t old_vuid = cli_state_get_uid(cli);
448 fstring old_user_name;
449 size_t passlen = strlen(password);
453 fstrcpy(old_user_name, cli->user_name);
454 cli_state_set_uid(cli, 0);
455 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
459 *new_vuid = cli_state_get_uid(cli);
460 cli_state_set_uid(cli, old_vuid);
461 status = cli_set_username(cli, old_user_name);
462 if (!NT_STATUS_IS_OK(status)) {
469 bool torture_close_connection(struct cli_state *c)
474 status = cli_tdis(c);
475 if (!NT_STATUS_IS_OK(status)) {
476 printf("tdis failed (%s)\n", nt_errstr(status));
486 /* check if the server produced the expected dos or nt error code */
487 static bool check_both_error(int line, NTSTATUS status,
488 uint8 eclass, uint32 ecode, NTSTATUS nterr)
490 if (NT_STATUS_IS_DOS(status)) {
494 /* Check DOS error */
495 cclass = NT_STATUS_DOS_CLASS(status);
496 num = NT_STATUS_DOS_CODE(status);
498 if (eclass != cclass || ecode != num) {
499 printf("unexpected error code class=%d code=%d\n",
500 (int)cclass, (int)num);
501 printf(" expected %d/%d %s (line=%d)\n",
502 (int)eclass, (int)ecode, nt_errstr(nterr), line);
507 if (!NT_STATUS_EQUAL(nterr, status)) {
508 printf("unexpected error code %s\n",
510 printf(" expected %s (line=%d)\n",
511 nt_errstr(nterr), line);
520 /* check if the server produced the expected error code */
521 static bool check_error(int line, NTSTATUS status,
522 uint8 eclass, uint32 ecode, NTSTATUS nterr)
524 if (NT_STATUS_IS_DOS(status)) {
528 /* Check DOS error */
530 cclass = NT_STATUS_DOS_CLASS(status);
531 num = NT_STATUS_DOS_CODE(status);
533 if (eclass != cclass || ecode != num) {
534 printf("unexpected error code class=%d code=%d\n",
535 (int)cclass, (int)num);
536 printf(" expected %d/%d %s (line=%d)\n",
537 (int)eclass, (int)ecode, nt_errstr(nterr),
545 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
546 printf("unexpected error code %s\n",
548 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
558 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
562 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
564 while (!NT_STATUS_IS_OK(status)) {
565 if (!check_both_error(__LINE__, status, ERRDOS,
566 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
570 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
577 static bool rw_torture(struct cli_state *c)
579 const char *lockfname = "\\torture.lck";
583 pid_t pid2, pid = getpid();
590 memset(buf, '\0', sizeof(buf));
592 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
594 if (!NT_STATUS_IS_OK(status)) {
595 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("open of %s failed (%s)\n",
599 lockfname, nt_errstr(status));
603 for (i=0;i<torture_numops;i++) {
604 unsigned n = (unsigned)sys_random()%10;
607 printf("%d\r", i); fflush(stdout);
609 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
611 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
615 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
617 if (!NT_STATUS_IS_OK(status)) {
618 printf("open failed (%s)\n", nt_errstr(status));
623 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
625 if (!NT_STATUS_IS_OK(status)) {
626 printf("write failed (%s)\n", nt_errstr(status));
631 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
632 sizeof(pid)+(j*sizeof(buf)),
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("write failed (%s)\n",
643 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
645 if (!NT_STATUS_IS_OK(status)) {
646 printf("read failed (%s)\n", nt_errstr(status));
648 } else if (nread != sizeof(pid)) {
649 printf("read/write compare failed: "
650 "recv %ld req %ld\n", (unsigned long)nread,
651 (unsigned long)sizeof(pid));
656 printf("data corruption!\n");
660 status = cli_close(c, fnum);
661 if (!NT_STATUS_IS_OK(status)) {
662 printf("close failed (%s)\n", nt_errstr(status));
666 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
667 if (!NT_STATUS_IS_OK(status)) {
668 printf("unlink failed (%s)\n", nt_errstr(status));
672 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("unlock failed (%s)\n", nt_errstr(status));
680 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
687 static bool run_torture(int dummy)
689 struct cli_state *cli;
694 cli_sockopt(cli, sockops);
696 ret = rw_torture(cli);
698 if (!torture_close_connection(cli)) {
705 static bool rw_torture3(struct cli_state *c, char *lockfname)
707 uint16_t fnum = (uint16_t)-1;
712 unsigned countprev = 0;
715 NTSTATUS status = NT_STATUS_OK;
718 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
720 SIVAL(buf, i, sys_random());
727 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
728 if (!NT_STATUS_IS_OK(status)) {
729 printf("unlink failed (%s) (normal, this file should "
730 "not exist)\n", nt_errstr(status));
733 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
735 if (!NT_STATUS_IS_OK(status)) {
736 printf("first open read/write of %s failed (%s)\n",
737 lockfname, nt_errstr(status));
743 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
745 status = cli_open(c, lockfname, O_RDONLY,
747 if (!NT_STATUS_IS_OK(status)) {
752 if (!NT_STATUS_IS_OK(status)) {
753 printf("second open read-only of %s failed (%s)\n",
754 lockfname, nt_errstr(status));
760 for (count = 0; count < sizeof(buf); count += sent)
762 if (count >= countprev) {
763 printf("%d %8d\r", i, count);
766 countprev += (sizeof(buf) / 20);
771 sent = ((unsigned)sys_random()%(20))+ 1;
772 if (sent > sizeof(buf) - count)
774 sent = sizeof(buf) - count;
777 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
779 if (!NT_STATUS_IS_OK(status)) {
780 printf("write failed (%s)\n",
787 status = cli_read(c, fnum, buf_rd+count, count,
788 sizeof(buf)-count, &sent);
789 if(!NT_STATUS_IS_OK(status)) {
790 printf("read failed offset:%d size:%ld (%s)\n",
791 count, (unsigned long)sizeof(buf)-count,
795 } else if (sent > 0) {
796 if (memcmp(buf_rd+count, buf+count, sent) != 0)
798 printf("read/write compare failed\n");
799 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
808 status = cli_close(c, fnum);
809 if (!NT_STATUS_IS_OK(status)) {
810 printf("close failed (%s)\n", nt_errstr(status));
817 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
819 const char *lockfname = "\\torture2.lck";
829 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
830 if (!NT_STATUS_IS_OK(status)) {
831 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
834 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("first open read/write of %s failed (%s)\n",
838 lockfname, nt_errstr(status));
842 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
843 if (!NT_STATUS_IS_OK(status)) {
844 printf("second open read-only of %s failed (%s)\n",
845 lockfname, nt_errstr(status));
846 cli_close(c1, fnum1);
850 for (i = 0; i < torture_numops; i++)
852 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
854 printf("%d\r", i); fflush(stdout);
857 generate_random_buffer((unsigned char *)buf, buf_size);
859 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
861 if (!NT_STATUS_IS_OK(status)) {
862 printf("write failed (%s)\n", nt_errstr(status));
867 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
868 if(!NT_STATUS_IS_OK(status)) {
869 printf("read failed (%s)\n", nt_errstr(status));
872 } else if (bytes_read != buf_size) {
873 printf("read failed\n");
874 printf("read %ld, expected %ld\n",
875 (unsigned long)bytes_read,
876 (unsigned long)buf_size);
881 if (memcmp(buf_rd, buf, buf_size) != 0)
883 printf("read/write compare failed\n");
889 status = cli_close(c2, fnum2);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("close failed (%s)\n", nt_errstr(status));
895 status = cli_close(c1, fnum1);
896 if (!NT_STATUS_IS_OK(status)) {
897 printf("close failed (%s)\n", nt_errstr(status));
901 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
902 if (!NT_STATUS_IS_OK(status)) {
903 printf("unlink failed (%s)\n", nt_errstr(status));
910 static bool run_readwritetest(int dummy)
912 struct cli_state *cli1, *cli2;
913 bool test1, test2 = False;
915 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
918 cli_sockopt(cli1, sockops);
919 cli_sockopt(cli2, sockops);
921 printf("starting readwritetest\n");
923 test1 = rw_torture2(cli1, cli2);
924 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
927 test2 = rw_torture2(cli1, cli1);
928 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
931 if (!torture_close_connection(cli1)) {
935 if (!torture_close_connection(cli2)) {
939 return (test1 && test2);
942 static bool run_readwritemulti(int dummy)
944 struct cli_state *cli;
949 cli_sockopt(cli, sockops);
951 printf("run_readwritemulti: fname %s\n", randomfname);
952 test = rw_torture3(cli, randomfname);
954 if (!torture_close_connection(cli)) {
961 static bool run_readwritelarge_internal(int max_xmit_k)
963 static struct cli_state *cli1;
965 const char *lockfname = "\\large.dat";
971 if (!torture_open_connection(&cli1, 0)) {
974 cli_sockopt(cli1, sockops);
975 memset(buf,'\0',sizeof(buf));
977 cli1->max_xmit = max_xmit_k*1024;
979 if (signing_state == Required) {
980 /* Horrible cheat to force
981 multiple signed outstanding
982 packets against a Samba server.
984 cli1->is_samba = false;
987 printf("starting readwritelarge_internal\n");
989 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
991 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
993 if (!NT_STATUS_IS_OK(status)) {
994 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
998 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
1000 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1002 if (!NT_STATUS_IS_OK(status)) {
1003 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1007 if (fsize == sizeof(buf))
1008 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1009 (unsigned long)fsize);
1011 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1012 (unsigned long)fsize);
1016 status = cli_close(cli1, fnum1);
1017 if (!NT_STATUS_IS_OK(status)) {
1018 printf("close failed (%s)\n", nt_errstr(status));
1022 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 printf("unlink failed (%s)\n", nt_errstr(status));
1028 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1030 if (!NT_STATUS_IS_OK(status)) {
1031 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1035 cli1->max_xmit = 4*1024;
1037 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1039 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1041 if (!NT_STATUS_IS_OK(status)) {
1042 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1046 if (fsize == sizeof(buf))
1047 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1048 (unsigned long)fsize);
1050 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1051 (unsigned long)fsize);
1056 /* ToDo - set allocation. JRA */
1057 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1058 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1061 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1063 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1067 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1070 status = cli_close(cli1, fnum1);
1071 if (!NT_STATUS_IS_OK(status)) {
1072 printf("close failed (%s)\n", nt_errstr(status));
1076 if (!torture_close_connection(cli1)) {
1082 static bool run_readwritelarge(int dummy)
1084 return run_readwritelarge_internal(128);
1087 static bool run_readwritelarge_signtest(int dummy)
1090 signing_state = Required;
1091 ret = run_readwritelarge_internal(2);
1092 signing_state = Undefined;
1099 #define ival(s) strtol(s, NULL, 0)
1101 /* run a test that simulates an approximate netbench client load */
1102 static bool run_netbench(int client)
1104 struct cli_state *cli;
1109 const char *params[20];
1110 bool correct = True;
1116 cli_sockopt(cli, sockops);
1120 slprintf(cname,sizeof(cname)-1, "client%d", client);
1122 f = fopen(client_txt, "r");
1129 while (fgets(line, sizeof(line)-1, f)) {
1133 line[strlen(line)-1] = 0;
1135 /* printf("[%d] %s\n", line_count, line); */
1137 all_string_sub(line,"client1", cname, sizeof(line));
1139 /* parse the command parameters */
1140 params[0] = strtok_r(line, " ", &saveptr);
1142 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1146 if (i < 2) continue;
1148 if (!strncmp(params[0],"SMB", 3)) {
1149 printf("ERROR: You are using a dbench 1 load file\n");
1153 if (!strcmp(params[0],"NTCreateX")) {
1154 nb_createx(params[1], ival(params[2]), ival(params[3]),
1156 } else if (!strcmp(params[0],"Close")) {
1157 nb_close(ival(params[1]));
1158 } else if (!strcmp(params[0],"Rename")) {
1159 nb_rename(params[1], params[2]);
1160 } else if (!strcmp(params[0],"Unlink")) {
1161 nb_unlink(params[1]);
1162 } else if (!strcmp(params[0],"Deltree")) {
1163 nb_deltree(params[1]);
1164 } else if (!strcmp(params[0],"Rmdir")) {
1165 nb_rmdir(params[1]);
1166 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1167 nb_qpathinfo(params[1]);
1168 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1169 nb_qfileinfo(ival(params[1]));
1170 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1171 nb_qfsinfo(ival(params[1]));
1172 } else if (!strcmp(params[0],"FIND_FIRST")) {
1173 nb_findfirst(params[1]);
1174 } else if (!strcmp(params[0],"WriteX")) {
1175 nb_writex(ival(params[1]),
1176 ival(params[2]), ival(params[3]), ival(params[4]));
1177 } else if (!strcmp(params[0],"ReadX")) {
1178 nb_readx(ival(params[1]),
1179 ival(params[2]), ival(params[3]), ival(params[4]));
1180 } else if (!strcmp(params[0],"Flush")) {
1181 nb_flush(ival(params[1]));
1183 printf("Unknown operation %s\n", params[0]);
1191 if (!torture_close_connection(cli)) {
1199 /* run a test that simulates an approximate netbench client load */
1200 static bool run_nbench(int dummy)
1203 bool correct = True;
1209 signal(SIGALRM, nb_alarm);
1211 t = create_procs(run_netbench, &correct);
1214 printf("\nThroughput %g MB/sec\n",
1215 1.0e-6 * nbio_total() / t);
1221 This test checks for two things:
1223 1) correct support for retaining locks over a close (ie. the server
1224 must not use posix semantics)
1225 2) support for lock timeouts
1227 static bool run_locktest1(int dummy)
1229 struct cli_state *cli1, *cli2;
1230 const char *fname = "\\lockt1.lck";
1231 uint16_t fnum1, fnum2, fnum3;
1233 unsigned lock_timeout;
1236 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1239 cli_sockopt(cli1, sockops);
1240 cli_sockopt(cli2, sockops);
1242 printf("starting locktest1\n");
1244 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1246 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1248 if (!NT_STATUS_IS_OK(status)) {
1249 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1253 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1259 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1265 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1266 if (!NT_STATUS_IS_OK(status)) {
1267 printf("lock1 failed (%s)\n", nt_errstr(status));
1271 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1272 if (NT_STATUS_IS_OK(status)) {
1273 printf("lock2 succeeded! This is a locking bug\n");
1276 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1277 NT_STATUS_LOCK_NOT_GRANTED)) {
1282 lock_timeout = (1 + (random() % 20));
1283 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1285 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1286 if (NT_STATUS_IS_OK(status)) {
1287 printf("lock3 succeeded! This is a locking bug\n");
1290 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1291 NT_STATUS_FILE_LOCK_CONFLICT)) {
1297 if (ABS(t2 - t1) < lock_timeout-1) {
1298 printf("error: This server appears not to support timed lock requests\n");
1301 printf("server slept for %u seconds for a %u second timeout\n",
1302 (unsigned int)(t2-t1), lock_timeout);
1304 status = cli_close(cli1, fnum2);
1305 if (!NT_STATUS_IS_OK(status)) {
1306 printf("close1 failed (%s)\n", nt_errstr(status));
1310 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1311 if (NT_STATUS_IS_OK(status)) {
1312 printf("lock4 succeeded! This is a locking bug\n");
1315 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1316 NT_STATUS_FILE_LOCK_CONFLICT)) {
1321 status = cli_close(cli1, fnum1);
1322 if (!NT_STATUS_IS_OK(status)) {
1323 printf("close2 failed (%s)\n", nt_errstr(status));
1327 status = cli_close(cli2, fnum3);
1328 if (!NT_STATUS_IS_OK(status)) {
1329 printf("close3 failed (%s)\n", nt_errstr(status));
1333 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1334 if (!NT_STATUS_IS_OK(status)) {
1335 printf("unlink failed (%s)\n", nt_errstr(status));
1340 if (!torture_close_connection(cli1)) {
1344 if (!torture_close_connection(cli2)) {
1348 printf("Passed locktest1\n");
1353 this checks to see if a secondary tconx can use open files from an
1356 static bool run_tcon_test(int dummy)
1358 static struct cli_state *cli;
1359 const char *fname = "\\tcontest.tmp";
1361 uint16 cnum1, cnum2, cnum3;
1362 uint16 vuid1, vuid2;
1367 memset(buf, '\0', sizeof(buf));
1369 if (!torture_open_connection(&cli, 0)) {
1372 cli_sockopt(cli, sockops);
1374 printf("starting tcontest\n");
1376 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1378 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1379 if (!NT_STATUS_IS_OK(status)) {
1380 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1384 cnum1 = cli_state_get_tid(cli);
1385 vuid1 = cli_state_get_uid(cli);
1387 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1388 if (!NT_STATUS_IS_OK(status)) {
1389 printf("initial write failed (%s)", nt_errstr(status));
1393 status = cli_tcon_andx(cli, share, "?????",
1394 password, strlen(password)+1);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 printf("%s refused 2nd tree connect (%s)\n", host,
1402 cnum2 = cli_state_get_tid(cli);
1403 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1404 vuid2 = cli_state_get_uid(cli) + 1;
1406 /* try a write with the wrong tid */
1407 cli_state_set_tid(cli, cnum2);
1409 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1410 if (NT_STATUS_IS_OK(status)) {
1411 printf("* server allows write with wrong TID\n");
1414 printf("server fails write with wrong TID : %s\n",
1419 /* try a write with an invalid tid */
1420 cli_state_set_tid(cli, cnum3);
1422 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1423 if (NT_STATUS_IS_OK(status)) {
1424 printf("* server allows write with invalid TID\n");
1427 printf("server fails write with invalid TID : %s\n",
1431 /* try a write with an invalid vuid */
1432 cli_state_set_uid(cli, vuid2);
1433 cli_state_set_tid(cli, cnum1);
1435 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1436 if (NT_STATUS_IS_OK(status)) {
1437 printf("* server allows write with invalid VUID\n");
1440 printf("server fails write with invalid VUID : %s\n",
1444 cli_state_set_tid(cli, cnum1);
1445 cli_state_set_uid(cli, vuid1);
1447 status = cli_close(cli, fnum1);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 printf("close failed (%s)\n", nt_errstr(status));
1453 cli_state_set_tid(cli, cnum2);
1455 status = cli_tdis(cli);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1461 cli_state_set_tid(cli, cnum1);
1463 if (!torture_close_connection(cli)) {
1472 checks for old style tcon support
1474 static bool run_tcon2_test(int dummy)
1476 static struct cli_state *cli;
1477 uint16 cnum, max_xmit;
1481 if (!torture_open_connection(&cli, 0)) {
1484 cli_sockopt(cli, sockops);
1486 printf("starting tcon2 test\n");
1488 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1492 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1496 if (!NT_STATUS_IS_OK(status)) {
1497 printf("tcon2 failed : %s\n", nt_errstr(status));
1499 printf("tcon OK : max_xmit=%d cnum=%d\n",
1500 (int)max_xmit, (int)cnum);
1503 if (!torture_close_connection(cli)) {
1507 printf("Passed tcon2 test\n");
1511 static bool tcon_devtest(struct cli_state *cli,
1512 const char *myshare, const char *devtype,
1513 const char *return_devtype,
1514 NTSTATUS expected_error)
1519 status = cli_tcon_andx(cli, myshare, devtype,
1520 password, strlen(password)+1);
1522 if (NT_STATUS_IS_OK(expected_error)) {
1523 if (NT_STATUS_IS_OK(status)) {
1524 if (strcmp(cli->dev, return_devtype) == 0) {
1527 printf("tconX to share %s with type %s "
1528 "succeeded but returned the wrong "
1529 "device type (got [%s] but should have got [%s])\n",
1530 myshare, devtype, cli->dev, return_devtype);
1534 printf("tconX to share %s with type %s "
1535 "should have succeeded but failed\n",
1541 if (NT_STATUS_IS_OK(status)) {
1542 printf("tconx to share %s with type %s "
1543 "should have failed but succeeded\n",
1547 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1551 printf("Returned unexpected error\n");
1560 checks for correct tconX support
1562 static bool run_tcon_devtype_test(int dummy)
1564 static struct cli_state *cli1 = NULL;
1569 status = cli_full_connection(&cli1, myname,
1570 host, NULL, port_to_use,
1572 username, workgroup,
1573 password, flags, signing_state);
1575 if (!NT_STATUS_IS_OK(status)) {
1576 printf("could not open connection\n");
1580 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1583 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1586 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1589 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1592 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1595 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1598 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1601 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1604 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1607 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1613 printf("Passed tcondevtest\n");
1620 This test checks that
1622 1) the server supports multiple locking contexts on the one SMB
1623 connection, distinguished by PID.
1625 2) the server correctly fails overlapping locks made by the same PID (this
1626 goes against POSIX behaviour, which is why it is tricky to implement)
1628 3) the server denies unlock requests by an incorrect client PID
1630 static bool run_locktest2(int dummy)
1632 static struct cli_state *cli;
1633 const char *fname = "\\lockt2.lck";
1634 uint16_t fnum1, fnum2, fnum3;
1635 bool correct = True;
1638 if (!torture_open_connection(&cli, 0)) {
1642 cli_sockopt(cli, sockops);
1644 printf("starting locktest2\n");
1646 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1650 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1651 if (!NT_STATUS_IS_OK(status)) {
1652 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1656 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1657 if (!NT_STATUS_IS_OK(status)) {
1658 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1664 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1665 if (!NT_STATUS_IS_OK(status)) {
1666 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1672 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1673 if (!NT_STATUS_IS_OK(status)) {
1674 printf("lock1 failed (%s)\n", nt_errstr(status));
1678 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1679 if (NT_STATUS_IS_OK(status)) {
1680 printf("WRITE lock1 succeeded! This is a locking bug\n");
1683 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1684 NT_STATUS_LOCK_NOT_GRANTED)) {
1689 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1690 if (NT_STATUS_IS_OK(status)) {
1691 printf("WRITE lock2 succeeded! This is a locking bug\n");
1694 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1695 NT_STATUS_LOCK_NOT_GRANTED)) {
1700 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1701 if (NT_STATUS_IS_OK(status)) {
1702 printf("READ lock2 succeeded! This is a locking bug\n");
1705 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1706 NT_STATUS_FILE_LOCK_CONFLICT)) {
1711 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1716 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1717 printf("unlock at 100 succeeded! This is a locking bug\n");
1721 status = cli_unlock(cli, fnum1, 0, 4);
1722 if (NT_STATUS_IS_OK(status)) {
1723 printf("unlock1 succeeded! This is a locking bug\n");
1726 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1727 NT_STATUS_RANGE_NOT_LOCKED)) {
1732 status = cli_unlock(cli, fnum1, 0, 8);
1733 if (NT_STATUS_IS_OK(status)) {
1734 printf("unlock2 succeeded! This is a locking bug\n");
1737 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1738 NT_STATUS_RANGE_NOT_LOCKED)) {
1743 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1744 if (NT_STATUS_IS_OK(status)) {
1745 printf("lock3 succeeded! This is a locking bug\n");
1748 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1749 NT_STATUS_LOCK_NOT_GRANTED)) {
1756 status = cli_close(cli, fnum1);
1757 if (!NT_STATUS_IS_OK(status)) {
1758 printf("close1 failed (%s)\n", nt_errstr(status));
1762 status = cli_close(cli, fnum2);
1763 if (!NT_STATUS_IS_OK(status)) {
1764 printf("close2 failed (%s)\n", nt_errstr(status));
1768 status = cli_close(cli, fnum3);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 printf("close3 failed (%s)\n", nt_errstr(status));
1774 if (!torture_close_connection(cli)) {
1778 printf("locktest2 finished\n");
1785 This test checks that
1787 1) the server supports the full offset range in lock requests
1789 static bool run_locktest3(int dummy)
1791 static struct cli_state *cli1, *cli2;
1792 const char *fname = "\\lockt3.lck";
1793 uint16_t fnum1, fnum2;
1796 bool correct = True;
1799 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1801 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1804 cli_sockopt(cli1, sockops);
1805 cli_sockopt(cli2, sockops);
1807 printf("starting locktest3\n");
1809 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1811 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1813 if (!NT_STATUS_IS_OK(status)) {
1814 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1818 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1819 if (!NT_STATUS_IS_OK(status)) {
1820 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1824 for (offset=i=0;i<torture_numops;i++) {
1827 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1828 if (!NT_STATUS_IS_OK(status)) {
1829 printf("lock1 %d failed (%s)\n",
1835 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1836 if (!NT_STATUS_IS_OK(status)) {
1837 printf("lock2 %d failed (%s)\n",
1844 for (offset=i=0;i<torture_numops;i++) {
1847 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1848 if (NT_STATUS_IS_OK(status)) {
1849 printf("error: lock1 %d succeeded!\n", i);
1853 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1854 if (NT_STATUS_IS_OK(status)) {
1855 printf("error: lock2 %d succeeded!\n", i);
1859 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1860 if (NT_STATUS_IS_OK(status)) {
1861 printf("error: lock3 %d succeeded!\n", i);
1865 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1866 if (NT_STATUS_IS_OK(status)) {
1867 printf("error: lock4 %d succeeded!\n", i);
1872 for (offset=i=0;i<torture_numops;i++) {
1875 status = cli_unlock(cli1, fnum1, offset-1, 1);
1876 if (!NT_STATUS_IS_OK(status)) {
1877 printf("unlock1 %d failed (%s)\n",
1883 status = cli_unlock(cli2, fnum2, offset-2, 1);
1884 if (!NT_STATUS_IS_OK(status)) {
1885 printf("unlock2 %d failed (%s)\n",
1892 status = cli_close(cli1, fnum1);
1893 if (!NT_STATUS_IS_OK(status)) {
1894 printf("close1 failed (%s)\n", nt_errstr(status));
1898 status = cli_close(cli2, fnum2);
1899 if (!NT_STATUS_IS_OK(status)) {
1900 printf("close2 failed (%s)\n", nt_errstr(status));
1904 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1905 if (!NT_STATUS_IS_OK(status)) {
1906 printf("unlink failed (%s)\n", nt_errstr(status));
1910 if (!torture_close_connection(cli1)) {
1914 if (!torture_close_connection(cli2)) {
1918 printf("finished locktest3\n");
1923 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1924 char *buf, off_t offset, size_t size,
1925 size_t *nread, size_t expect)
1930 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1932 if(!NT_STATUS_IS_OK(status)) {
1934 } else if (l_nread != expect) {
1945 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1946 printf("** "); correct = False; \
1950 looks at overlapping locks
1952 static bool run_locktest4(int dummy)
1954 static struct cli_state *cli1, *cli2;
1955 const char *fname = "\\lockt4.lck";
1956 uint16_t fnum1, fnum2, f;
1959 bool correct = True;
1962 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1966 cli_sockopt(cli1, sockops);
1967 cli_sockopt(cli2, sockops);
1969 printf("starting locktest4\n");
1971 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1973 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1974 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1976 memset(buf, 0, sizeof(buf));
1978 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1980 if (!NT_STATUS_IS_OK(status)) {
1981 printf("Failed to create file: %s\n", nt_errstr(status));
1986 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1987 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1988 EXPECTED(ret, False);
1989 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1991 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1992 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1993 EXPECTED(ret, True);
1994 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1996 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1998 EXPECTED(ret, False);
1999 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
2001 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
2002 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
2003 EXPECTED(ret, True);
2004 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
2006 ret = (cli_setpid(cli1, 1),
2007 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
2008 (cli_setpid(cli1, 2),
2009 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
2010 EXPECTED(ret, False);
2011 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
2013 ret = (cli_setpid(cli1, 1),
2014 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
2015 (cli_setpid(cli1, 2),
2016 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
2017 EXPECTED(ret, True);
2018 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
2020 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
2021 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
2022 EXPECTED(ret, True);
2023 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
2025 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
2026 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
2027 EXPECTED(ret, False);
2028 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
2030 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
2031 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
2032 EXPECTED(ret, False);
2033 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2035 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2036 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2037 EXPECTED(ret, True);
2038 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2040 ret = (cli_setpid(cli1, 1),
2041 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2042 (cli_setpid(cli1, 2),
2043 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2044 EXPECTED(ret, False);
2045 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2047 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2048 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2049 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2050 EXPECTED(ret, False);
2051 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2054 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2055 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2056 EXPECTED(ret, False);
2057 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2059 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2060 ret = NT_STATUS_IS_OK(status);
2062 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2064 ret = NT_STATUS_IS_OK(status);
2066 EXPECTED(ret, False);
2067 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2070 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2072 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2073 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2074 EXPECTED(ret, True);
2075 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2078 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2079 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2081 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2082 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2084 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2085 EXPECTED(ret, True);
2086 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2088 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2089 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2090 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2092 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2093 EXPECTED(ret, True);
2094 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2096 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2097 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2098 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2100 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2101 EXPECTED(ret, True);
2102 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2104 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2105 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2106 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2107 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2109 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2110 EXPECTED(ret, True);
2111 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2113 cli_close(cli1, fnum1);
2114 cli_close(cli2, fnum2);
2115 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2116 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2117 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2118 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2119 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2120 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2121 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2123 cli_close(cli1, fnum1);
2124 EXPECTED(ret, True);
2125 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2128 cli_close(cli1, fnum1);
2129 cli_close(cli2, fnum2);
2130 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2131 torture_close_connection(cli1);
2132 torture_close_connection(cli2);
2134 printf("finished locktest4\n");
2139 looks at lock upgrade/downgrade.
2141 static bool run_locktest5(int dummy)
2143 static struct cli_state *cli1, *cli2;
2144 const char *fname = "\\lockt5.lck";
2145 uint16_t fnum1, fnum2, fnum3;
2148 bool correct = True;
2151 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2155 cli_sockopt(cli1, sockops);
2156 cli_sockopt(cli2, sockops);
2158 printf("starting locktest5\n");
2160 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2162 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2163 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2164 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2166 memset(buf, 0, sizeof(buf));
2168 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2170 if (!NT_STATUS_IS_OK(status)) {
2171 printf("Failed to create file: %s\n", nt_errstr(status));
2176 /* Check for NT bug... */
2177 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2178 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2179 cli_close(cli1, fnum1);
2180 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2181 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2182 ret = NT_STATUS_IS_OK(status);
2183 EXPECTED(ret, True);
2184 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2185 cli_close(cli1, fnum1);
2186 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2187 cli_unlock(cli1, fnum3, 0, 1);
2189 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2190 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2191 EXPECTED(ret, True);
2192 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2194 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2195 ret = NT_STATUS_IS_OK(status);
2196 EXPECTED(ret, False);
2198 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2200 /* Unlock the process 2 lock. */
2201 cli_unlock(cli2, fnum2, 0, 4);
2203 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2204 ret = NT_STATUS_IS_OK(status);
2205 EXPECTED(ret, False);
2207 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2209 /* Unlock the process 1 fnum3 lock. */
2210 cli_unlock(cli1, fnum3, 0, 4);
2212 /* Stack 2 more locks here. */
2213 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2214 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2216 EXPECTED(ret, True);
2217 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2219 /* Unlock the first process lock, then check this was the WRITE lock that was
2222 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2223 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2225 EXPECTED(ret, True);
2226 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2228 /* Unlock the process 2 lock. */
2229 cli_unlock(cli2, fnum2, 0, 4);
2231 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2233 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2234 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2235 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2237 EXPECTED(ret, True);
2238 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2240 /* Ensure the next unlock fails. */
2241 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2242 EXPECTED(ret, False);
2243 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2245 /* Ensure connection 2 can get a write lock. */
2246 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2247 ret = NT_STATUS_IS_OK(status);
2248 EXPECTED(ret, True);
2250 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2254 cli_close(cli1, fnum1);
2255 cli_close(cli2, fnum2);
2256 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2257 if (!torture_close_connection(cli1)) {
2260 if (!torture_close_connection(cli2)) {
2264 printf("finished locktest5\n");
2270 tries the unusual lockingX locktype bits
2272 static bool run_locktest6(int dummy)
2274 static struct cli_state *cli;
2275 const char *fname[1] = { "\\lock6.txt" };
2280 if (!torture_open_connection(&cli, 0)) {
2284 cli_sockopt(cli, sockops);
2286 printf("starting locktest6\n");
2289 printf("Testing %s\n", fname[i]);
2291 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2293 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2294 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2295 cli_close(cli, fnum);
2296 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2298 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2299 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2300 cli_close(cli, fnum);
2301 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2303 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2306 torture_close_connection(cli);
2308 printf("finished locktest6\n");
2312 static bool run_locktest7(int dummy)
2314 struct cli_state *cli1;
2315 const char *fname = "\\lockt7.lck";
2318 bool correct = False;
2322 if (!torture_open_connection(&cli1, 0)) {
2326 cli_sockopt(cli1, sockops);
2328 printf("starting locktest7\n");
2330 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2332 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2334 memset(buf, 0, sizeof(buf));
2336 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2338 if (!NT_STATUS_IS_OK(status)) {
2339 printf("Failed to create file: %s\n", nt_errstr(status));
2343 cli_setpid(cli1, 1);
2345 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2346 if (!NT_STATUS_IS_OK(status)) {
2347 printf("Unable to apply read lock on range 130:4, "
2348 "error was %s\n", nt_errstr(status));
2351 printf("pid1 successfully locked range 130:4 for READ\n");
2354 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 printf("pid1 unable to read the range 130:4, error was %s\n",
2359 } else if (nread != 4) {
2360 printf("pid1 unable to read the range 130:4, "
2361 "recv %ld req %d\n", (unsigned long)nread, 4);
2364 printf("pid1 successfully read the range 130:4\n");
2367 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2368 if (!NT_STATUS_IS_OK(status)) {
2369 printf("pid1 unable to write to the range 130:4, error was "
2370 "%s\n", nt_errstr(status));
2371 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2372 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2376 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2380 cli_setpid(cli1, 2);
2382 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2383 if (!NT_STATUS_IS_OK(status)) {
2384 printf("pid2 unable to read the range 130:4, error was %s\n",
2387 } else if (nread != 4) {
2388 printf("pid2 unable to read the range 130:4, "
2389 "recv %ld req %d\n", (unsigned long)nread, 4);
2392 printf("pid2 successfully read the range 130:4\n");
2395 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2396 if (!NT_STATUS_IS_OK(status)) {
2397 printf("pid2 unable to write to the range 130:4, error was "
2398 "%s\n", nt_errstr(status));
2399 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2400 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2404 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2408 cli_setpid(cli1, 1);
2409 cli_unlock(cli1, fnum1, 130, 4);
2411 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2412 if (!NT_STATUS_IS_OK(status)) {
2413 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2416 printf("pid1 successfully locked range 130:4 for WRITE\n");
2419 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 printf("pid1 unable to read the range 130:4, error was %s\n",
2424 } else if (nread != 4) {
2425 printf("pid1 unable to read the range 130:4, "
2426 "recv %ld req %d\n", (unsigned long)nread, 4);
2429 printf("pid1 successfully read the range 130:4\n");
2432 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2433 if (!NT_STATUS_IS_OK(status)) {
2434 printf("pid1 unable to write to the range 130:4, error was "
2435 "%s\n", nt_errstr(status));
2438 printf("pid1 successfully wrote to the range 130:4\n");
2441 cli_setpid(cli1, 2);
2443 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 printf("pid2 unable to read the range 130:4, error was "
2446 "%s\n", nt_errstr(status));
2447 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2448 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2452 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2453 (unsigned long)nread);
2457 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2458 if (!NT_STATUS_IS_OK(status)) {
2459 printf("pid2 unable to write to the range 130:4, error was "
2460 "%s\n", nt_errstr(status));
2461 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2462 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2466 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2470 cli_unlock(cli1, fnum1, 130, 0);
2474 cli_close(cli1, fnum1);
2475 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2476 torture_close_connection(cli1);
2478 printf("finished locktest7\n");
2483 * This demonstrates a problem with our use of GPFS share modes: A file
2484 * descriptor sitting in the pending close queue holding a GPFS share mode
2485 * blocks opening a file another time. Happens with Word 2007 temp files.
2486 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2487 * open is denied with NT_STATUS_SHARING_VIOLATION.
2490 static bool run_locktest8(int dummy)
2492 struct cli_state *cli1;
2493 const char *fname = "\\lockt8.lck";
2494 uint16_t fnum1, fnum2;
2496 bool correct = False;
2499 if (!torture_open_connection(&cli1, 0)) {
2503 cli_sockopt(cli1, sockops);
2505 printf("starting locktest8\n");
2507 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2509 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2511 if (!NT_STATUS_IS_OK(status)) {
2512 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2516 memset(buf, 0, sizeof(buf));
2518 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 d_fprintf(stderr, "cli_open second time returned %s\n",
2525 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2526 if (!NT_STATUS_IS_OK(status)) {
2527 printf("Unable to apply read lock on range 1:1, error was "
2528 "%s\n", nt_errstr(status));
2532 status = cli_close(cli1, fnum1);
2533 if (!NT_STATUS_IS_OK(status)) {
2534 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2538 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2539 if (!NT_STATUS_IS_OK(status)) {
2540 d_fprintf(stderr, "cli_open third time returned %s\n",
2548 cli_close(cli1, fnum1);
2549 cli_close(cli1, fnum2);
2550 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2551 torture_close_connection(cli1);
2553 printf("finished locktest8\n");
2558 * This test is designed to be run in conjunction with
2559 * external NFS or POSIX locks taken in the filesystem.
2560 * It checks that the smbd server will block until the
2561 * lock is released and then acquire it. JRA.
2564 static bool got_alarm;
2565 static struct cli_state *alarm_cli;
2567 static void alarm_handler(int dummy)
2572 static void alarm_handler_parent(int dummy)
2574 cli_state_disconnect(alarm_cli);
2577 static void do_local_lock(int read_fd, int write_fd)
2582 const char *local_pathname = NULL;
2585 local_pathname = talloc_asprintf(talloc_tos(),
2586 "%s/lockt9.lck", local_path);
2587 if (!local_pathname) {
2588 printf("child: alloc fail\n");
2592 unlink(local_pathname);
2593 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2595 printf("child: open of %s failed %s.\n",
2596 local_pathname, strerror(errno));
2600 /* Now take a fcntl lock. */
2601 lock.l_type = F_WRLCK;
2602 lock.l_whence = SEEK_SET;
2605 lock.l_pid = getpid();
2607 ret = fcntl(fd,F_SETLK,&lock);
2609 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2610 local_pathname, strerror(errno));
2613 printf("child: got lock 0:4 on file %s.\n",
2618 CatchSignal(SIGALRM, alarm_handler);
2620 /* Signal the parent. */
2621 if (write(write_fd, &c, 1) != 1) {
2622 printf("child: start signal fail %s.\n",
2629 /* Wait for the parent to be ready. */
2630 if (read(read_fd, &c, 1) != 1) {
2631 printf("child: reply signal fail %s.\n",
2639 printf("child: released lock 0:4 on file %s.\n",
2645 static bool run_locktest9(int dummy)
2647 struct cli_state *cli1;
2648 const char *fname = "\\lockt9.lck";
2650 bool correct = False;
2651 int pipe_in[2], pipe_out[2];
2655 struct timeval start;
2659 printf("starting locktest9\n");
2661 if (local_path == NULL) {
2662 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2666 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2671 if (child_pid == -1) {
2675 if (child_pid == 0) {
2677 do_local_lock(pipe_out[0], pipe_in[1]);
2687 ret = read(pipe_in[0], &c, 1);
2689 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2694 if (!torture_open_connection(&cli1, 0)) {
2698 cli_sockopt(cli1, sockops);
2700 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2702 if (!NT_STATUS_IS_OK(status)) {
2703 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2707 /* Ensure the child has the lock. */
2708 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2709 if (NT_STATUS_IS_OK(status)) {
2710 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2713 d_printf("Child has the lock.\n");
2716 /* Tell the child to wait 5 seconds then exit. */
2717 ret = write(pipe_out[1], &c, 1);
2719 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2724 /* Wait 20 seconds for the lock. */
2726 CatchSignal(SIGALRM, alarm_handler_parent);
2729 start = timeval_current();
2731 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2732 if (!NT_STATUS_IS_OK(status)) {
2733 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2734 "%s\n", nt_errstr(status));
2739 seconds = timeval_elapsed(&start);
2741 printf("Parent got the lock after %.2f seconds.\n",
2744 status = cli_close(cli1, fnum);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2753 cli_close(cli1, fnum);
2754 torture_close_connection(cli1);
2758 printf("finished locktest9\n");
2763 test whether fnums and tids open on one VC are available on another (a major
2766 static bool run_fdpasstest(int dummy)
2768 struct cli_state *cli1, *cli2;
2769 const char *fname = "\\fdpass.tst";
2774 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2777 cli_sockopt(cli1, sockops);
2778 cli_sockopt(cli2, sockops);
2780 printf("starting fdpasstest\n");
2782 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2784 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2786 if (!NT_STATUS_IS_OK(status)) {
2787 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2791 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2793 if (!NT_STATUS_IS_OK(status)) {
2794 printf("write failed (%s)\n", nt_errstr(status));
2798 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2799 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2800 cli_setpid(cli2, cli_getpid(cli1));
2802 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2803 printf("read succeeded! nasty security hole [%s]\n", buf);
2807 cli_close(cli1, fnum1);
2808 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2810 torture_close_connection(cli1);
2811 torture_close_connection(cli2);
2813 printf("finished fdpasstest\n");
2817 static bool run_fdsesstest(int dummy)
2819 struct cli_state *cli;
2824 const char *fname = "\\fdsess.tst";
2825 const char *fname1 = "\\fdsess1.tst";
2832 if (!torture_open_connection(&cli, 0))
2834 cli_sockopt(cli, sockops);
2836 if (!torture_cli_session_setup2(cli, &new_vuid))
2839 saved_cnum = cli_state_get_tid(cli);
2840 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2842 new_cnum = cli_state_get_tid(cli);
2843 cli_state_set_tid(cli, saved_cnum);
2845 printf("starting fdsesstest\n");
2847 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2848 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2850 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2851 if (!NT_STATUS_IS_OK(status)) {
2852 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2856 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2858 if (!NT_STATUS_IS_OK(status)) {
2859 printf("write failed (%s)\n", nt_errstr(status));
2863 saved_vuid = cli_state_get_uid(cli);
2864 cli_state_set_uid(cli, new_vuid);
2866 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2867 printf("read succeeded with different vuid! "
2868 "nasty security hole [%s]\n", buf);
2871 /* Try to open a file with different vuid, samba cnum. */
2872 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2873 printf("create with different vuid, same cnum succeeded.\n");
2874 cli_close(cli, fnum2);
2875 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2877 printf("create with different vuid, same cnum failed.\n");
2878 printf("This will cause problems with service clients.\n");
2882 cli_state_set_uid(cli, saved_vuid);
2884 /* Try with same vuid, different cnum. */
2885 cli_state_set_tid(cli, new_cnum);
2887 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2888 printf("read succeeded with different cnum![%s]\n", buf);
2892 cli_state_set_tid(cli, saved_cnum);
2893 cli_close(cli, fnum1);
2894 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2896 torture_close_connection(cli);
2898 printf("finished fdsesstest\n");
2903 This test checks that
2905 1) the server does not allow an unlink on a file that is open
2907 static bool run_unlinktest(int dummy)
2909 struct cli_state *cli;
2910 const char *fname = "\\unlink.tst";
2912 bool correct = True;
2915 if (!torture_open_connection(&cli, 0)) {
2919 cli_sockopt(cli, sockops);
2921 printf("starting unlink test\n");
2923 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2927 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2928 if (!NT_STATUS_IS_OK(status)) {
2929 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2933 status = cli_unlink(cli, fname,
2934 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2935 if (NT_STATUS_IS_OK(status)) {
2936 printf("error: server allowed unlink on an open file\n");
2939 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2940 NT_STATUS_SHARING_VIOLATION);
2943 cli_close(cli, fnum);
2944 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2946 if (!torture_close_connection(cli)) {
2950 printf("unlink test finished\n");
2957 test how many open files this server supports on the one socket
2959 static bool run_maxfidtest(int dummy)
2961 struct cli_state *cli;
2963 uint16_t fnums[0x11000];
2966 bool correct = True;
2972 printf("failed to connect\n");
2976 cli_sockopt(cli, sockops);
2978 for (i=0; i<0x11000; i++) {
2979 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2980 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2982 if (!NT_STATUS_IS_OK(status)) {
2983 printf("open of %s failed (%s)\n",
2984 fname, nt_errstr(status));
2985 printf("maximum fnum is %d\n", i);
2993 printf("cleaning up\n");
2995 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2996 cli_close(cli, fnums[i]);
2998 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2999 if (!NT_STATUS_IS_OK(status)) {
3000 printf("unlink of %s failed (%s)\n",
3001 fname, nt_errstr(status));
3008 printf("maxfid test finished\n");
3009 if (!torture_close_connection(cli)) {
3015 /* generate a random buffer */
3016 static void rand_buf(char *buf, int len)
3019 *buf = (char)sys_random();
3024 /* send smb negprot commands, not reading the response */
3025 static bool run_negprot_nowait(int dummy)
3027 struct tevent_context *ev;
3029 struct cli_state *cli;
3030 bool correct = True;
3032 printf("starting negprot nowait test\n");
3034 ev = tevent_context_init(talloc_tos());
3039 if (!(cli = open_nbt_connection())) {
3044 for (i=0;i<50000;i++) {
3045 struct tevent_req *req;
3047 req = cli_negprot_send(ev, ev, cli);
3052 if (!tevent_req_poll(req, ev)) {
3053 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3061 if (torture_close_connection(cli)) {
3065 printf("finished negprot nowait test\n");
3070 /* send smb negprot commands, not reading the response */
3071 static bool run_bad_nbt_session(int dummy)
3073 struct nmb_name called, calling;
3074 struct sockaddr_storage ss;
3079 printf("starting bad nbt session test\n");
3081 make_nmb_name(&calling, myname, 0x0);
3082 make_nmb_name(&called , host, 0x20);
3084 if (!resolve_name(host, &ss, 0x20, true)) {
3085 d_fprintf(stderr, "Could not resolve name %s\n", host);
3089 status = open_socket_out(&ss, 139, 10000, &fd);
3090 if (!NT_STATUS_IS_OK(status)) {
3091 d_fprintf(stderr, "open_socket_out failed: %s\n",
3096 ret = cli_bad_session_request(fd, &calling, &called);
3099 d_fprintf(stderr, "open_socket_out failed: %s\n",
3104 printf("finished bad nbt session test\n");
3108 /* send random IPC commands */
3109 static bool run_randomipc(int dummy)
3111 char *rparam = NULL;
3113 unsigned int rdrcnt,rprcnt;
3115 int api, param_len, i;
3116 struct cli_state *cli;
3117 bool correct = True;
3120 printf("starting random ipc test\n");
3122 if (!torture_open_connection(&cli, 0)) {
3126 for (i=0;i<count;i++) {
3127 api = sys_random() % 500;
3128 param_len = (sys_random() % 64);
3130 rand_buf(param, param_len);
3135 param, param_len, 8,
3136 NULL, 0, BUFFER_SIZE,
3140 printf("%d/%d\r", i,count);
3143 printf("%d/%d\n", i, count);
3145 if (!torture_close_connection(cli)) {
3149 printf("finished random ipc test\n");
3156 static void browse_callback(const char *sname, uint32 stype,
3157 const char *comment, void *state)
3159 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3165 This test checks the browse list code
3168 static bool run_browsetest(int dummy)
3170 static struct cli_state *cli;
3171 bool correct = True;
3173 printf("starting browse test\n");
3175 if (!torture_open_connection(&cli, 0)) {
3179 printf("domain list:\n");
3180 cli_NetServerEnum(cli, cli->server_domain,
3181 SV_TYPE_DOMAIN_ENUM,
3182 browse_callback, NULL);
3184 printf("machine list:\n");
3185 cli_NetServerEnum(cli, cli->server_domain,
3187 browse_callback, NULL);
3189 if (!torture_close_connection(cli)) {
3193 printf("browse test finished\n");
3201 This checks how the getatr calls works
3203 static bool run_attrtest(int dummy)
3205 struct cli_state *cli;
3208 const char *fname = "\\attrib123456789.tst";
3209 bool correct = True;
3212 printf("starting attrib test\n");
3214 if (!torture_open_connection(&cli, 0)) {
3218 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3219 cli_open(cli, fname,
3220 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3221 cli_close(cli, fnum);
3223 status = cli_getatr(cli, fname, NULL, NULL, &t);
3224 if (!NT_STATUS_IS_OK(status)) {
3225 printf("getatr failed (%s)\n", nt_errstr(status));
3229 if (abs(t - time(NULL)) > 60*60*24*10) {
3230 printf("ERROR: SMBgetatr bug. time is %s",
3236 t2 = t-60*60*24; /* 1 day ago */
3238 status = cli_setatr(cli, fname, 0, t2);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 printf("setatr failed (%s)\n", nt_errstr(status));
3244 status = cli_getatr(cli, fname, NULL, NULL, &t);
3245 if (!NT_STATUS_IS_OK(status)) {
3246 printf("getatr failed (%s)\n", nt_errstr(status));
3251 printf("ERROR: getatr/setatr bug. times are\n%s",
3253 printf("%s", ctime(&t2));
3257 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3259 if (!torture_close_connection(cli)) {
3263 printf("attrib test finished\n");
3270 This checks a couple of trans2 calls
3272 static bool run_trans2test(int dummy)
3274 struct cli_state *cli;
3277 time_t c_time, a_time, m_time;
3278 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3279 const char *fname = "\\trans2.tst";
3280 const char *dname = "\\trans2";
3281 const char *fname2 = "\\trans2\\trans2.tst";
3283 bool correct = True;
3287 printf("starting trans2 test\n");
3289 if (!torture_open_connection(&cli, 0)) {
3293 status = cli_get_fs_attr_info(cli, &fs_attr);
3294 if (!NT_STATUS_IS_OK(status)) {
3295 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3300 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3301 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3302 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3303 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3309 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3310 if (!NT_STATUS_IS_OK(status)) {
3311 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3315 if (strcmp(pname, fname)) {
3316 printf("qfilename gave different name? [%s] [%s]\n",
3321 cli_close(cli, fnum);
3325 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3326 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3328 if (!NT_STATUS_IS_OK(status)) {
3329 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3332 cli_close(cli, fnum);
3334 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3336 if (!NT_STATUS_IS_OK(status)) {
3337 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3340 time_t t = time(NULL);
3342 if (c_time != m_time) {
3343 printf("create time=%s", ctime(&c_time));
3344 printf("modify time=%s", ctime(&m_time));
3345 printf("This system appears to have sticky create times\n");
3347 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3348 printf("access time=%s", ctime(&a_time));
3349 printf("This system appears to set a midnight access time\n");
3353 if (abs(m_time - t) > 60*60*24*7) {
3354 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3360 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3361 cli_open(cli, fname,
3362 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3363 cli_close(cli, fnum);
3364 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3365 &m_time_ts, &size, NULL, NULL);
3366 if (!NT_STATUS_IS_OK(status)) {
3367 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3370 if (w_time_ts.tv_sec < 60*60*24*2) {
3371 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3372 printf("This system appears to set a initial 0 write time\n");
3377 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3380 /* check if the server updates the directory modification time
3381 when creating a new file */
3382 status = cli_mkdir(cli, dname);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3388 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3389 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3395 cli_open(cli, fname2,
3396 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3397 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3398 cli_close(cli, fnum);
3399 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3400 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3401 if (!NT_STATUS_IS_OK(status)) {
3402 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3405 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3407 printf("This system does not update directory modification times\n");
3411 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3412 cli_rmdir(cli, dname);
3414 if (!torture_close_connection(cli)) {
3418 printf("trans2 test finished\n");
3424 This checks new W2K calls.
3427 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3429 uint8_t *buf = NULL;
3433 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3434 pcli->max_xmit, NULL, &buf, &len);
3435 if (!NT_STATUS_IS_OK(status)) {
3436 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3439 printf("qfileinfo: level %d, len = %u\n", level, len);
3440 dump_data(0, (uint8 *)buf, len);
3447 static bool run_w2ktest(int dummy)
3449 struct cli_state *cli;
3451 const char *fname = "\\w2ktest\\w2k.tst";
3453 bool correct = True;
3455 printf("starting w2k test\n");
3457 if (!torture_open_connection(&cli, 0)) {
3461 cli_open(cli, fname,
3462 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3464 for (level = 1004; level < 1040; level++) {
3465 new_trans(cli, fnum, level);
3468 cli_close(cli, fnum);
3470 if (!torture_close_connection(cli)) {
3474 printf("w2k test finished\n");
3481 this is a harness for some oplock tests
3483 static bool run_oplock1(int dummy)
3485 struct cli_state *cli1;
3486 const char *fname = "\\lockt1.lck";
3488 bool correct = True;
3491 printf("starting oplock test 1\n");
3493 if (!torture_open_connection(&cli1, 0)) {
3497 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3499 cli_sockopt(cli1, sockops);
3501 cli1->use_oplocks = True;
3503 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3505 if (!NT_STATUS_IS_OK(status)) {
3506 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3510 cli1->use_oplocks = False;
3512 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3513 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3515 status = cli_close(cli1, fnum1);
3516 if (!NT_STATUS_IS_OK(status)) {
3517 printf("close2 failed (%s)\n", nt_errstr(status));
3521 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3522 if (!NT_STATUS_IS_OK(status)) {
3523 printf("unlink failed (%s)\n", nt_errstr(status));
3527 if (!torture_close_connection(cli1)) {
3531 printf("finished oplock test 1\n");
3536 static bool run_oplock2(int dummy)
3538 struct cli_state *cli1, *cli2;
3539 const char *fname = "\\lockt2.lck";
3540 uint16_t fnum1, fnum2;
3541 int saved_use_oplocks = use_oplocks;
3543 bool correct = True;
3544 volatile bool *shared_correct;
3548 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3549 *shared_correct = True;
3551 use_level_II_oplocks = True;
3554 printf("starting oplock test 2\n");
3556 if (!torture_open_connection(&cli1, 0)) {
3557 use_level_II_oplocks = False;
3558 use_oplocks = saved_use_oplocks;
3562 if (!torture_open_connection(&cli2, 1)) {
3563 use_level_II_oplocks = False;
3564 use_oplocks = saved_use_oplocks;
3568 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3570 cli_sockopt(cli1, sockops);
3571 cli_sockopt(cli2, sockops);
3573 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3575 if (!NT_STATUS_IS_OK(status)) {
3576 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3580 /* Don't need the globals any more. */
3581 use_level_II_oplocks = False;
3582 use_oplocks = saved_use_oplocks;
3586 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3587 if (!NT_STATUS_IS_OK(status)) {
3588 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3589 *shared_correct = False;
3595 status = cli_close(cli2, fnum2);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 printf("close2 failed (%s)\n", nt_errstr(status));
3598 *shared_correct = False;
3606 /* Ensure cli1 processes the break. Empty file should always return 0
3608 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3609 if (!NT_STATUS_IS_OK(status)) {
3610 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3612 } else if (nread != 0) {
3613 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3614 (unsigned long)nread, 0);
3618 /* Should now be at level II. */
3619 /* Test if sending a write locks causes a break to none. */
3620 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3621 if (!NT_STATUS_IS_OK(status)) {
3622 printf("lock failed (%s)\n", nt_errstr(status));
3626 cli_unlock(cli1, fnum1, 0, 4);
3630 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3631 if (!NT_STATUS_IS_OK(status)) {
3632 printf("lock failed (%s)\n", nt_errstr(status));
3636 cli_unlock(cli1, fnum1, 0, 4);
3640 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3642 status = cli_close(cli1, fnum1);
3643 if (!NT_STATUS_IS_OK(status)) {
3644 printf("close1 failed (%s)\n", nt_errstr(status));
3650 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3651 if (!NT_STATUS_IS_OK(status)) {
3652 printf("unlink failed (%s)\n", nt_errstr(status));
3656 if (!torture_close_connection(cli1)) {
3660 if (!*shared_correct) {
3664 printf("finished oplock test 2\n");
3669 struct oplock4_state {
3670 struct tevent_context *ev;
3671 struct cli_state *cli;
3676 static void oplock4_got_break(struct tevent_req *req);
3677 static void oplock4_got_open(struct tevent_req *req);
3679 static bool run_oplock4(int dummy)
3681 struct tevent_context *ev;
3682 struct cli_state *cli1, *cli2;
3683 struct tevent_req *oplock_req, *open_req;
3684 const char *fname = "\\lockt4.lck";
3685 const char *fname_ln = "\\lockt4_ln.lck";
3686 uint16_t fnum1, fnum2;
3687 int saved_use_oplocks = use_oplocks;
3689 bool correct = true;
3693 struct oplock4_state *state;
3695 printf("starting oplock test 4\n");
3697 if (!torture_open_connection(&cli1, 0)) {
3698 use_level_II_oplocks = false;
3699 use_oplocks = saved_use_oplocks;
3703 if (!torture_open_connection(&cli2, 1)) {
3704 use_level_II_oplocks = false;
3705 use_oplocks = saved_use_oplocks;
3709 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3710 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3712 cli_sockopt(cli1, sockops);
3713 cli_sockopt(cli2, sockops);
3715 /* Create the file. */
3716 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3718 if (!NT_STATUS_IS_OK(status)) {
3719 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3723 status = cli_close(cli1, fnum1);
3724 if (!NT_STATUS_IS_OK(status)) {
3725 printf("close1 failed (%s)\n", nt_errstr(status));
3729 /* Now create a hardlink. */
3730 status = cli_nt_hardlink(cli1, fname, fname_ln);
3731 if (!NT_STATUS_IS_OK(status)) {
3732 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3736 /* Prove that opening hardlinks cause deny modes to conflict. */
3737 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3738 if (!NT_STATUS_IS_OK(status)) {
3739 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3743 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3744 if (NT_STATUS_IS_OK(status)) {
3745 printf("open of %s succeeded - should fail with sharing violation.\n",
3750 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3751 printf("open of %s should fail with sharing violation. Got %s\n",
3752 fname_ln, nt_errstr(status));
3756 status = cli_close(cli1, fnum1);
3757 if (!NT_STATUS_IS_OK(status)) {
3758 printf("close1 failed (%s)\n", nt_errstr(status));
3762 cli1->use_oplocks = true;
3763 cli1->use_level_II_oplocks = true;
3765 cli2->use_oplocks = true;
3766 cli2->use_level_II_oplocks = true;
3768 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3769 if (!NT_STATUS_IS_OK(status)) {
3770 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3774 ev = tevent_context_init(talloc_tos());
3776 printf("tevent_req_create failed\n");
3780 state = talloc(ev, struct oplock4_state);
3781 if (state == NULL) {
3782 printf("talloc failed\n");
3787 state->got_break = &got_break;
3788 state->fnum2 = &fnum2;
3790 oplock_req = cli_smb_oplock_break_waiter_send(
3791 talloc_tos(), ev, cli1);
3792 if (oplock_req == NULL) {
3793 printf("cli_smb_oplock_break_waiter_send failed\n");
3796 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3798 open_req = cli_open_send(
3799 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3800 if (oplock_req == NULL) {
3801 printf("cli_open_send failed\n");
3804 tevent_req_set_callback(open_req, oplock4_got_open, state);
3809 while (!got_break || fnum2 == 0xffff) {
3811 ret = tevent_loop_once(ev);
3813 printf("tevent_loop_once failed: %s\n",
3819 status = cli_close(cli2, fnum2);
3820 if (!NT_STATUS_IS_OK(status)) {
3821 printf("close2 failed (%s)\n", nt_errstr(status));
3825 status = cli_close(cli1, fnum1);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 printf("close1 failed (%s)\n", nt_errstr(status));
3831 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("unlink failed (%s)\n", nt_errstr(status));
3837 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("unlink failed (%s)\n", nt_errstr(status));
3843 if (!torture_close_connection(cli1)) {
3851 printf("finished oplock test 4\n");
3856 static void oplock4_got_break(struct tevent_req *req)
3858 struct oplock4_state *state = tevent_req_callback_data(
3859 req, struct oplock4_state);
3864 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3866 if (!NT_STATUS_IS_OK(status)) {
3867 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3871 *state->got_break = true;
3873 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3876 printf("cli_oplock_ack_send failed\n");
3881 static void oplock4_got_open(struct tevent_req *req)
3883 struct oplock4_state *state = tevent_req_callback_data(
3884 req, struct oplock4_state);
3887 status = cli_open_recv(req, state->fnum2);
3888 if (!NT_STATUS_IS_OK(status)) {
3889 printf("cli_open_recv returned %s\n", nt_errstr(status));
3890 *state->fnum2 = 0xffff;
3895 Test delete on close semantics.
3897 static bool run_deletetest(int dummy)
3899 struct cli_state *cli1 = NULL;
3900 struct cli_state *cli2 = NULL;
3901 const char *fname = "\\delete.file";
3902 uint16_t fnum1 = (uint16_t)-1;
3903 uint16_t fnum2 = (uint16_t)-1;
3904 bool correct = True;
3907 printf("starting delete test\n");
3909 if (!torture_open_connection(&cli1, 0)) {
3913 cli_sockopt(cli1, sockops);
3915 /* Test 1 - this should delete the file on close. */
3917 cli_setatr(cli1, fname, 0, 0);
3918 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3920 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3921 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3922 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3923 if (!NT_STATUS_IS_OK(status)) {
3924 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3929 status = cli_close(cli1, fnum1);
3930 if (!NT_STATUS_IS_OK(status)) {
3931 printf("[1] close failed (%s)\n", nt_errstr(status));
3936 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3937 printf("[1] open of %s succeeded (should fail)\n", fname);
3942 printf("first delete on close test succeeded.\n");
3944 /* Test 2 - this should delete the file on close. */
3946 cli_setatr(cli1, fname, 0, 0);
3947 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3949 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3950 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3951 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3952 if (!NT_STATUS_IS_OK(status)) {
3953 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3958 status = cli_nt_delete_on_close(cli1, fnum1, true);
3959 if (!NT_STATUS_IS_OK(status)) {
3960 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3965 status = cli_close(cli1, fnum1);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 printf("[2] close failed (%s)\n", nt_errstr(status));
3972 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3973 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3974 status = cli_close(cli1, fnum1);
3975 if (!NT_STATUS_IS_OK(status)) {
3976 printf("[2] close failed (%s)\n", nt_errstr(status));
3980 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3982 printf("second delete on close test succeeded.\n");
3985 cli_setatr(cli1, fname, 0, 0);
3986 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3988 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3989 FILE_ATTRIBUTE_NORMAL,
3990 FILE_SHARE_READ|FILE_SHARE_WRITE,
3991 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3992 if (!NT_STATUS_IS_OK(status)) {
3993 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3998 /* This should fail with a sharing violation - open for delete is only compatible
3999 with SHARE_DELETE. */
4001 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4002 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
4003 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4008 /* This should succeed. */
4009 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4010 FILE_ATTRIBUTE_NORMAL,
4011 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4012 FILE_OPEN, 0, 0, &fnum2);
4013 if (!NT_STATUS_IS_OK(status)) {
4014 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4019 status = cli_nt_delete_on_close(cli1, fnum1, true);
4020 if (!NT_STATUS_IS_OK(status)) {
4021 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4026 status = cli_close(cli1, fnum1);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4033 status = cli_close(cli1, fnum2);
4034 if (!NT_STATUS_IS_OK(status)) {
4035 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4040 /* This should fail - file should no longer be there. */
4042 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4043 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4044 status = cli_close(cli1, fnum1);
4045 if (!NT_STATUS_IS_OK(status)) {
4046 printf("[3] close failed (%s)\n", nt_errstr(status));
4048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4052 printf("third delete on close test succeeded.\n");
4055 cli_setatr(cli1, fname, 0, 0);
4056 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4058 status = cli_ntcreate(cli1, fname, 0,
4059 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4060 FILE_ATTRIBUTE_NORMAL,
4061 FILE_SHARE_READ|FILE_SHARE_WRITE,
4062 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4069 /* This should succeed. */
4070 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4071 FILE_ATTRIBUTE_NORMAL,
4072 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4073 FILE_OPEN, 0, 0, &fnum2);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4080 status = cli_close(cli1, fnum2);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4087 status = cli_nt_delete_on_close(cli1, fnum1, true);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4094 /* This should fail - no more opens once delete on close set. */
4095 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4096 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4097 FILE_OPEN, 0, 0, &fnum2))) {
4098 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4102 printf("fourth delete on close test succeeded.\n");
4104 status = cli_close(cli1, fnum1);
4105 if (!NT_STATUS_IS_OK(status)) {
4106 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4112 cli_setatr(cli1, fname, 0, 0);
4113 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4115 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4116 if (!NT_STATUS_IS_OK(status)) {
4117 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4122 /* This should fail - only allowed on NT opens with DELETE access. */
4124 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4125 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4130 status = cli_close(cli1, fnum1);
4131 if (!NT_STATUS_IS_OK(status)) {
4132 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4137 printf("fifth delete on close test succeeded.\n");
4140 cli_setatr(cli1, fname, 0, 0);
4141 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4143 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4144 FILE_ATTRIBUTE_NORMAL,
4145 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4146 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("[6] open of %s failed (%s)\n", fname,
4154 /* This should fail - only allowed on NT opens with DELETE access. */
4156 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4157 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4162 status = cli_close(cli1, fnum1);
4163 if (!NT_STATUS_IS_OK(status)) {
4164 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4169 printf("sixth delete on close test succeeded.\n");
4172 cli_setatr(cli1, fname, 0, 0);
4173 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4175 status = cli_ntcreate(cli1, fname, 0,
4176 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4177 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4179 if (!NT_STATUS_IS_OK(status)) {
4180 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4185 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4186 printf("[7] setting delete_on_close on file failed !\n");
4191 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4192 printf("[7] unsetting delete_on_close on file failed !\n");
4197 status = cli_close(cli1, fnum1);
4198 if (!NT_STATUS_IS_OK(status)) {
4199 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4204 /* This next open should succeed - we reset the flag. */
4205 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4206 if (!NT_STATUS_IS_OK(status)) {
4207 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4212 status = cli_close(cli1, fnum1);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4219 printf("seventh delete on close test succeeded.\n");
4222 cli_setatr(cli1, fname, 0, 0);
4223 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4225 if (!torture_open_connection(&cli2, 1)) {
4226 printf("[8] failed to open second connection.\n");
4231 cli_sockopt(cli1, sockops);
4233 status = cli_ntcreate(cli1, fname, 0,
4234 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4235 FILE_ATTRIBUTE_NORMAL,
4236 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4237 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4238 if (!NT_STATUS_IS_OK(status)) {
4239 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4244 status = cli_ntcreate(cli2, fname, 0,
4245 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4246 FILE_ATTRIBUTE_NORMAL,
4247 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4248 FILE_OPEN, 0, 0, &fnum2);
4249 if (!NT_STATUS_IS_OK(status)) {
4250 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4255 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4256 printf("[8] setting delete_on_close on file failed !\n");
4261 status = cli_close(cli1, fnum1);
4262 if (!NT_STATUS_IS_OK(status)) {
4263 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4268 status = cli_close(cli2, fnum2);
4269 if (!NT_STATUS_IS_OK(status)) {
4270 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4275 /* This should fail.. */
4276 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4277 if (NT_STATUS_IS_OK(status)) {
4278 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4282 printf("eighth delete on close test succeeded.\n");
4284 /* This should fail - we need to set DELETE_ACCESS. */
4285 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4286 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4287 printf("[9] open of %s succeeded should have failed!\n", fname);
4292 printf("ninth delete on close test succeeded.\n");
4294 status = cli_ntcreate(cli1, fname, 0,
4295 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4296 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4297 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4299 if (!NT_STATUS_IS_OK(status)) {
4300 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4305 /* This should delete the file. */
4306 status = cli_close(cli1, fnum1);
4307 if (!NT_STATUS_IS_OK(status)) {
4308 printf("[10] close failed (%s)\n", nt_errstr(status));
4313 /* This should fail.. */
4314 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4315 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4319 printf("tenth delete on close test succeeded.\n");
4321 cli_setatr(cli1, fname, 0, 0);
4322 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4324 /* What error do we get when attempting to open a read-only file with
4327 /* Create a readonly file. */
4328 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4329 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4330 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4331 if (!NT_STATUS_IS_OK(status)) {
4332 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4337 status = cli_close(cli1, fnum1);
4338 if (!NT_STATUS_IS_OK(status)) {
4339 printf("[11] close failed (%s)\n", nt_errstr(status));
4344 /* Now try open for delete access. */
4345 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4346 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4347 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4348 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4349 cli_close(cli1, fnum1);
4353 NTSTATUS nterr = cli_nt_error(cli1);
4354 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4355 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4359 printf("eleventh delete on close test succeeded.\n");
4363 printf("finished delete test\n");
4366 /* FIXME: This will crash if we aborted before cli2 got
4367 * intialized, because these functions don't handle
4368 * uninitialized connections. */
4370 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4371 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4372 cli_setatr(cli1, fname, 0, 0);
4373 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4375 if (cli1 && !torture_close_connection(cli1)) {
4378 if (cli2 && !torture_close_connection(cli2)) {
4384 static bool run_deletetest_ln(int dummy)
4386 struct cli_state *cli;
4387 const char *fname = "\\delete1";
4388 const char *fname_ln = "\\delete1_ln";
4392 bool correct = true;
4395 printf("starting deletetest-ln\n");
4397 if (!torture_open_connection(&cli, 0)) {
4401 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4402 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 cli_sockopt(cli, sockops);
4406 /* Create the file. */
4407 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4408 if (!NT_STATUS_IS_OK(status)) {
4409 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4413 status = cli_close(cli, fnum);
4414 if (!NT_STATUS_IS_OK(status)) {
4415 printf("close1 failed (%s)\n", nt_errstr(status));
4419 /* Now create a hardlink. */
4420 status = cli_nt_hardlink(cli, fname, fname_ln);
4421 if (!NT_STATUS_IS_OK(status)) {
4422 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4426 /* Open the original file. */
4427 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4428 FILE_ATTRIBUTE_NORMAL,
4429 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4430 FILE_OPEN_IF, 0, 0, &fnum);
4431 if (!NT_STATUS_IS_OK(status)) {
4432 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4436 /* Unlink the hard link path. */
4437 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4438 FILE_ATTRIBUTE_NORMAL,
4439 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4440 FILE_OPEN_IF, 0, 0, &fnum1);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4445 status = cli_nt_delete_on_close(cli, fnum1, true);
4446 if (!NT_STATUS_IS_OK(status)) {
4447 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4448 __location__, fname_ln, nt_errstr(status));
4452 status = cli_close(cli, fnum1);
4453 if (!NT_STATUS_IS_OK(status)) {
4454 printf("close %s failed (%s)\n",
4455 fname_ln, nt_errstr(status));
4459 status = cli_close(cli, fnum);
4460 if (!NT_STATUS_IS_OK(status)) {
4461 printf("close %s failed (%s)\n",
4462 fname, nt_errstr(status));
4466 /* Ensure the original file is still there. */
4467 status = cli_getatr(cli, fname, NULL, NULL, &t);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 printf("%s getatr on file %s failed (%s)\n",
4476 /* Ensure the link path is gone. */
4477 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4478 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4479 printf("%s, getatr for file %s returned wrong error code %s "
4480 "- should have been deleted\n",
4482 fname_ln, nt_errstr(status));
4486 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4487 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4489 if (!torture_close_connection(cli)) {
4493 printf("finished deletetest-ln\n");
4499 print out server properties
4501 static bool run_properties(int dummy)
4503 struct cli_state *cli;
4504 bool correct = True;
4506 printf("starting properties test\n");
4510 if (!torture_open_connection(&cli, 0)) {
4514 cli_sockopt(cli, sockops);
4516 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli));
4518 if (!torture_close_connection(cli)) {
4527 /* FIRST_DESIRED_ACCESS 0xf019f */
4528 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4529 FILE_READ_EA| /* 0xf */ \
4530 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4531 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4532 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4533 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4534 /* SECOND_DESIRED_ACCESS 0xe0080 */
4535 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4536 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4537 WRITE_OWNER_ACCESS /* 0xe0000 */
4540 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4541 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4543 WRITE_OWNER_ACCESS /* */
4547 Test ntcreate calls made by xcopy
4549 static bool run_xcopy(int dummy)
4551 static struct cli_state *cli1;
4552 const char *fname = "\\test.txt";
4553 bool correct = True;
4554 uint16_t fnum1, fnum2;
4557 printf("starting xcopy test\n");
4559 if (!torture_open_connection(&cli1, 0)) {
4563 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4564 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4565 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4566 if (!NT_STATUS_IS_OK(status)) {
4567 printf("First open failed - %s\n", nt_errstr(status));
4571 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4572 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4573 FILE_OPEN, 0x200000, 0, &fnum2);
4574 if (!NT_STATUS_IS_OK(status)) {
4575 printf("second open failed - %s\n", nt_errstr(status));
4579 if (!torture_close_connection(cli1)) {
4587 Test rename on files open with share delete and no share delete.
4589 static bool run_rename(int dummy)
4591 static struct cli_state *cli1;
4592 const char *fname = "\\test.txt";
4593 const char *fname1 = "\\test1.txt";
4594 bool correct = True;
4599 printf("starting rename test\n");
4601 if (!torture_open_connection(&cli1, 0)) {
4605 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4606 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4608 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4609 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4610 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("First open failed - %s\n", nt_errstr(status));
4616 status = cli_rename(cli1, fname, fname1);
4617 if (!NT_STATUS_IS_OK(status)) {
4618 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4620 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4624 status = cli_close(cli1, fnum1);
4625 if (!NT_STATUS_IS_OK(status)) {
4626 printf("close - 1 failed (%s)\n", nt_errstr(status));
4630 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4631 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4632 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4634 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4636 FILE_SHARE_DELETE|FILE_SHARE_READ,
4638 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4639 if (!NT_STATUS_IS_OK(status)) {
4640 printf("Second open failed - %s\n", nt_errstr(status));
4644 status = cli_rename(cli1, fname, fname1);
4645 if (!NT_STATUS_IS_OK(status)) {
4646 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4649 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4652 status = cli_close(cli1, fnum1);
4653 if (!NT_STATUS_IS_OK(status)) {
4654 printf("close - 2 failed (%s)\n", nt_errstr(status));
4658 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4659 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4661 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4662 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4663 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 printf("Third open failed - %s\n", nt_errstr(status));
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4676 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4679 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4680 printf("[8] setting delete_on_close on file failed !\n");
4684 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4685 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4691 status = cli_rename(cli1, fname, fname1);
4692 if (!NT_STATUS_IS_OK(status)) {
4693 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4696 printf("Third rename succeeded (SHARE_NONE)\n");
4699 status = cli_close(cli1, fnum1);
4700 if (!NT_STATUS_IS_OK(status)) {
4701 printf("close - 3 failed (%s)\n", nt_errstr(status));
4705 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4706 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4710 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4711 FILE_ATTRIBUTE_NORMAL,
4712 FILE_SHARE_READ | FILE_SHARE_WRITE,
4713 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4714 if (!NT_STATUS_IS_OK(status)) {
4715 printf("Fourth open failed - %s\n", nt_errstr(status));
4719 status = cli_rename(cli1, fname, fname1);
4720 if (!NT_STATUS_IS_OK(status)) {
4721 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4723 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4727 status = cli_close(cli1, fnum1);
4728 if (!NT_STATUS_IS_OK(status)) {
4729 printf("close - 4 failed (%s)\n", nt_errstr(status));
4733 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4734 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4738 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4739 FILE_ATTRIBUTE_NORMAL,
4740 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4741 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4742 if (!NT_STATUS_IS_OK(status)) {
4743 printf("Fifth open failed - %s\n", nt_errstr(status));
4747 status = cli_rename(cli1, fname, fname1);
4748 if (!NT_STATUS_IS_OK(status)) {
4749 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4752 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4756 * Now check if the first name still exists ...
4759 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4760 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4761 printf("Opening original file after rename of open file fails: %s\n",
4765 printf("Opening original file after rename of open file works ...\n");
4766 (void)cli_close(cli1, fnum2);
4770 status = cli_close(cli1, fnum1);
4771 if (!NT_STATUS_IS_OK(status)) {
4772 printf("close - 5 failed (%s)\n", nt_errstr(status));
4776 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4777 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4778 if (!NT_STATUS_IS_OK(status)) {
4779 printf("getatr on file %s failed - %s ! \n",
4780 fname1, nt_errstr(status));
4783 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4784 printf("Renamed file %s has wrong attr 0x%x "
4785 "(should be 0x%x)\n",
4788 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4791 printf("Renamed file %s has archive bit set\n", fname1);
4795 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4796 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4798 if (!torture_close_connection(cli1)) {
4805 static bool run_pipe_number(int dummy)
4807 struct cli_state *cli1;
4808 const char *pipe_name = "\\SPOOLSS";
4813 printf("starting pipenumber test\n");
4814 if (!torture_open_connection(&cli1, 0)) {
4818 cli_sockopt(cli1, sockops);
4820 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4821 FILE_ATTRIBUTE_NORMAL,
4822 FILE_SHARE_READ|FILE_SHARE_WRITE,
4823 FILE_OPEN_IF, 0, 0, &fnum);
4824 if (!NT_STATUS_IS_OK(status)) {
4825 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4829 printf("\r%6d", num_pipes);
4832 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4833 torture_close_connection(cli1);
4838 Test open mode returns on read-only files.
4840 static bool run_opentest(int dummy)
4842 static struct cli_state *cli1;
4843 static struct cli_state *cli2;
4844 const char *fname = "\\readonly.file";
4845 uint16_t fnum1, fnum2;
4848 bool correct = True;
4852 printf("starting open test\n");
4854 if (!torture_open_connection(&cli1, 0)) {
4858 cli_setatr(cli1, fname, 0, 0);
4859 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4861 cli_sockopt(cli1, sockops);
4863 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4864 if (!NT_STATUS_IS_OK(status)) {
4865 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4869 status = cli_close(cli1, fnum1);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 printf("close2 failed (%s)\n", nt_errstr(status));
4875 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4881 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4882 if (!NT_STATUS_IS_OK(status)) {
4883 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4887 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4888 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4890 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4891 NT_STATUS_ACCESS_DENIED)) {
4892 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4895 printf("finished open test 1\n");
4897 cli_close(cli1, fnum1);
4899 /* Now try not readonly and ensure ERRbadshare is returned. */
4901 cli_setatr(cli1, fname, 0, 0);
4903 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4904 if (!NT_STATUS_IS_OK(status)) {
4905 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4909 /* This will fail - but the error should be ERRshare. */
4910 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4912 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4913 NT_STATUS_SHARING_VIOLATION)) {
4914 printf("correct error code ERRDOS/ERRbadshare returned\n");
4917 status = cli_close(cli1, fnum1);
4918 if (!NT_STATUS_IS_OK(status)) {
4919 printf("close2 failed (%s)\n", nt_errstr(status));
4923 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4925 printf("finished open test 2\n");
4927 /* Test truncate open disposition on file opened for read. */
4928 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4929 if (!NT_STATUS_IS_OK(status)) {
4930 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4934 /* write 20 bytes. */
4936 memset(buf, '\0', 20);
4938 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4939 if (!NT_STATUS_IS_OK(status)) {
4940 printf("write failed (%s)\n", nt_errstr(status));
4944 status = cli_close(cli1, fnum1);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4950 /* Ensure size == 20. */
4951 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4952 if (!NT_STATUS_IS_OK(status)) {
4953 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4958 printf("(3) file size != 20\n");
4962 /* Now test if we can truncate a file opened for readonly. */
4963 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4969 status = cli_close(cli1, fnum1);
4970 if (!NT_STATUS_IS_OK(status)) {
4971 printf("close2 failed (%s)\n", nt_errstr(status));
4975 /* Ensure size == 0. */
4976 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4977 if (!NT_STATUS_IS_OK(status)) {
4978 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4983 printf("(3) file size != 0\n");
4986 printf("finished open test 3\n");
4988 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4990 printf("Do ctemp tests\n");
4991 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4992 if (!NT_STATUS_IS_OK(status)) {
4993 printf("ctemp failed (%s)\n", nt_errstr(status));
4997 printf("ctemp gave path %s\n", tmp_path);
4998 status = cli_close(cli1, fnum1);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 printf("close of temp failed (%s)\n", nt_errstr(status));
5003 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5004 if (!NT_STATUS_IS_OK(status)) {
5005 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5008 /* Test the non-io opens... */
5010 if (!torture_open_connection(&cli2, 1)) {
5014 cli_setatr(cli2, fname, 0, 0);
5015 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5017 cli_sockopt(cli2, sockops);
5019 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5020 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5021 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5022 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5028 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5029 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5030 FILE_OPEN_IF, 0, 0, &fnum2);
5031 if (!NT_STATUS_IS_OK(status)) {
5032 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5036 status = cli_close(cli1, fnum1);
5037 if (!NT_STATUS_IS_OK(status)) {
5038 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5042 status = cli_close(cli2, fnum2);
5043 if (!NT_STATUS_IS_OK(status)) {
5044 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5048 printf("non-io open test #1 passed.\n");
5050 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5052 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5054 status = cli_ntcreate(cli1, fname, 0,
5055 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5056 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5057 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5058 if (!NT_STATUS_IS_OK(status)) {
5059 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5063 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5064 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5065 FILE_OPEN_IF, 0, 0, &fnum2);
5066 if (!NT_STATUS_IS_OK(status)) {
5067 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5071 status = cli_close(cli1, fnum1);
5072 if (!NT_STATUS_IS_OK(status)) {
5073 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5077 status = cli_close(cli2, fnum2);
5078 if (!NT_STATUS_IS_OK(status)) {
5079 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5083 printf("non-io open test #2 passed.\n");
5085 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5087 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5089 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5090 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5091 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5092 if (!NT_STATUS_IS_OK(status)) {
5093 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5097 status = cli_ntcreate(cli2, fname, 0,
5098 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5099 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5100 FILE_OPEN_IF, 0, 0, &fnum2);
5101 if (!NT_STATUS_IS_OK(status)) {
5102 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5106 status = cli_close(cli1, fnum1);
5107 if (!NT_STATUS_IS_OK(status)) {
5108 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5112 status = cli_close(cli2, fnum2);
5113 if (!NT_STATUS_IS_OK(status)) {
5114 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5118 printf("non-io open test #3 passed.\n");
5120 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5122 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5124 status = cli_ntcreate(cli1, fname, 0,
5125 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5126 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5127 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5128 if (!NT_STATUS_IS_OK(status)) {
5129 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5133 status = cli_ntcreate(cli2, fname, 0,
5134 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5135 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5136 FILE_OPEN_IF, 0, 0, &fnum2);
5137 if (NT_STATUS_IS_OK(status)) {
5138 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5142 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5144 status = cli_close(cli1, fnum1);
5145 if (!NT_STATUS_IS_OK(status)) {
5146 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5150 printf("non-io open test #4 passed.\n");
5152 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5154 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5156 status = cli_ntcreate(cli1, fname, 0,
5157 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5158 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5159 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5160 if (!NT_STATUS_IS_OK(status)) {
5161 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5165 status = cli_ntcreate(cli2, fname, 0,
5166 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5167 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5168 FILE_OPEN_IF, 0, 0, &fnum2);
5169 if (!NT_STATUS_IS_OK(status)) {
5170 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5174 status = cli_close(cli1, fnum1);
5175 if (!NT_STATUS_IS_OK(status)) {
5176 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5180 status = cli_close(cli2, fnum2);
5181 if (!NT_STATUS_IS_OK(status)) {
5182 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5186 printf("non-io open test #5 passed.\n");
5188 printf("TEST #6 testing 1 non-io open, one io open\n");
5190 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5192 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5193 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5194 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5195 if (!NT_STATUS_IS_OK(status)) {
5196 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5200 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5201 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5202 FILE_OPEN_IF, 0, 0, &fnum2);
5203 if (!NT_STATUS_IS_OK(status)) {
5204 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5208 status = cli_close(cli1, fnum1);
5209 if (!NT_STATUS_IS_OK(status)) {
5210 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5214 status = cli_close(cli2, fnum2);
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5220 printf("non-io open test #6 passed.\n");
5222 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5224 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5226 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5227 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5228 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5234 status = cli_ntcreate(cli2, fname, 0,
5235 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5236 FILE_ATTRIBUTE_NORMAL,
5237 FILE_SHARE_READ|FILE_SHARE_DELETE,
5238 FILE_OPEN_IF, 0, 0, &fnum2);
5239 if (NT_STATUS_IS_OK(status)) {
5240 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5244 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5246 status = cli_close(cli1, fnum1);
5247 if (!NT_STATUS_IS_OK(status)) {
5248 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5252 printf("non-io open test #7 passed.\n");
5254 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5256 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5257 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5258 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5259 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5260 if (!NT_STATUS_IS_OK(status)) {
5261 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5266 /* Write to ensure we have to update the file time. */
5267 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5269 if (!NT_STATUS_IS_OK(status)) {
5270 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5275 status = cli_close(cli1, fnum1);
5276 if (!NT_STATUS_IS_OK(status)) {
5277 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5283 if (!torture_close_connection(cli1)) {
5286 if (!torture_close_connection(cli2)) {
5293 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5295 uint16 major, minor;
5296 uint32 caplow, caphigh;
5299 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5300 printf("Server doesn't support UNIX CIFS extensions.\n");
5301 return NT_STATUS_NOT_SUPPORTED;
5304 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5306 if (!NT_STATUS_IS_OK(status)) {
5307 printf("Server didn't return UNIX CIFS extensions: %s\n",
5312 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5314 if (!NT_STATUS_IS_OK(status)) {
5315 printf("Server doesn't support setting UNIX CIFS extensions: "
5316 "%s.\n", nt_errstr(status));
5320 return NT_STATUS_OK;
5324 Test POSIX open /mkdir calls.
5326 static bool run_simple_posix_open_test(int dummy)
5328 static struct cli_state *cli1;
5329 const char *fname = "posix:file";
5330 const char *hname = "posix:hlink";
5331 const char *sname = "posix:symlink";
5332 const char *dname = "posix:dir";
5335 uint16_t fnum1 = (uint16_t)-1;
5336 SMB_STRUCT_STAT sbuf;
5337 bool correct = false;
5341 printf("Starting simple POSIX open test\n");
5343 if (!torture_open_connection(&cli1, 0)) {
5347 cli_sockopt(cli1, sockops);
5349 status = torture_setup_unix_extensions(cli1);
5350 if (!NT_STATUS_IS_OK(status)) {
5354 cli_setatr(cli1, fname, 0, 0);
5355 cli_posix_unlink(cli1, fname);
5356 cli_setatr(cli1, dname, 0, 0);
5357 cli_posix_rmdir(cli1, dname);
5358 cli_setatr(cli1, hname, 0, 0);
5359 cli_posix_unlink(cli1, hname);
5360 cli_setatr(cli1, sname, 0, 0);
5361 cli_posix_unlink(cli1, sname);
5363 /* Create a directory. */
5364 status = cli_posix_mkdir(cli1, dname, 0777);
5365 if (!NT_STATUS_IS_OK(status)) {
5366 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5370 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5372 if (!NT_STATUS_IS_OK(status)) {
5373 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5377 /* Test ftruncate - set file size. */
5378 status = cli_ftruncate(cli1, fnum1, 1000);
5379 if (!NT_STATUS_IS_OK(status)) {
5380 printf("ftruncate failed (%s)\n", nt_errstr(status));
5384 /* Ensure st_size == 1000 */
5385 status = cli_posix_stat(cli1, fname, &sbuf);
5386 if (!NT_STATUS_IS_OK(status)) {
5387 printf("stat failed (%s)\n", nt_errstr(status));
5391 if (sbuf.st_ex_size != 1000) {
5392 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5396 /* Test ftruncate - set file size back to zero. */
5397 status = cli_ftruncate(cli1, fnum1, 0);
5398 if (!NT_STATUS_IS_OK(status)) {
5399 printf("ftruncate failed (%s)\n", nt_errstr(status));
5403 status = cli_close(cli1, fnum1);
5404 if (!NT_STATUS_IS_OK(status)) {
5405 printf("close failed (%s)\n", nt_errstr(status));
5409 /* Now open the file again for read only. */
5410 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5411 if (!NT_STATUS_IS_OK(status)) {
5412 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5416 /* Now unlink while open. */
5417 status = cli_posix_unlink(cli1, fname);
5418 if (!NT_STATUS_IS_OK(status)) {
5419 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5423 status = cli_close(cli1, fnum1);
5424 if (!NT_STATUS_IS_OK(status)) {
5425 printf("close(2) failed (%s)\n", nt_errstr(status));
5429 /* Ensure the file has gone. */
5430 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5431 if (NT_STATUS_IS_OK(status)) {
5432 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5436 /* Create again to test open with O_TRUNC. */
5437 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5438 if (!NT_STATUS_IS_OK(status)) {
5439 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5443 /* Test ftruncate - set file size. */
5444 status = cli_ftruncate(cli1, fnum1, 1000);
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("ftruncate failed (%s)\n", nt_errstr(status));
5450 /* Ensure st_size == 1000 */
5451 status = cli_posix_stat(cli1, fname, &sbuf);
5452 if (!NT_STATUS_IS_OK(status)) {
5453 printf("stat failed (%s)\n", nt_errstr(status));
5457 if (sbuf.st_ex_size != 1000) {
5458 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5462 status = cli_close(cli1, fnum1);
5463 if (!NT_STATUS_IS_OK(status)) {
5464 printf("close(2) failed (%s)\n", nt_errstr(status));
5468 /* Re-open with O_TRUNC. */
5469 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5470 if (!NT_STATUS_IS_OK(status)) {
5471 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5475 /* Ensure st_size == 0 */
5476 status = cli_posix_stat(cli1, fname, &sbuf);
5477 if (!NT_STATUS_IS_OK(status)) {
5478 printf("stat failed (%s)\n", nt_errstr(status));
5482 if (sbuf.st_ex_size != 0) {
5483 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5487 status = cli_close(cli1, fnum1);
5488 if (!NT_STATUS_IS_OK(status)) {
5489 printf("close failed (%s)\n", nt_errstr(status));
5493 status = cli_posix_unlink(cli1, fname);
5494 if (!NT_STATUS_IS_OK(status)) {
5495 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5499 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5500 if (!NT_STATUS_IS_OK(status)) {
5501 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5502 dname, nt_errstr(status));
5506 cli_close(cli1, fnum1);
5508 /* What happens when we try and POSIX open a directory for write ? */
5509 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5510 if (NT_STATUS_IS_OK(status)) {
5511 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5514 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5515 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5520 /* Create the file. */
5521 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5523 if (!NT_STATUS_IS_OK(status)) {
5524 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5528 /* Write some data into it. */
5529 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5531 if (!NT_STATUS_IS_OK(status)) {
5532 printf("cli_write failed: %s\n", nt_errstr(status));
5536 cli_close(cli1, fnum1);
5538 /* Now create a hardlink. */
5539 status = cli_posix_hardlink(cli1, fname, hname);
5540 if (!NT_STATUS_IS_OK(status)) {
5541 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5545 /* Now create a symlink. */
5546 status = cli_posix_symlink(cli1, fname, sname);
5547 if (!NT_STATUS_IS_OK(status)) {
5548 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5552 /* Open the hardlink for read. */
5553 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5554 if (!NT_STATUS_IS_OK(status)) {
5555 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5559 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5560 if (!NT_STATUS_IS_OK(status)) {
5561 printf("POSIX read of %s failed (%s)\n", hname,
5564 } else if (nread != 10) {
5565 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5566 hname, (unsigned long)nread, 10);
5570 if (memcmp(buf, "TEST DATA\n", 10)) {
5571 printf("invalid data read from hardlink\n");
5575 /* Do a POSIX lock/unlock. */
5576 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5577 if (!NT_STATUS_IS_OK(status)) {
5578 printf("POSIX lock failed %s\n", nt_errstr(status));
5582 /* Punch a hole in the locked area. */
5583 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5584 if (!NT_STATUS_IS_OK(status)) {
5585 printf("POSIX unlock failed %s\n", nt_errstr(status));
5589 cli_close(cli1, fnum1);
5591 /* Open the symlink for read - this should fail. A POSIX
5592 client should not be doing opens on a symlink. */
5593 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5594 if (NT_STATUS_IS_OK(status)) {
5595 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5598 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5599 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5600 printf("POSIX open of %s should have failed "
5601 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5602 "failed with %s instead.\n",
5603 sname, nt_errstr(status));
5608 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5609 if (!NT_STATUS_IS_OK(status)) {
5610 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5614 if (strcmp(namebuf, fname) != 0) {
5615 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5616 sname, fname, namebuf);
5620 status = cli_posix_rmdir(cli1, dname);
5621 if (!NT_STATUS_IS_OK(status)) {
5622 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5626 printf("Simple POSIX open test passed\n");
5631 if (fnum1 != (uint16_t)-1) {
5632 cli_close(cli1, fnum1);
5633 fnum1 = (uint16_t)-1;
5636 cli_setatr(cli1, sname, 0, 0);
5637 cli_posix_unlink(cli1, sname);
5638 cli_setatr(cli1, hname, 0, 0);
5639 cli_posix_unlink(cli1, hname);
5640 cli_setatr(cli1, fname, 0, 0);
5641 cli_posix_unlink(cli1, fname);
5642 cli_setatr(cli1, dname, 0, 0);
5643 cli_posix_rmdir(cli1, dname);
5645 if (!torture_close_connection(cli1)) {
5653 static uint32 open_attrs_table[] = {
5654 FILE_ATTRIBUTE_NORMAL,
5655 FILE_ATTRIBUTE_ARCHIVE,
5656 FILE_ATTRIBUTE_READONLY,
5657 FILE_ATTRIBUTE_HIDDEN,
5658 FILE_ATTRIBUTE_SYSTEM,
5660 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5661 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5662 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5663 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5664 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5665 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5667 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5668 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5669 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5670 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5673 struct trunc_open_results {
5680 static struct trunc_open_results attr_results[] = {
5681 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5682 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5683 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5684 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5685 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5686 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5687 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5688 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5689 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5690 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5691 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5692 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5693 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5694 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5695 { 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 },
5696 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5697 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5698 { 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 },
5699 { 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 },
5700 { 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 },
5701 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5702 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5703 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5704 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5705 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5706 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5709 static bool run_openattrtest(int dummy)
5711 static struct cli_state *cli1;
5712 const char *fname = "\\openattr.file";
5714 bool correct = True;
5716 unsigned int i, j, k, l;
5719 printf("starting open attr test\n");
5721 if (!torture_open_connection(&cli1, 0)) {
5725 cli_sockopt(cli1, sockops);
5727 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5728 cli_setatr(cli1, fname, 0, 0);
5729 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5731 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5732 open_attrs_table[i], FILE_SHARE_NONE,
5733 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5734 if (!NT_STATUS_IS_OK(status)) {
5735 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5739 status = cli_close(cli1, fnum1);
5740 if (!NT_STATUS_IS_OK(status)) {
5741 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5745 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5746 status = cli_ntcreate(cli1, fname, 0,
5747 FILE_READ_DATA|FILE_WRITE_DATA,
5748 open_attrs_table[j],
5749 FILE_SHARE_NONE, FILE_OVERWRITE,
5751 if (!NT_STATUS_IS_OK(status)) {
5752 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5753 if (attr_results[l].num == k) {
5754 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5755 k, open_attrs_table[i],
5756 open_attrs_table[j],
5757 fname, NT_STATUS_V(status), nt_errstr(status));
5762 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5763 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5764 k, open_attrs_table[i], open_attrs_table[j],
5769 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5775 status = cli_close(cli1, fnum1);
5776 if (!NT_STATUS_IS_OK(status)) {
5777 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5781 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5782 if (!NT_STATUS_IS_OK(status)) {
5783 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5788 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5789 k, open_attrs_table[i], open_attrs_table[j], attr );
5792 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5793 if (attr_results[l].num == k) {
5794 if (attr != attr_results[l].result_attr ||
5795 open_attrs_table[i] != attr_results[l].init_attr ||
5796 open_attrs_table[j] != attr_results[l].trunc_attr) {
5797 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5798 open_attrs_table[i],
5799 open_attrs_table[j],
5801 attr_results[l].result_attr);
5811 cli_setatr(cli1, fname, 0, 0);
5812 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5814 printf("open attr test %s.\n", correct ? "passed" : "failed");
5816 if (!torture_close_connection(cli1)) {
5822 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5823 const char *name, void *state)
5825 int *matched = (int *)state;
5826 if (matched != NULL) {
5829 return NT_STATUS_OK;
5833 test directory listing speed
5835 static bool run_dirtest(int dummy)
5838 static struct cli_state *cli;
5840 struct timeval core_start;
5841 bool correct = True;
5844 printf("starting directory test\n");
5846 if (!torture_open_connection(&cli, 0)) {
5850 cli_sockopt(cli, sockops);
5853 for (i=0;i<torture_numops;i++) {
5855 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5856 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5857 fprintf(stderr,"Failed to open %s\n", fname);
5860 cli_close(cli, fnum);
5863 core_start = timeval_current();
5866 cli_list(cli, "a*.*", 0, list_fn, &matched);
5867 printf("Matched %d\n", matched);
5870 cli_list(cli, "b*.*", 0, list_fn, &matched);
5871 printf("Matched %d\n", matched);
5874 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5875 printf("Matched %d\n", matched);
5877 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5880 for (i=0;i<torture_numops;i++) {
5882 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5883 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5886 if (!torture_close_connection(cli)) {
5890 printf("finished dirtest\n");
5895 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5898 struct cli_state *pcli = (struct cli_state *)state;
5900 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5902 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5903 return NT_STATUS_OK;
5905 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5906 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5907 printf("del_fn: failed to rmdir %s\n,", fname );
5909 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5910 printf("del_fn: failed to unlink %s\n,", fname );
5912 return NT_STATUS_OK;
5917 sees what IOCTLs are supported
5919 bool torture_ioctl_test(int dummy)
5921 static struct cli_state *cli;
5922 uint16_t device, function;
5924 const char *fname = "\\ioctl.dat";
5928 if (!torture_open_connection(&cli, 0)) {
5932 printf("starting ioctl test\n");
5934 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5936 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5937 if (!NT_STATUS_IS_OK(status)) {
5938 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5942 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5943 printf("ioctl device info: %s\n", nt_errstr(status));
5945 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5946 printf("ioctl job info: %s\n", nt_errstr(status));
5948 for (device=0;device<0x100;device++) {
5949 printf("ioctl test with device = 0x%x\n", device);
5950 for (function=0;function<0x100;function++) {
5951 uint32 code = (device<<16) | function;
5953 status = cli_raw_ioctl(cli, fnum, code, &blob);
5955 if (NT_STATUS_IS_OK(status)) {
5956 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5958 data_blob_free(&blob);
5963 if (!torture_close_connection(cli)) {
5972 tries varients of chkpath
5974 bool torture_chkpath_test(int dummy)
5976 static struct cli_state *cli;
5981 if (!torture_open_connection(&cli, 0)) {
5985 printf("starting chkpath test\n");
5987 /* cleanup from an old run */
5988 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5989 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5990 cli_rmdir(cli, "\\chkpath.dir");
5992 status = cli_mkdir(cli, "\\chkpath.dir");
5993 if (!NT_STATUS_IS_OK(status)) {
5994 printf("mkdir1 failed : %s\n", nt_errstr(status));
5998 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5999 if (!NT_STATUS_IS_OK(status)) {
6000 printf("mkdir2 failed : %s\n", nt_errstr(status));
6004 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6006 if (!NT_STATUS_IS_OK(status)) {
6007 printf("open1 failed (%s)\n", nt_errstr(status));
6010 cli_close(cli, fnum);
6012 status = cli_chkpath(cli, "\\chkpath.dir");
6013 if (!NT_STATUS_IS_OK(status)) {
6014 printf("chkpath1 failed: %s\n", nt_errstr(status));
6018 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6019 if (!NT_STATUS_IS_OK(status)) {
6020 printf("chkpath2 failed: %s\n", nt_errstr(status));
6024 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6025 if (!NT_STATUS_IS_OK(status)) {
6026 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6027 NT_STATUS_NOT_A_DIRECTORY);
6029 printf("* chkpath on a file should fail\n");
6033 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6034 if (!NT_STATUS_IS_OK(status)) {
6035 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6036 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6038 printf("* chkpath on a non existant file should fail\n");
6042 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6043 if (!NT_STATUS_IS_OK(status)) {
6044 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6045 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6047 printf("* chkpath on a non existent component should fail\n");
6051 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6052 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6053 cli_rmdir(cli, "\\chkpath.dir");
6055 if (!torture_close_connection(cli)) {
6062 static bool run_eatest(int dummy)
6064 static struct cli_state *cli;
6065 const char *fname = "\\eatest.txt";
6066 bool correct = True;
6070 struct ea_struct *ea_list = NULL;
6071 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6074 printf("starting eatest\n");
6076 if (!torture_open_connection(&cli, 0)) {
6077 talloc_destroy(mem_ctx);
6081 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6083 status = cli_ntcreate(cli, fname, 0,
6084 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6085 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6087 if (!NT_STATUS_IS_OK(status)) {
6088 printf("open failed - %s\n", nt_errstr(status));
6089 talloc_destroy(mem_ctx);
6093 for (i = 0; i < 10; i++) {
6094 fstring ea_name, ea_val;
6096 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6097 memset(ea_val, (char)i+1, i+1);
6098 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6099 if (!NT_STATUS_IS_OK(status)) {
6100 printf("ea_set of name %s failed - %s\n", ea_name,
6102 talloc_destroy(mem_ctx);
6107 cli_close(cli, fnum);
6108 for (i = 0; i < 10; i++) {
6109 fstring ea_name, ea_val;
6111 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6112 memset(ea_val, (char)i+1, i+1);
6113 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6114 if (!NT_STATUS_IS_OK(status)) {
6115 printf("ea_set of name %s failed - %s\n", ea_name,
6117 talloc_destroy(mem_ctx);
6122 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6123 if (!NT_STATUS_IS_OK(status)) {
6124 printf("ea_get list failed - %s\n", nt_errstr(status));
6128 printf("num_eas = %d\n", (int)num_eas);
6130 if (num_eas != 20) {
6131 printf("Should be 20 EA's stored... failing.\n");
6135 for (i = 0; i < num_eas; i++) {
6136 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6137 dump_data(0, ea_list[i].value.data,
6138 ea_list[i].value.length);
6141 /* Setting EA's to zero length deletes them. Test this */
6142 printf("Now deleting all EA's - case indepenent....\n");
6145 cli_set_ea_path(cli, fname, "", "", 0);
6147 for (i = 0; i < 20; i++) {
6149 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6150 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6151 if (!NT_STATUS_IS_OK(status)) {
6152 printf("ea_set of name %s failed - %s\n", ea_name,
6154 talloc_destroy(mem_ctx);
6160 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6161 if (!NT_STATUS_IS_OK(status)) {
6162 printf("ea_get list failed - %s\n", nt_errstr(status));
6166 printf("num_eas = %d\n", (int)num_eas);
6167 for (i = 0; i < num_eas; i++) {
6168 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6169 dump_data(0, ea_list[i].value.data,
6170 ea_list[i].value.length);
6174 printf("deleting EA's failed.\n");
6178 /* Try and delete a non existant EA. */
6179 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6180 if (!NT_STATUS_IS_OK(status)) {
6181 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6186 talloc_destroy(mem_ctx);
6187 if (!torture_close_connection(cli)) {
6194 static bool run_dirtest1(int dummy)
6197 static struct cli_state *cli;
6200 bool correct = True;
6202 printf("starting directory test\n");
6204 if (!torture_open_connection(&cli, 0)) {
6208 cli_sockopt(cli, sockops);
6210 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6211 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6212 cli_rmdir(cli, "\\LISTDIR");
6213 cli_mkdir(cli, "\\LISTDIR");
6215 /* Create 1000 files and 1000 directories. */
6216 for (i=0;i<1000;i++) {
6218 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6219 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6220 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6221 fprintf(stderr,"Failed to open %s\n", fname);
6224 cli_close(cli, fnum);
6226 for (i=0;i<1000;i++) {
6228 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6229 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6230 fprintf(stderr,"Failed to open %s\n", fname);
6235 /* Now ensure that doing an old list sees both files and directories. */
6237 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6238 printf("num_seen = %d\n", num_seen );
6239 /* We should see 100 files + 1000 directories + . and .. */
6240 if (num_seen != 2002)
6243 /* Ensure if we have the "must have" bits we only see the
6247 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6248 printf("num_seen = %d\n", num_seen );
6249 if (num_seen != 1002)
6253 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6254 printf("num_seen = %d\n", num_seen );
6255 if (num_seen != 1000)
6258 /* Delete everything. */
6259 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6260 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6261 cli_rmdir(cli, "\\LISTDIR");
6264 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6265 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6266 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6269 if (!torture_close_connection(cli)) {
6273 printf("finished dirtest1\n");
6278 static bool run_error_map_extract(int dummy) {
6280 static struct cli_state *c_dos;
6281 static struct cli_state *c_nt;
6293 /* NT-Error connection */
6295 if (!(c_nt = open_nbt_connection())) {
6299 c_nt->use_spnego = False;
6301 status = cli_negprot(c_nt);
6303 if (!NT_STATUS_IS_OK(status)) {
6304 printf("%s rejected the NT-error negprot (%s)\n", host,
6310 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6311 if (!NT_STATUS_IS_OK(status)) {
6312 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6316 /* DOS-Error connection */
6318 force_dos_errors = true;
6319 if (!(c_dos = open_nbt_connection())) {
6320 force_dos_errors = false;
6323 force_dos_errors = false;
6325 c_dos->use_spnego = False;
6327 status = cli_negprot(c_dos);
6328 if (!NT_STATUS_IS_OK(status)) {
6329 printf("%s rejected the DOS-error negprot (%s)\n", host,
6331 cli_shutdown(c_dos);
6335 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6336 if (!NT_STATUS_IS_OK(status)) {
6337 printf("%s rejected the DOS-error initial session setup (%s)\n",
6338 host, nt_errstr(status));
6342 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6343 fstr_sprintf(user, "%X", error);
6345 status = cli_session_setup(c_nt, user,
6346 password, strlen(password),
6347 password, strlen(password),
6349 if (NT_STATUS_IS_OK(status)) {
6350 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6353 /* Case #1: 32-bit NT errors */
6354 if (cli_is_nt_error(c_nt)) {
6355 nt_status = cli_nt_error(c_nt);
6357 printf("/** Dos error on NT connection! (%s) */\n",
6359 nt_status = NT_STATUS(0xc0000000);
6362 status = cli_session_setup(c_dos, user,
6363 password, strlen(password),
6364 password, strlen(password),
6366 if (NT_STATUS_IS_OK(status)) {
6367 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6370 /* Case #1: 32-bit NT errors */
6371 if (!cli_is_dos_error(c_dos)) {
6372 printf("/** NT error on DOS connection! (%s) */\n",
6374 errnum = errclass = 0;
6376 cli_dos_error(c_dos, &errclass, &errnum);
6379 if (NT_STATUS_V(nt_status) != error) {
6380 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6381 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6382 get_nt_error_c_code(talloc_tos(), nt_status));
6385 printf("\t{%s,\t%s,\t%s},\n",
6386 smb_dos_err_class(errclass),
6387 smb_dos_err_name(errclass, errnum),
6388 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6393 static bool run_sesssetup_bench(int dummy)
6395 static struct cli_state *c;
6396 const char *fname = "\\file.dat";
6401 if (!torture_open_connection(&c, 0)) {
6405 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6406 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6407 FILE_DELETE_ON_CLOSE, 0, &fnum);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6413 for (i=0; i<torture_numops; i++) {
6414 status = cli_session_setup(
6416 password, strlen(password),
6417 password, strlen(password),
6419 if (!NT_STATUS_IS_OK(status)) {
6420 d_printf("(%s) cli_session_setup failed: %s\n",
6421 __location__, nt_errstr(status));
6425 d_printf("\r%d ", (int)cli_state_get_uid(c));
6427 status = cli_ulogoff(c);
6428 if (!NT_STATUS_IS_OK(status)) {
6429 d_printf("(%s) cli_ulogoff failed: %s\n",
6430 __location__, nt_errstr(status));
6438 static bool subst_test(const char *str, const char *user, const char *domain,
6439 uid_t uid, gid_t gid, const char *expected)
6444 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6446 if (strcmp(subst, expected) != 0) {
6447 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6448 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6457 static void chain1_open_completion(struct tevent_req *req)
6461 status = cli_open_recv(req, &fnum);
6464 d_printf("cli_open_recv returned %s: %d\n",
6466 NT_STATUS_IS_OK(status) ? fnum : -1);
6469 static void chain1_write_completion(struct tevent_req *req)
6473 status = cli_write_andx_recv(req, &written);
6476 d_printf("cli_write_andx_recv returned %s: %d\n",
6478 NT_STATUS_IS_OK(status) ? (int)written : -1);
6481 static void chain1_close_completion(struct tevent_req *req)
6484 bool *done = (bool *)tevent_req_callback_data_void(req);
6486 status = cli_close_recv(req);
6491 d_printf("cli_close returned %s\n", nt_errstr(status));
6494 static bool run_chain1(int dummy)
6496 struct cli_state *cli1;
6497 struct event_context *evt = event_context_init(NULL);
6498 struct tevent_req *reqs[3], *smbreqs[3];
6500 const char *str = "foobar";
6503 printf("starting chain1 test\n");
6504 if (!torture_open_connection(&cli1, 0)) {
6508 cli_sockopt(cli1, sockops);
6510 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6511 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6512 if (reqs[0] == NULL) return false;
6513 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6516 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6517 (const uint8_t *)str, 0, strlen(str)+1,
6518 smbreqs, 1, &smbreqs[1]);
6519 if (reqs[1] == NULL) return false;
6520 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6522 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6523 if (reqs[2] == NULL) return false;
6524 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6526 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6527 if (!NT_STATUS_IS_OK(status)) {
6532 tevent_loop_once(evt);
6535 torture_close_connection(cli1);
6539 static void chain2_sesssetup_completion(struct tevent_req *req)
6542 status = cli_session_setup_guest_recv(req);
6543 d_printf("sesssetup returned %s\n", nt_errstr(status));
6546 static void chain2_tcon_completion(struct tevent_req *req)
6548 bool *done = (bool *)tevent_req_callback_data_void(req);
6550 status = cli_tcon_andx_recv(req);
6551 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6555 static bool run_chain2(int dummy)
6557 struct cli_state *cli1;
6558 struct event_context *evt = event_context_init(NULL);
6559 struct tevent_req *reqs[2], *smbreqs[2];
6563 printf("starting chain2 test\n");
6564 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6565 port_to_use, Undefined, 0);
6566 if (!NT_STATUS_IS_OK(status)) {
6570 cli_sockopt(cli1, sockops);
6572 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6574 if (reqs[0] == NULL) return false;
6575 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6577 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6578 "?????", NULL, 0, &smbreqs[1]);
6579 if (reqs[1] == NULL) return false;
6580 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6582 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6583 if (!NT_STATUS_IS_OK(status)) {
6588 tevent_loop_once(evt);
6591 torture_close_connection(cli1);
6596 struct torture_createdel_state {
6597 struct tevent_context *ev;
6598 struct cli_state *cli;
6601 static void torture_createdel_created(struct tevent_req *subreq);
6602 static void torture_createdel_closed(struct tevent_req *subreq);
6604 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6605 struct tevent_context *ev,
6606 struct cli_state *cli,
6609 struct tevent_req *req, *subreq;
6610 struct torture_createdel_state *state;
6612 req = tevent_req_create(mem_ctx, &state,
6613 struct torture_createdel_state);
6620 subreq = cli_ntcreate_send(
6621 state, ev, cli, name, 0,
6622 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6623 FILE_ATTRIBUTE_NORMAL,
6624 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6625 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6627 if (tevent_req_nomem(subreq, req)) {
6628 return tevent_req_post(req, ev);
6630 tevent_req_set_callback(subreq, torture_createdel_created, req);
6634 static void torture_createdel_created(struct tevent_req *subreq)
6636 struct tevent_req *req = tevent_req_callback_data(
6637 subreq, struct tevent_req);
6638 struct torture_createdel_state *state = tevent_req_data(
6639 req, struct torture_createdel_state);
6643 status = cli_ntcreate_recv(subreq, &fnum);
6644 TALLOC_FREE(subreq);
6645 if (!NT_STATUS_IS_OK(status)) {
6646 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6647 nt_errstr(status)));
6648 tevent_req_nterror(req, status);
6652 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6653 if (tevent_req_nomem(subreq, req)) {
6656 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6659 static void torture_createdel_closed(struct tevent_req *subreq)
6661 struct tevent_req *req = tevent_req_callback_data(
6662 subreq, struct tevent_req);
6665 status = cli_close_recv(subreq);
6666 if (!NT_STATUS_IS_OK(status)) {
6667 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6668 tevent_req_nterror(req, status);
6671 tevent_req_done(req);
6674 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6676 return tevent_req_simple_recv_ntstatus(req);
6679 struct torture_createdels_state {
6680 struct tevent_context *ev;
6681 struct cli_state *cli;
6682 const char *base_name;
6686 struct tevent_req **reqs;
6689 static void torture_createdels_done(struct tevent_req *subreq);
6691 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6692 struct tevent_context *ev,
6693 struct cli_state *cli,
6694 const char *base_name,
6698 struct tevent_req *req;
6699 struct torture_createdels_state *state;
6702 req = tevent_req_create(mem_ctx, &state,
6703 struct torture_createdels_state);
6709 state->base_name = talloc_strdup(state, base_name);
6710 if (tevent_req_nomem(state->base_name, req)) {
6711 return tevent_req_post(req, ev);
6713 state->num_files = MAX(num_parallel, num_files);
6715 state->received = 0;
6717 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6718 if (tevent_req_nomem(state->reqs, req)) {
6719 return tevent_req_post(req, ev);
6722 for (i=0; i<num_parallel; i++) {
6725 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6727 if (tevent_req_nomem(name, req)) {
6728 return tevent_req_post(req, ev);
6730 state->reqs[i] = torture_createdel_send(
6731 state->reqs, state->ev, state->cli, name);
6732 if (tevent_req_nomem(state->reqs[i], req)) {
6733 return tevent_req_post(req, ev);
6735 name = talloc_move(state->reqs[i], &name);
6736 tevent_req_set_callback(state->reqs[i],
6737 torture_createdels_done, req);
6743 static void torture_createdels_done(struct tevent_req *subreq)
6745 struct tevent_req *req = tevent_req_callback_data(
6746 subreq, struct tevent_req);
6747 struct torture_createdels_state *state = tevent_req_data(
6748 req, struct torture_createdels_state);
6749 size_t num_parallel = talloc_array_length(state->reqs);
6754 status = torture_createdel_recv(subreq);
6755 if (!NT_STATUS_IS_OK(status)){
6756 DEBUG(10, ("torture_createdel_recv returned %s\n",
6757 nt_errstr(status)));
6758 TALLOC_FREE(subreq);
6759 tevent_req_nterror(req, status);
6763 for (i=0; i<num_parallel; i++) {
6764 if (subreq == state->reqs[i]) {
6768 if (i == num_parallel) {
6769 DEBUG(10, ("received something we did not send\n"));
6770 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6773 TALLOC_FREE(state->reqs[i]);
6775 if (state->sent >= state->num_files) {
6776 tevent_req_done(req);
6780 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6782 if (tevent_req_nomem(name, req)) {
6785 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6787 if (tevent_req_nomem(state->reqs[i], req)) {
6790 name = talloc_move(state->reqs[i], &name);
6791 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6795 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6797 return tevent_req_simple_recv_ntstatus(req);
6800 struct swallow_notify_state {
6801 struct tevent_context *ev;
6802 struct cli_state *cli;
6804 uint32_t completion_filter;
6806 bool (*fn)(uint32_t action, const char *name, void *priv);
6810 static void swallow_notify_done(struct tevent_req *subreq);
6812 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6813 struct tevent_context *ev,
6814 struct cli_state *cli,
6816 uint32_t completion_filter,
6818 bool (*fn)(uint32_t action,
6823 struct tevent_req *req, *subreq;
6824 struct swallow_notify_state *state;
6826 req = tevent_req_create(mem_ctx, &state,
6827 struct swallow_notify_state);
6834 state->completion_filter = completion_filter;
6835 state->recursive = recursive;
6839 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6840 0xffff, state->completion_filter,
6842 if (tevent_req_nomem(subreq, req)) {
6843 return tevent_req_post(req, ev);
6845 tevent_req_set_callback(subreq, swallow_notify_done, req);
6849 static void swallow_notify_done(struct tevent_req *subreq)
6851 struct tevent_req *req = tevent_req_callback_data(
6852 subreq, struct tevent_req);
6853 struct swallow_notify_state *state = tevent_req_data(
6854 req, struct swallow_notify_state);
6856 uint32_t i, num_changes;
6857 struct notify_change *changes;
6859 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6860 TALLOC_FREE(subreq);
6861 if (!NT_STATUS_IS_OK(status)) {
6862 DEBUG(10, ("cli_notify_recv returned %s\n",
6863 nt_errstr(status)));
6864 tevent_req_nterror(req, status);
6868 for (i=0; i<num_changes; i++) {
6869 state->fn(changes[i].action, changes[i].name, state->priv);
6871 TALLOC_FREE(changes);
6873 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6874 0xffff, state->completion_filter,
6876 if (tevent_req_nomem(subreq, req)) {
6879 tevent_req_set_callback(subreq, swallow_notify_done, req);
6882 static bool print_notifies(uint32_t action, const char *name, void *priv)
6884 if (DEBUGLEVEL > 5) {
6885 d_printf("%d %s\n", (int)action, name);
6890 static void notify_bench_done(struct tevent_req *req)
6892 int *num_finished = (int *)tevent_req_callback_data_void(req);
6896 static bool run_notify_bench(int dummy)
6898 const char *dname = "\\notify-bench";
6899 struct tevent_context *ev;
6902 struct tevent_req *req1;
6903 struct tevent_req *req2 = NULL;
6904 int i, num_unc_names;
6905 int num_finished = 0;
6907 printf("starting notify-bench test\n");
6909 if (use_multishare_conn) {
6911 unc_list = file_lines_load(multishare_conn_fname,
6912 &num_unc_names, 0, NULL);
6913 if (!unc_list || num_unc_names <= 0) {
6914 d_printf("Failed to load unc names list from '%s'\n",
6915 multishare_conn_fname);
6918 TALLOC_FREE(unc_list);
6923 ev = tevent_context_init(talloc_tos());
6925 d_printf("tevent_context_init failed\n");
6929 for (i=0; i<num_unc_names; i++) {
6930 struct cli_state *cli;
6933 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6935 if (base_fname == NULL) {
6939 if (!torture_open_connection(&cli, i)) {
6943 status = cli_ntcreate(cli, dname, 0,
6944 MAXIMUM_ALLOWED_ACCESS,
6945 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6947 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6950 if (!NT_STATUS_IS_OK(status)) {
6951 d_printf("Could not create %s: %s\n", dname,
6956 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6957 FILE_NOTIFY_CHANGE_FILE_NAME |
6958 FILE_NOTIFY_CHANGE_DIR_NAME |
6959 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6960 FILE_NOTIFY_CHANGE_LAST_WRITE,
6961 false, print_notifies, NULL);
6963 d_printf("Could not create notify request\n");
6967 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6968 base_fname, 10, torture_numops);
6970 d_printf("Could not create createdels request\n");
6973 TALLOC_FREE(base_fname);
6975 tevent_req_set_callback(req2, notify_bench_done,
6979 while (num_finished < num_unc_names) {
6981 ret = tevent_loop_once(ev);
6983 d_printf("tevent_loop_once failed\n");
6988 if (!tevent_req_poll(req2, ev)) {
6989 d_printf("tevent_req_poll failed\n");
6992 status = torture_createdels_recv(req2);
6993 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6998 static bool run_mangle1(int dummy)
7000 struct cli_state *cli;
7001 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7005 time_t change_time, access_time, write_time;
7009 printf("starting mangle1 test\n");
7010 if (!torture_open_connection(&cli, 0)) {
7014 cli_sockopt(cli, sockops);
7016 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7017 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7019 if (!NT_STATUS_IS_OK(status)) {
7020 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7023 cli_close(cli, fnum);
7025 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7026 if (!NT_STATUS_IS_OK(status)) {
7027 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7031 d_printf("alt_name: %s\n", alt_name);
7033 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7034 if (!NT_STATUS_IS_OK(status)) {
7035 d_printf("cli_open(%s) failed: %s\n", alt_name,
7039 cli_close(cli, fnum);
7041 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7042 &write_time, &size, &mode);
7043 if (!NT_STATUS_IS_OK(status)) {
7044 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7052 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7054 size_t *to_pull = (size_t *)priv;
7055 size_t thistime = *to_pull;
7057 thistime = MIN(thistime, n);
7058 if (thistime == 0) {
7062 memset(buf, 0, thistime);
7063 *to_pull -= thistime;
7067 static bool run_windows_write(int dummy)
7069 struct cli_state *cli1;
7073 const char *fname = "\\writetest.txt";
7074 struct timeval start_time;
7079 printf("starting windows_write test\n");
7080 if (!torture_open_connection(&cli1, 0)) {
7084 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7085 if (!NT_STATUS_IS_OK(status)) {
7086 printf("open failed (%s)\n", nt_errstr(status));
7090 cli_sockopt(cli1, sockops);
7092 start_time = timeval_current();
7094 for (i=0; i<torture_numops; i++) {
7096 off_t start = i * torture_blocksize;
7097 size_t to_pull = torture_blocksize - 1;
7099 status = cli_writeall(cli1, fnum, 0, &c,
7100 start + torture_blocksize - 1, 1, NULL);
7101 if (!NT_STATUS_IS_OK(status)) {
7102 printf("cli_write failed: %s\n", nt_errstr(status));
7106 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7107 null_source, &to_pull);
7108 if (!NT_STATUS_IS_OK(status)) {
7109 printf("cli_push returned: %s\n", nt_errstr(status));
7114 seconds = timeval_elapsed(&start_time);
7115 kbytes = (double)torture_blocksize * torture_numops;
7118 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7119 (double)seconds, (int)(kbytes/seconds));
7123 cli_close(cli1, fnum);
7124 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7125 torture_close_connection(cli1);
7129 static bool run_cli_echo(int dummy)
7131 struct cli_state *cli;
7134 printf("starting cli_echo test\n");
7135 if (!torture_open_connection(&cli, 0)) {
7138 cli_sockopt(cli, sockops);
7140 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7142 d_printf("cli_echo returned %s\n", nt_errstr(status));
7144 torture_close_connection(cli);
7145 return NT_STATUS_IS_OK(status);
7148 static bool run_uid_regression_test(int dummy)
7150 static struct cli_state *cli;
7153 bool correct = True;
7156 printf("starting uid regression test\n");
7158 if (!torture_open_connection(&cli, 0)) {
7162 cli_sockopt(cli, sockops);
7164 /* Ok - now save then logoff our current user. */
7165 old_vuid = cli_state_get_uid(cli);
7167 status = cli_ulogoff(cli);
7168 if (!NT_STATUS_IS_OK(status)) {
7169 d_printf("(%s) cli_ulogoff failed: %s\n",
7170 __location__, nt_errstr(status));
7175 cli_state_set_uid(cli, old_vuid);
7177 /* Try an operation. */
7178 status = cli_mkdir(cli, "\\uid_reg_test");
7179 if (NT_STATUS_IS_OK(status)) {
7180 d_printf("(%s) cli_mkdir succeeded\n",
7185 /* Should be bad uid. */
7186 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7187 NT_STATUS_USER_SESSION_DELETED)) {
7193 old_cnum = cli_state_get_tid(cli);
7195 /* Now try a SMBtdis with the invald vuid set to zero. */
7196 cli_state_set_uid(cli, 0);
7198 /* This should succeed. */
7199 status = cli_tdis(cli);
7201 if (NT_STATUS_IS_OK(status)) {
7202 d_printf("First tdis with invalid vuid should succeed.\n");
7204 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7209 cli_state_set_uid(cli, old_vuid);
7210 cli_state_set_tid(cli, old_cnum);
7212 /* This should fail. */
7213 status = cli_tdis(cli);
7214 if (NT_STATUS_IS_OK(status)) {
7215 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7219 /* Should be bad tid. */
7220 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7221 NT_STATUS_NETWORK_NAME_DELETED)) {
7227 cli_rmdir(cli, "\\uid_reg_test");
7236 static const char *illegal_chars = "*\\/?<>|\":";
7237 static char force_shortname_chars[] = " +,.[];=\177";
7239 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7240 const char *mask, void *state)
7242 struct cli_state *pcli = (struct cli_state *)state;
7244 NTSTATUS status = NT_STATUS_OK;
7246 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7248 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7249 return NT_STATUS_OK;
7251 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7252 status = cli_rmdir(pcli, fname);
7253 if (!NT_STATUS_IS_OK(status)) {
7254 printf("del_fn: failed to rmdir %s\n,", fname );
7257 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7258 if (!NT_STATUS_IS_OK(status)) {
7259 printf("del_fn: failed to unlink %s\n,", fname );
7271 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7272 const char *name, void *state)
7274 struct sn_state *s = (struct sn_state *)state;
7278 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7279 i, finfo->name, finfo->short_name);
7282 if (strchr(force_shortname_chars, i)) {
7283 if (!finfo->short_name) {
7284 /* Shortname not created when it should be. */
7285 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7286 __location__, finfo->name, i);
7289 } else if (finfo->short_name){
7290 /* Shortname created when it should not be. */
7291 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7292 __location__, finfo->short_name, finfo->name);
7296 return NT_STATUS_OK;
7299 static bool run_shortname_test(int dummy)
7301 static struct cli_state *cli;
7302 bool correct = True;
7308 printf("starting shortname test\n");
7310 if (!torture_open_connection(&cli, 0)) {
7314 cli_sockopt(cli, sockops);
7316 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7317 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7318 cli_rmdir(cli, "\\shortname");
7320 status = cli_mkdir(cli, "\\shortname");
7321 if (!NT_STATUS_IS_OK(status)) {
7322 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7323 __location__, nt_errstr(status));
7328 strlcpy(fname, "\\shortname\\", sizeof(fname));
7329 strlcat(fname, "test .txt", sizeof(fname));
7333 for (i = 32; i < 128; i++) {
7334 uint16_t fnum = (uint16_t)-1;
7338 if (strchr(illegal_chars, i)) {
7343 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7344 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7345 if (!NT_STATUS_IS_OK(status)) {
7346 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7347 __location__, fname, nt_errstr(status));
7351 cli_close(cli, fnum);
7354 status = cli_list(cli, "\\shortname\\test*.*", 0,
7355 shortname_list_fn, &s);
7356 if (s.matched != 1) {
7357 d_printf("(%s) failed to list %s: %s\n",
7358 __location__, fname, nt_errstr(status));
7363 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7364 if (!NT_STATUS_IS_OK(status)) {
7365 d_printf("(%s) failed to delete %s: %s\n",
7366 __location__, fname, nt_errstr(status));
7379 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7380 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7381 cli_rmdir(cli, "\\shortname");
7382 torture_close_connection(cli);
7386 static void pagedsearch_cb(struct tevent_req *req)
7389 struct tldap_message *msg;
7392 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7393 if (rc != TLDAP_SUCCESS) {
7394 d_printf("tldap_search_paged_recv failed: %s\n",
7395 tldap_err2string(rc));
7398 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7402 if (!tldap_entry_dn(msg, &dn)) {
7403 d_printf("tldap_entry_dn failed\n");
7406 d_printf("%s\n", dn);
7410 static bool run_tldap(int dummy)
7412 struct tldap_context *ld;
7415 struct sockaddr_storage addr;
7416 struct tevent_context *ev;
7417 struct tevent_req *req;
7421 if (!resolve_name(host, &addr, 0, false)) {
7422 d_printf("could not find host %s\n", host);
7425 status = open_socket_out(&addr, 389, 9999, &fd);
7426 if (!NT_STATUS_IS_OK(status)) {
7427 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7431 ld = tldap_context_create(talloc_tos(), fd);
7434 d_printf("tldap_context_create failed\n");
7438 rc = tldap_fetch_rootdse(ld);
7439 if (rc != TLDAP_SUCCESS) {
7440 d_printf("tldap_fetch_rootdse failed: %s\n",
7441 tldap_errstr(talloc_tos(), ld, rc));
7445 basedn = tldap_talloc_single_attribute(
7446 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7447 if (basedn == NULL) {
7448 d_printf("no defaultNamingContext\n");
7451 d_printf("defaultNamingContext: %s\n", basedn);
7453 ev = tevent_context_init(talloc_tos());
7455 d_printf("tevent_context_init failed\n");
7459 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7460 TLDAP_SCOPE_SUB, "(objectclass=*)",
7462 NULL, 0, NULL, 0, 0, 0, 0, 5);
7464 d_printf("tldap_search_paged_send failed\n");
7467 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7469 tevent_req_poll(req, ev);
7473 /* test search filters against rootDSE */
7474 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7475 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7477 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7478 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7479 talloc_tos(), NULL, NULL);
7480 if (rc != TLDAP_SUCCESS) {
7481 d_printf("tldap_search with complex filter failed: %s\n",
7482 tldap_errstr(talloc_tos(), ld, rc));
7490 /* Torture test to ensure no regression of :
7491 https://bugzilla.samba.org/show_bug.cgi?id=7084
7494 static bool run_dir_createtime(int dummy)
7496 struct cli_state *cli;
7497 const char *dname = "\\testdir";
7498 const char *fname = "\\testdir\\testfile";
7500 struct timespec create_time;
7501 struct timespec create_time1;
7505 if (!torture_open_connection(&cli, 0)) {
7509 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7510 cli_rmdir(cli, dname);
7512 status = cli_mkdir(cli, dname);
7513 if (!NT_STATUS_IS_OK(status)) {
7514 printf("mkdir failed: %s\n", nt_errstr(status));
7518 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7520 if (!NT_STATUS_IS_OK(status)) {
7521 printf("cli_qpathinfo2 returned %s\n",
7526 /* Sleep 3 seconds, then create a file. */
7529 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7531 if (!NT_STATUS_IS_OK(status)) {
7532 printf("cli_open failed: %s\n", nt_errstr(status));
7536 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7538 if (!NT_STATUS_IS_OK(status)) {
7539 printf("cli_qpathinfo2 (2) returned %s\n",
7544 if (timespec_compare(&create_time1, &create_time)) {
7545 printf("run_dir_createtime: create time was updated (error)\n");
7547 printf("run_dir_createtime: create time was not updated (correct)\n");
7553 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7554 cli_rmdir(cli, dname);
7555 if (!torture_close_connection(cli)) {
7562 static bool run_streamerror(int dummy)
7564 struct cli_state *cli;
7565 const char *dname = "\\testdir";
7566 const char *streamname =
7567 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7569 time_t change_time, access_time, write_time;
7571 uint16_t mode, fnum;
7574 if (!torture_open_connection(&cli, 0)) {
7578 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7579 cli_rmdir(cli, dname);
7581 status = cli_mkdir(cli, dname);
7582 if (!NT_STATUS_IS_OK(status)) {
7583 printf("mkdir failed: %s\n", nt_errstr(status));
7587 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7589 status = cli_nt_error(cli);
7591 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7592 printf("pathinfo returned %s, expected "
7593 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7598 status = cli_ntcreate(cli, streamname, 0x16,
7599 FILE_READ_DATA|FILE_READ_EA|
7600 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7601 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7602 FILE_OPEN, 0, 0, &fnum);
7604 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7605 printf("ntcreate returned %s, expected "
7606 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7612 cli_rmdir(cli, dname);
7616 static bool run_local_substitute(int dummy)
7620 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7621 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7622 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7623 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7624 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7625 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7626 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7627 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7629 /* Different captialization rules in sub_basic... */
7631 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7637 static bool run_local_base64(int dummy)
7642 for (i=1; i<2000; i++) {
7643 DATA_BLOB blob1, blob2;
7646 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7648 generate_random_buffer(blob1.data, blob1.length);
7650 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7652 d_fprintf(stderr, "base64_encode_data_blob failed "
7653 "for %d bytes\n", i);
7656 blob2 = base64_decode_data_blob(b64);
7659 if (data_blob_cmp(&blob1, &blob2)) {
7660 d_fprintf(stderr, "data_blob_cmp failed for %d "
7664 TALLOC_FREE(blob1.data);
7665 data_blob_free(&blob2);
7670 static bool run_local_gencache(int dummy)
7676 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7677 d_printf("%s: gencache_set() failed\n", __location__);
7681 if (!gencache_get("foo", NULL, NULL)) {
7682 d_printf("%s: gencache_get() failed\n", __location__);
7686 if (!gencache_get("foo", &val, &tm)) {
7687 d_printf("%s: gencache_get() failed\n", __location__);
7691 if (strcmp(val, "bar") != 0) {
7692 d_printf("%s: gencache_get() returned %s, expected %s\n",
7693 __location__, val, "bar");
7700 if (!gencache_del("foo")) {
7701 d_printf("%s: gencache_del() failed\n", __location__);
7704 if (gencache_del("foo")) {
7705 d_printf("%s: second gencache_del() succeeded\n",
7710 if (gencache_get("foo", &val, &tm)) {
7711 d_printf("%s: gencache_get() on deleted entry "
7712 "succeeded\n", __location__);
7716 blob = data_blob_string_const_null("bar");
7717 tm = time(NULL) + 60;
7719 if (!gencache_set_data_blob("foo", &blob, tm)) {
7720 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7724 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7725 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7729 if (strcmp((const char *)blob.data, "bar") != 0) {
7730 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7731 __location__, (const char *)blob.data, "bar");
7732 data_blob_free(&blob);
7736 data_blob_free(&blob);
7738 if (!gencache_del("foo")) {
7739 d_printf("%s: gencache_del() failed\n", __location__);
7742 if (gencache_del("foo")) {
7743 d_printf("%s: second gencache_del() succeeded\n",
7748 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7749 d_printf("%s: gencache_get_data_blob() on deleted entry "
7750 "succeeded\n", __location__);
7757 static bool rbt_testval(struct db_context *db, const char *key,
7760 struct db_record *rec;
7761 TDB_DATA data = string_tdb_data(value);
7765 rec = db->fetch_locked(db, db, string_tdb_data(key));
7767 d_fprintf(stderr, "fetch_locked failed\n");
7770 status = rec->store(rec, data, 0);
7771 if (!NT_STATUS_IS_OK(status)) {
7772 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7777 rec = db->fetch_locked(db, db, string_tdb_data(key));
7779 d_fprintf(stderr, "second fetch_locked failed\n");
7782 if ((rec->value.dsize != data.dsize)
7783 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7784 d_fprintf(stderr, "Got wrong data back\n");
7794 static bool run_local_rbtree(int dummy)
7796 struct db_context *db;
7800 db = db_open_rbt(NULL);
7803 d_fprintf(stderr, "db_open_rbt failed\n");
7807 for (i=0; i<1000; i++) {
7810 if (asprintf(&key, "key%ld", random()) == -1) {
7813 if (asprintf(&value, "value%ld", random()) == -1) {
7818 if (!rbt_testval(db, key, value)) {
7825 if (asprintf(&value, "value%ld", random()) == -1) {
7830 if (!rbt_testval(db, key, value)) {
7849 local test for character set functions
7851 This is a very simple test for the functionality in convert_string_error()
7853 static bool run_local_convert_string(int dummy)
7855 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7856 const char *test_strings[2] = { "March", "M\303\244rz" };
7860 for (i=0; i<2; i++) {
7861 const char *str = test_strings[i];
7862 int len = strlen(str);
7863 size_t converted_size;
7866 memset(dst, 'X', sizeof(dst));
7868 /* first try with real source length */
7869 ret = convert_string_error(CH_UNIX, CH_UTF8,
7874 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7878 if (converted_size != len) {
7879 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7880 str, len, (int)converted_size);
7884 if (strncmp(str, dst, converted_size) != 0) {
7885 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7889 if (strlen(str) != converted_size) {
7890 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7891 (int)strlen(str), (int)converted_size);
7895 if (dst[converted_size] != 'X') {
7896 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7900 /* now with srclen==-1, this causes the nul to be
7902 ret = convert_string_error(CH_UNIX, CH_UTF8,
7907 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7911 if (converted_size != len+1) {
7912 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7913 str, len, (int)converted_size);
7917 if (strncmp(str, dst, converted_size) != 0) {
7918 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7922 if (len+1 != converted_size) {
7923 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7924 len+1, (int)converted_size);
7928 if (dst[converted_size] != 'X') {
7929 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7936 TALLOC_FREE(tmp_ctx);
7939 TALLOC_FREE(tmp_ctx);
7944 struct talloc_dict_test {
7948 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7950 int *count = (int *)priv;
7955 static bool run_local_talloc_dict(int dummy)
7957 struct talloc_dict *dict;
7958 struct talloc_dict_test *t;
7961 dict = talloc_dict_init(talloc_tos());
7966 t = talloc(talloc_tos(), struct talloc_dict_test);
7973 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7978 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7991 static bool run_local_string_to_sid(int dummy) {
7994 if (string_to_sid(&sid, "S--1-5-32-545")) {
7995 printf("allowing S--1-5-32-545\n");
7998 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7999 printf("allowing S-1-5-32-+545\n");
8002 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")) {
8003 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8006 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
8007 printf("allowing S-1-5-32-545-abc\n");
8010 if (!string_to_sid(&sid, "S-1-5-32-545")) {
8011 printf("could not parse S-1-5-32-545\n");
8014 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8015 printf("mis-parsed S-1-5-32-545 as %s\n",
8016 sid_string_tos(&sid));
8022 static bool run_local_binary_to_sid(int dummy) {
8023 struct dom_sid *sid = talloc(NULL, struct dom_sid);
8024 static const char good_binary_sid[] = {
8025 0x1, /* revision number */
8027 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8028 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8029 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8030 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8031 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8032 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8033 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8034 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8035 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8036 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8037 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8038 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8039 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8040 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8041 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8042 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8045 static const char long_binary_sid[] = {
8046 0x1, /* revision number */
8048 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8049 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8050 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8051 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8052 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8053 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8054 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8055 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8056 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8057 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8058 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8059 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8060 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8061 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8062 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8063 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8069 static const char long_binary_sid2[] = {
8070 0x1, /* revision number */
8072 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8073 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8074 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8075 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8076 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8077 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8078 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8079 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8080 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8081 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8082 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8083 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8084 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8098 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8099 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8100 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8101 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8102 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8103 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8104 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8107 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8110 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8113 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8119 /* Split a path name into filename and stream name components. Canonicalise
8120 * such that an implicit $DATA token is always explicit.
8122 * The "specification" of this function can be found in the
8123 * run_local_stream_name() function in torture.c, I've tried those
8124 * combinations against a W2k3 server.
8127 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8128 char **pbase, char **pstream)
8131 char *stream = NULL;
8132 char *sname; /* stream name */
8133 const char *stype; /* stream type */
8135 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8137 sname = strchr_m(fname, ':');
8139 if (lp_posix_pathnames() || (sname == NULL)) {
8140 if (pbase != NULL) {
8141 base = talloc_strdup(mem_ctx, fname);
8142 NT_STATUS_HAVE_NO_MEMORY(base);
8147 if (pbase != NULL) {
8148 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8149 NT_STATUS_HAVE_NO_MEMORY(base);
8154 stype = strchr_m(sname, ':');
8156 if (stype == NULL) {
8157 sname = talloc_strdup(mem_ctx, sname);
8161 if (strcasecmp_m(stype, ":$DATA") != 0) {
8163 * If there is an explicit stream type, so far we only
8164 * allow $DATA. Is there anything else allowed? -- vl
8166 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8168 return NT_STATUS_OBJECT_NAME_INVALID;
8170 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8174 if (sname == NULL) {
8176 return NT_STATUS_NO_MEMORY;
8179 if (sname[0] == '\0') {
8181 * no stream name, so no stream
8186 if (pstream != NULL) {
8187 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8188 if (stream == NULL) {
8191 return NT_STATUS_NO_MEMORY;
8194 * upper-case the type field
8196 strupper_m(strchr_m(stream, ':')+1);
8200 if (pbase != NULL) {
8203 if (pstream != NULL) {
8206 return NT_STATUS_OK;
8209 static bool test_stream_name(const char *fname, const char *expected_base,
8210 const char *expected_stream,
8211 NTSTATUS expected_status)
8215 char *stream = NULL;
8217 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8218 if (!NT_STATUS_EQUAL(status, expected_status)) {
8222 if (!NT_STATUS_IS_OK(status)) {
8226 if (base == NULL) goto error;
8228 if (strcmp(expected_base, base) != 0) goto error;
8230 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8231 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8233 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8237 TALLOC_FREE(stream);
8241 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8242 fname, expected_base ? expected_base : "<NULL>",
8243 expected_stream ? expected_stream : "<NULL>",
8244 nt_errstr(expected_status));
8245 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8246 base ? base : "<NULL>", stream ? stream : "<NULL>",
8249 TALLOC_FREE(stream);
8253 static bool run_local_stream_name(int dummy)
8257 ret &= test_stream_name(
8258 "bla", "bla", NULL, NT_STATUS_OK);
8259 ret &= test_stream_name(
8260 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8261 ret &= test_stream_name(
8262 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8263 ret &= test_stream_name(
8264 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8265 ret &= test_stream_name(
8266 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8267 ret &= test_stream_name(
8268 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8269 ret &= test_stream_name(
8270 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8271 ret &= test_stream_name(
8272 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8277 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8279 if (a.length != b.length) {
8280 printf("a.length=%d != b.length=%d\n",
8281 (int)a.length, (int)b.length);
8284 if (memcmp(a.data, b.data, a.length) != 0) {
8285 printf("a.data and b.data differ\n");
8291 static bool run_local_memcache(int dummy)
8293 struct memcache *cache;
8295 DATA_BLOB d1, d2, d3;
8296 DATA_BLOB v1, v2, v3;
8298 TALLOC_CTX *mem_ctx;
8300 size_t size1, size2;
8303 cache = memcache_init(NULL, 100);
8305 if (cache == NULL) {
8306 printf("memcache_init failed\n");
8310 d1 = data_blob_const("d1", 2);
8311 d2 = data_blob_const("d2", 2);
8312 d3 = data_blob_const("d3", 2);
8314 k1 = data_blob_const("d1", 2);
8315 k2 = data_blob_const("d2", 2);
8317 memcache_add(cache, STAT_CACHE, k1, d1);
8318 memcache_add(cache, GETWD_CACHE, k2, d2);
8320 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8321 printf("could not find k1\n");
8324 if (!data_blob_equal(d1, v1)) {
8328 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8329 printf("could not find k2\n");
8332 if (!data_blob_equal(d2, v2)) {
8336 memcache_add(cache, STAT_CACHE, k1, d3);
8338 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8339 printf("could not find replaced k1\n");
8342 if (!data_blob_equal(d3, v3)) {
8346 memcache_add(cache, GETWD_CACHE, k1, d1);
8348 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8349 printf("Did find k2, should have been purged\n");
8355 cache = memcache_init(NULL, 0);
8357 mem_ctx = talloc_init("foo");
8359 str1 = talloc_strdup(mem_ctx, "string1");
8360 str2 = talloc_strdup(mem_ctx, "string2");
8362 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8363 data_blob_string_const("torture"), &str1);
8364 size1 = talloc_total_size(cache);
8366 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8367 data_blob_string_const("torture"), &str2);
8368 size2 = talloc_total_size(cache);
8370 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8372 if (size2 > size1) {
8373 printf("memcache leaks memory!\n");
8383 static void wbclient_done(struct tevent_req *req)
8386 struct winbindd_response *wb_resp;
8387 int *i = (int *)tevent_req_callback_data_void(req);
8389 wbc_err = wb_trans_recv(req, req, &wb_resp);
8392 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8395 static bool run_local_wbclient(int dummy)
8397 struct event_context *ev;
8398 struct wb_context **wb_ctx;
8399 struct winbindd_request wb_req;
8400 bool result = false;
8403 BlockSignals(True, SIGPIPE);
8405 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8410 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8411 if (wb_ctx == NULL) {
8415 ZERO_STRUCT(wb_req);
8416 wb_req.cmd = WINBINDD_PING;
8418 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8420 for (i=0; i<nprocs; i++) {
8421 wb_ctx[i] = wb_context_init(ev, NULL);
8422 if (wb_ctx[i] == NULL) {
8425 for (j=0; j<torture_numops; j++) {
8426 struct tevent_req *req;
8427 req = wb_trans_send(ev, ev, wb_ctx[i],
8428 (j % 2) == 0, &wb_req);
8432 tevent_req_set_callback(req, wbclient_done, &i);
8438 while (i < nprocs * torture_numops) {
8439 tevent_loop_once(ev);
8448 static void getaddrinfo_finished(struct tevent_req *req)
8450 char *name = (char *)tevent_req_callback_data_void(req);
8451 struct addrinfo *ainfo;
8454 res = getaddrinfo_recv(req, &ainfo);
8456 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8459 d_printf("gai(%s) succeeded\n", name);
8460 freeaddrinfo(ainfo);
8463 static bool run_getaddrinfo_send(int dummy)
8465 TALLOC_CTX *frame = talloc_stackframe();
8466 struct fncall_context *ctx;
8467 struct tevent_context *ev;
8468 bool result = false;
8469 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8470 "www.slashdot.org", "heise.de" };
8471 struct tevent_req *reqs[4];
8474 ev = event_context_init(frame);
8479 ctx = fncall_context_init(frame, 4);
8481 for (i=0; i<ARRAY_SIZE(names); i++) {
8482 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8484 if (reqs[i] == NULL) {
8487 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8488 discard_const_p(void, names[i]));
8491 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8492 tevent_loop_once(ev);
8501 static bool dbtrans_inc(struct db_context *db)
8503 struct db_record *rec;
8508 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8510 printf(__location__ "fetch_lock failed\n");
8514 if (rec->value.dsize != sizeof(uint32_t)) {
8515 printf(__location__ "value.dsize = %d\n",
8516 (int)rec->value.dsize);
8520 val = (uint32_t *)rec->value.dptr;
8523 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8526 if (!NT_STATUS_IS_OK(status)) {
8527 printf(__location__ "store failed: %s\n",
8538 static bool run_local_dbtrans(int dummy)
8540 struct db_context *db;
8541 struct db_record *rec;
8546 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8547 O_RDWR|O_CREAT, 0600);
8549 printf("Could not open transtest.db\n");
8553 res = db->transaction_start(db);
8555 printf(__location__ "transaction_start failed\n");
8559 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8561 printf(__location__ "fetch_lock failed\n");
8565 if (rec->value.dptr == NULL) {
8567 status = rec->store(
8568 rec, make_tdb_data((uint8_t *)&initial,
8571 if (!NT_STATUS_IS_OK(status)) {
8572 printf(__location__ "store returned %s\n",
8580 res = db->transaction_commit(db);
8582 printf(__location__ "transaction_commit failed\n");
8590 res = db->transaction_start(db);
8592 printf(__location__ "transaction_start failed\n");
8596 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8597 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8601 for (i=0; i<10; i++) {
8602 if (!dbtrans_inc(db)) {
8607 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8608 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8612 if (val2 != val + 10) {
8613 printf(__location__ "val=%d, val2=%d\n",
8614 (int)val, (int)val2);
8618 printf("val2=%d\r", val2);
8620 res = db->transaction_commit(db);
8622 printf(__location__ "transaction_commit failed\n");
8632 * Just a dummy test to be run under a debugger. There's no real way
8633 * to inspect the tevent_select specific function from outside of
8637 static bool run_local_tevent_select(int dummy)
8639 struct tevent_context *ev;
8640 struct tevent_fd *fd1, *fd2;
8641 bool result = false;
8643 ev = tevent_context_init_byname(NULL, "select");
8645 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8649 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8651 d_fprintf(stderr, "tevent_add_fd failed\n");
8654 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8656 d_fprintf(stderr, "tevent_add_fd failed\n");
8661 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8663 d_fprintf(stderr, "tevent_add_fd failed\n");
8673 static double create_procs(bool (*fn)(int), bool *result)
8676 volatile pid_t *child_status;
8677 volatile bool *child_status_out;
8680 struct timeval start;
8684 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8685 if (!child_status) {
8686 printf("Failed to setup shared memory\n");
8690 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8691 if (!child_status_out) {
8692 printf("Failed to setup result status shared memory\n");
8696 for (i = 0; i < nprocs; i++) {
8697 child_status[i] = 0;
8698 child_status_out[i] = True;
8701 start = timeval_current();
8703 for (i=0;i<nprocs;i++) {
8706 pid_t mypid = getpid();
8707 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8709 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8712 if (torture_open_connection(¤t_cli, i)) break;
8714 printf("pid %d failed to start\n", (int)getpid());
8720 child_status[i] = getpid();
8722 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8724 child_status_out[i] = fn(i);
8731 for (i=0;i<nprocs;i++) {
8732 if (child_status[i]) synccount++;
8734 if (synccount == nprocs) break;
8736 } while (timeval_elapsed(&start) < 30);
8738 if (synccount != nprocs) {
8739 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8741 return timeval_elapsed(&start);
8744 /* start the client load */
8745 start = timeval_current();
8747 for (i=0;i<nprocs;i++) {
8748 child_status[i] = 0;
8751 printf("%d clients started\n", nprocs);
8753 for (i=0;i<nprocs;i++) {
8754 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8759 for (i=0;i<nprocs;i++) {
8760 if (!child_status_out[i]) {
8764 return timeval_elapsed(&start);
8767 #define FLAG_MULTIPROC 1
8774 {"FDPASS", run_fdpasstest, 0},
8775 {"LOCK1", run_locktest1, 0},
8776 {"LOCK2", run_locktest2, 0},
8777 {"LOCK3", run_locktest3, 0},
8778 {"LOCK4", run_locktest4, 0},
8779 {"LOCK5", run_locktest5, 0},
8780 {"LOCK6", run_locktest6, 0},
8781 {"LOCK7", run_locktest7, 0},
8782 {"LOCK8", run_locktest8, 0},
8783 {"LOCK9", run_locktest9, 0},
8784 {"UNLINK", run_unlinktest, 0},
8785 {"BROWSE", run_browsetest, 0},
8786 {"ATTR", run_attrtest, 0},
8787 {"TRANS2", run_trans2test, 0},
8788 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8789 {"TORTURE",run_torture, FLAG_MULTIPROC},
8790 {"RANDOMIPC", run_randomipc, 0},
8791 {"NEGNOWAIT", run_negprot_nowait, 0},
8792 {"NBENCH", run_nbench, 0},
8793 {"NBENCH2", run_nbench2, 0},
8794 {"OPLOCK1", run_oplock1, 0},
8795 {"OPLOCK2", run_oplock2, 0},
8796 {"OPLOCK4", run_oplock4, 0},
8797 {"DIR", run_dirtest, 0},
8798 {"DIR1", run_dirtest1, 0},
8799 {"DIR-CREATETIME", run_dir_createtime, 0},
8800 {"DENY1", torture_denytest1, 0},
8801 {"DENY2", torture_denytest2, 0},
8802 {"TCON", run_tcon_test, 0},
8803 {"TCONDEV", run_tcon_devtype_test, 0},
8804 {"RW1", run_readwritetest, 0},
8805 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8806 {"RW3", run_readwritelarge, 0},
8807 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8808 {"OPEN", run_opentest, 0},
8809 {"POSIX", run_simple_posix_open_test, 0},
8810 {"POSIX-APPEND", run_posix_append, 0},
8811 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8812 {"ASYNC-ECHO", run_async_echo, 0},
8813 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8814 { "SHORTNAME-TEST", run_shortname_test, 0},
8815 { "ADDRCHANGE", run_addrchange, 0},
8817 {"OPENATTR", run_openattrtest, 0},
8819 {"XCOPY", run_xcopy, 0},
8820 {"RENAME", run_rename, 0},
8821 {"DELETE", run_deletetest, 0},
8822 {"DELETE-LN", run_deletetest_ln, 0},
8823 {"PROPERTIES", run_properties, 0},
8824 {"MANGLE", torture_mangle, 0},
8825 {"MANGLE1", run_mangle1, 0},
8826 {"W2K", run_w2ktest, 0},
8827 {"TRANS2SCAN", torture_trans2_scan, 0},
8828 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8829 {"UTABLE", torture_utable, 0},
8830 {"CASETABLE", torture_casetable, 0},
8831 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8832 {"PIPE_NUMBER", run_pipe_number, 0},
8833 {"TCON2", run_tcon2_test, 0},
8834 {"IOCTL", torture_ioctl_test, 0},
8835 {"CHKPATH", torture_chkpath_test, 0},
8836 {"FDSESS", run_fdsesstest, 0},
8837 { "EATEST", run_eatest, 0},
8838 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8839 { "CHAIN1", run_chain1, 0},
8840 { "CHAIN2", run_chain2, 0},
8841 { "WINDOWS-WRITE", run_windows_write, 0},
8842 { "NTTRANS-CREATE", run_nttrans_create, 0},
8843 { "CLI_ECHO", run_cli_echo, 0},
8844 { "GETADDRINFO", run_getaddrinfo_send, 0},
8845 { "TLDAP", run_tldap },
8846 { "STREAMERROR", run_streamerror },
8847 { "NOTIFY-BENCH", run_notify_bench },
8848 { "BAD-NBT-SESSION", run_bad_nbt_session },
8849 { "SMB-ANY-CONNECT", run_smb_any_connect },
8850 { "NOTIFY-ONLINE", run_notify_online },
8851 { "SMB2-BASIC", run_smb2_basic },
8852 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8853 { "LOCAL-GENCACHE", run_local_gencache, 0},
8854 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8855 { "LOCAL-BASE64", run_local_base64, 0},
8856 { "LOCAL-RBTREE", run_local_rbtree, 0},
8857 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8858 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8859 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8860 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8861 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8862 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8863 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8864 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8869 /****************************************************************************
8870 run a specified test or "ALL"
8871 ****************************************************************************/
8872 static bool run_test(const char *name)
8879 if (strequal(name,"ALL")) {
8880 for (i=0;torture_ops[i].name;i++) {
8881 run_test(torture_ops[i].name);
8886 for (i=0;torture_ops[i].name;i++) {
8887 fstr_sprintf(randomfname, "\\XX%x",
8888 (unsigned)random());
8890 if (strequal(name, torture_ops[i].name)) {
8892 printf("Running %s\n", name);
8893 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8894 t = create_procs(torture_ops[i].fn, &result);
8897 printf("TEST %s FAILED!\n", name);
8900 struct timeval start;
8901 start = timeval_current();
8902 if (!torture_ops[i].fn(0)) {
8904 printf("TEST %s FAILED!\n", name);
8906 t = timeval_elapsed(&start);
8908 printf("%s took %g secs\n\n", name, t);
8913 printf("Did not find a test named %s\n", name);
8921 static void usage(void)
8925 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8926 printf("Please use samba4 torture.\n\n");
8928 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8930 printf("\t-d debuglevel\n");
8931 printf("\t-U user%%pass\n");
8932 printf("\t-k use kerberos\n");
8933 printf("\t-N numprocs\n");
8934 printf("\t-n my_netbios_name\n");
8935 printf("\t-W workgroup\n");
8936 printf("\t-o num_operations\n");
8937 printf("\t-O socket_options\n");
8938 printf("\t-m maximum protocol\n");
8939 printf("\t-L use oplocks\n");
8940 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8941 printf("\t-A showall\n");
8942 printf("\t-p port\n");
8943 printf("\t-s seed\n");
8944 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8945 printf("\t-f filename filename to test\n");
8948 printf("tests are:");
8949 for (i=0;torture_ops[i].name;i++) {
8950 printf(" %s", torture_ops[i].name);
8954 printf("default test is ALL\n");
8959 /****************************************************************************
8961 ****************************************************************************/
8962 int main(int argc,char *argv[])
8968 bool correct = True;
8969 TALLOC_CTX *frame = talloc_stackframe();
8970 int seed = time(NULL);
8972 #ifdef HAVE_SETBUFFER
8973 setbuffer(stdout, NULL, 0);
8976 setup_logging("smbtorture", DEBUG_STDOUT);
8980 if (is_default_dyn_CONFIGFILE()) {
8981 if(getenv("SMB_CONF_PATH")) {
8982 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8985 lp_load_global(get_dyn_CONFIGFILE());
8992 for(p = argv[1]; *p; p++)
8996 if (strncmp(argv[1], "//", 2)) {
9000 fstrcpy(host, &argv[1][2]);
9001 p = strchr_m(&host[2],'/');
9006 fstrcpy(share, p+1);
9008 fstrcpy(myname, get_myname(talloc_tos()));
9010 fprintf(stderr, "Failed to get my hostname.\n");
9014 if (*username == 0 && getenv("LOGNAME")) {
9015 fstrcpy(username,getenv("LOGNAME"));
9021 fstrcpy(workgroup, lp_workgroup());
9023 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9027 port_to_use = atoi(optarg);
9030 seed = atoi(optarg);
9033 fstrcpy(workgroup,optarg);
9036 max_protocol = interpret_protocol(optarg, max_protocol);
9039 nprocs = atoi(optarg);
9042 torture_numops = atoi(optarg);
9045 lp_set_cmdline("log level", optarg);
9054 local_path = optarg;
9057 torture_showall = True;
9060 fstrcpy(myname, optarg);
9063 client_txt = optarg;
9070 use_kerberos = True;
9072 d_printf("No kerberos support compiled in\n");
9078 fstrcpy(username,optarg);
9079 p = strchr_m(username,'%');
9082 fstrcpy(password, p+1);
9087 fstrcpy(multishare_conn_fname, optarg);
9088 use_multishare_conn = True;
9091 torture_blocksize = atoi(optarg);
9094 test_filename = SMB_STRDUP(optarg);
9097 printf("Unknown option %c (%d)\n", (char)opt, opt);
9102 d_printf("using seed %d\n", seed);
9106 if(use_kerberos && !gotuser) gotpass = True;
9109 p = getpass("Password:");
9111 fstrcpy(password, p);
9116 printf("host=%s share=%s user=%s myname=%s\n",
9117 host, share, username, myname);
9119 if (argc == optind) {
9120 correct = run_test("ALL");
9122 for (i=optind;i<argc;i++) {
9123 if (!run_test(argv[i])) {