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 fstring multishare_conn_fname;
61 static bool use_multishare_conn = False;
62 static bool do_encrypt;
63 static const char *local_path = NULL;
64 static int signing_state = Undefined;
67 bool torture_showall = False;
69 static double create_procs(bool (*fn)(int), bool *result);
72 /* return a pointer to a anonymous shared memory segment of size "size"
73 which will persist across fork() but will disappear when all processes
76 The memory is not zeroed
78 This function uses system5 shared memory. It takes advantage of a property
79 that the memory is not destroyed if it is attached when the id is removed
81 void *shm_setup(int size)
87 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
89 printf("can't get shared memory\n");
92 shm_unlink("private");
93 if (ftruncate(shmid, size) == -1) {
94 printf("can't set shared memory size\n");
97 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
98 if (ret == MAP_FAILED) {
99 printf("can't map shared memory\n");
103 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
105 printf("can't get shared memory\n");
108 ret = (void *)shmat(shmid, 0, 0);
109 if (!ret || ret == (void *)-1) {
110 printf("can't attach to shared memory\n");
113 /* the following releases the ipc, but note that this process
114 and all its children will still have access to the memory, its
115 just that the shmid is no longer valid for other shm calls. This
116 means we don't leave behind lots of shm segments after we exit
118 See Stevens "advanced programming in unix env" for details
120 shmctl(shmid, IPC_RMID, 0);
126 /********************************************************************
127 Ensure a connection is encrypted.
128 ********************************************************************/
130 static bool force_cli_encryption(struct cli_state *c,
131 const char *sharename)
134 uint32 caplow, caphigh;
137 if (!SERVER_HAS_UNIX_CIFS(c)) {
138 d_printf("Encryption required and "
139 "server that doesn't support "
140 "UNIX extensions - failing connect\n");
144 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
146 if (!NT_STATUS_IS_OK(status)) {
147 d_printf("Encryption required and "
148 "can't get UNIX CIFS extensions "
149 "version from server: %s\n", nt_errstr(status));
153 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
154 d_printf("Encryption required and "
155 "share %s doesn't support "
156 "encryption.\n", sharename);
160 if (c->use_kerberos) {
161 status = cli_gss_smb_encryption_start(c);
163 status = cli_raw_ntlm_smb_encryption_start(c,
169 if (!NT_STATUS_IS_OK(status)) {
170 d_printf("Encryption required and "
171 "setup failed with error %s.\n",
180 static struct cli_state *open_nbt_connection(void)
187 flags |= CLI_FULL_CONNECTION_OPLOCKS;
190 if (use_level_II_oplocks) {
191 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
195 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
198 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
199 signing_state, flags, &c);
200 if (!NT_STATUS_IS_OK(status)) {
201 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
205 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
210 /****************************************************************************
211 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
212 ****************************************************************************/
214 static bool cli_bad_session_request(int fd,
215 struct nmb_name *calling, struct nmb_name *called)
224 uint8_t message_type;
227 frame = talloc_stackframe();
229 iov[0].iov_base = len_buf;
230 iov[0].iov_len = sizeof(len_buf);
232 /* put in the destination name */
234 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
236 if (iov[1].iov_base == NULL) {
239 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
240 talloc_get_size(iov[1].iov_base));
244 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
246 if (iov[2].iov_base == NULL) {
249 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
250 talloc_get_size(iov[2].iov_base));
252 /* Deliberately corrupt the name len (first byte) */
253 *((uint8_t *)iov[2].iov_base) = 100;
255 /* send a session request (RFC 1002) */
256 /* setup the packet length
257 * Remove four bytes from the length count, since the length
258 * field in the NBT Session Service header counts the number
259 * of bytes which follow. The cli_send_smb() function knows
260 * about this and accounts for those four bytes.
264 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
265 SCVAL(len_buf,0,0x81);
267 len = write_data_iov(fd, iov, 3);
271 len = read_smb(fd, talloc_tos(), &inbuf, &err);
277 message_type = CVAL(inbuf, 0);
278 if (message_type != 0x83) {
279 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
284 if (smb_len(inbuf) != 1) {
285 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
286 (int)smb_len(inbuf));
290 error = CVAL(inbuf, 4);
292 d_fprintf(stderr, "Expected error 0x82, got %d\n",
303 /* Insert a NULL at the first separator of the given path and return a pointer
304 * to the remainder of the string.
307 terminate_path_at_separator(char * path)
315 if ((p = strchr_m(path, '/'))) {
320 if ((p = strchr_m(path, '\\'))) {
330 parse a //server/share type UNC name
332 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
333 char **hostname, char **sharename)
337 *hostname = *sharename = NULL;
339 if (strncmp(unc_name, "\\\\", 2) &&
340 strncmp(unc_name, "//", 2)) {
344 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
345 p = terminate_path_at_separator(*hostname);
348 *sharename = talloc_strdup(mem_ctx, p);
349 terminate_path_at_separator(*sharename);
352 if (*hostname && *sharename) {
356 TALLOC_FREE(*hostname);
357 TALLOC_FREE(*sharename);
361 static bool torture_open_connection_share(struct cli_state **c,
362 const char *hostname,
363 const char *sharename)
369 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
371 flags |= CLI_FULL_CONNECTION_OPLOCKS;
372 if (use_level_II_oplocks)
373 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
375 status = cli_full_connection(c, myname,
376 hostname, NULL, port_to_use,
379 password, flags, signing_state);
380 if (!NT_STATUS_IS_OK(status)) {
381 printf("failed to open share connection: //%s/%s port:%d - %s\n",
382 hostname, sharename, port_to_use, nt_errstr(status));
386 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
389 return force_cli_encryption(*c,
395 bool torture_open_connection(struct cli_state **c, int conn_index)
397 char **unc_list = NULL;
398 int num_unc_names = 0;
401 if (use_multishare_conn==True) {
403 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
404 if (!unc_list || num_unc_names <= 0) {
405 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
409 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
411 printf("Failed to parse UNC name %s\n",
412 unc_list[conn_index % num_unc_names]);
413 TALLOC_FREE(unc_list);
417 result = torture_open_connection_share(c, h, s);
419 /* h, s were copied earlier */
420 TALLOC_FREE(unc_list);
424 return torture_open_connection_share(c, host, share);
427 bool torture_init_connection(struct cli_state **pcli)
429 struct cli_state *cli;
431 cli = open_nbt_connection();
440 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
442 uint16_t old_vuid = cli_state_get_uid(cli);
443 fstring old_user_name;
444 size_t passlen = strlen(password);
448 fstrcpy(old_user_name, cli->user_name);
449 cli_state_set_uid(cli, 0);
450 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
454 *new_vuid = cli_state_get_uid(cli);
455 cli_state_set_uid(cli, old_vuid);
456 status = cli_set_username(cli, old_user_name);
457 if (!NT_STATUS_IS_OK(status)) {
464 bool torture_close_connection(struct cli_state *c)
469 status = cli_tdis(c);
470 if (!NT_STATUS_IS_OK(status)) {
471 printf("tdis failed (%s)\n", nt_errstr(status));
481 /* check if the server produced the expected dos or nt error code */
482 static bool check_both_error(int line, NTSTATUS status,
483 uint8 eclass, uint32 ecode, NTSTATUS nterr)
485 if (NT_STATUS_IS_DOS(status)) {
489 /* Check DOS error */
490 cclass = NT_STATUS_DOS_CLASS(status);
491 num = NT_STATUS_DOS_CODE(status);
493 if (eclass != cclass || ecode != num) {
494 printf("unexpected error code class=%d code=%d\n",
495 (int)cclass, (int)num);
496 printf(" expected %d/%d %s (line=%d)\n",
497 (int)eclass, (int)ecode, nt_errstr(nterr), line);
502 if (!NT_STATUS_EQUAL(nterr, status)) {
503 printf("unexpected error code %s\n",
505 printf(" expected %s (line=%d)\n",
506 nt_errstr(nterr), line);
515 /* check if the server produced the expected error code */
516 static bool check_error(int line, NTSTATUS status,
517 uint8 eclass, uint32 ecode, NTSTATUS nterr)
519 if (NT_STATUS_IS_DOS(status)) {
523 /* Check DOS error */
525 cclass = NT_STATUS_DOS_CLASS(status);
526 num = NT_STATUS_DOS_CODE(status);
528 if (eclass != cclass || ecode != num) {
529 printf("unexpected error code class=%d code=%d\n",
530 (int)cclass, (int)num);
531 printf(" expected %d/%d %s (line=%d)\n",
532 (int)eclass, (int)ecode, nt_errstr(nterr),
540 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
541 printf("unexpected error code %s\n",
543 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
553 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
557 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
559 while (!NT_STATUS_IS_OK(status)) {
560 if (!check_both_error(__LINE__, status, ERRDOS,
561 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
565 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
572 static bool rw_torture(struct cli_state *c)
574 const char *lockfname = "\\torture.lck";
578 pid_t pid2, pid = getpid();
585 memset(buf, '\0', sizeof(buf));
587 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
589 if (!NT_STATUS_IS_OK(status)) {
590 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
592 if (!NT_STATUS_IS_OK(status)) {
593 printf("open of %s failed (%s)\n",
594 lockfname, nt_errstr(status));
598 for (i=0;i<torture_numops;i++) {
599 unsigned n = (unsigned)sys_random()%10;
602 printf("%d\r", i); fflush(stdout);
604 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
606 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
610 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
612 if (!NT_STATUS_IS_OK(status)) {
613 printf("open failed (%s)\n", nt_errstr(status));
618 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
620 if (!NT_STATUS_IS_OK(status)) {
621 printf("write failed (%s)\n", nt_errstr(status));
626 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
627 sizeof(pid)+(j*sizeof(buf)),
629 if (!NT_STATUS_IS_OK(status)) {
630 printf("write failed (%s)\n",
638 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
640 if (!NT_STATUS_IS_OK(status)) {
641 printf("read failed (%s)\n", nt_errstr(status));
643 } else if (nread != sizeof(pid)) {
644 printf("read/write compare failed: "
645 "recv %ld req %ld\n", (unsigned long)nread,
646 (unsigned long)sizeof(pid));
651 printf("data corruption!\n");
655 status = cli_close(c, fnum);
656 if (!NT_STATUS_IS_OK(status)) {
657 printf("close failed (%s)\n", nt_errstr(status));
661 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
662 if (!NT_STATUS_IS_OK(status)) {
663 printf("unlink failed (%s)\n", nt_errstr(status));
667 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
668 if (!NT_STATUS_IS_OK(status)) {
669 printf("unlock failed (%s)\n", nt_errstr(status));
675 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
682 static bool run_torture(int dummy)
684 struct cli_state *cli;
689 cli_sockopt(cli, sockops);
691 ret = rw_torture(cli);
693 if (!torture_close_connection(cli)) {
700 static bool rw_torture3(struct cli_state *c, char *lockfname)
702 uint16_t fnum = (uint16_t)-1;
707 unsigned countprev = 0;
710 NTSTATUS status = NT_STATUS_OK;
713 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
715 SIVAL(buf, i, sys_random());
722 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
723 if (!NT_STATUS_IS_OK(status)) {
724 printf("unlink failed (%s) (normal, this file should "
725 "not exist)\n", nt_errstr(status));
728 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
730 if (!NT_STATUS_IS_OK(status)) {
731 printf("first open read/write of %s failed (%s)\n",
732 lockfname, nt_errstr(status));
738 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
740 status = cli_open(c, lockfname, O_RDONLY,
742 if (!NT_STATUS_IS_OK(status)) {
747 if (!NT_STATUS_IS_OK(status)) {
748 printf("second open read-only of %s failed (%s)\n",
749 lockfname, nt_errstr(status));
755 for (count = 0; count < sizeof(buf); count += sent)
757 if (count >= countprev) {
758 printf("%d %8d\r", i, count);
761 countprev += (sizeof(buf) / 20);
766 sent = ((unsigned)sys_random()%(20))+ 1;
767 if (sent > sizeof(buf) - count)
769 sent = sizeof(buf) - count;
772 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("write failed (%s)\n",
782 status = cli_read(c, fnum, buf_rd+count, count,
783 sizeof(buf)-count, &sent);
784 if(!NT_STATUS_IS_OK(status)) {
785 printf("read failed offset:%d size:%ld (%s)\n",
786 count, (unsigned long)sizeof(buf)-count,
790 } else if (sent > 0) {
791 if (memcmp(buf_rd+count, buf+count, sent) != 0)
793 printf("read/write compare failed\n");
794 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
803 status = cli_close(c, fnum);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("close failed (%s)\n", nt_errstr(status));
812 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
814 const char *lockfname = "\\torture2.lck";
824 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
829 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
831 if (!NT_STATUS_IS_OK(status)) {
832 printf("first open read/write of %s failed (%s)\n",
833 lockfname, nt_errstr(status));
837 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
838 if (!NT_STATUS_IS_OK(status)) {
839 printf("second open read-only of %s failed (%s)\n",
840 lockfname, nt_errstr(status));
841 cli_close(c1, fnum1);
845 for (i = 0; i < torture_numops; i++)
847 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
849 printf("%d\r", i); fflush(stdout);
852 generate_random_buffer((unsigned char *)buf, buf_size);
854 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("write failed (%s)\n", nt_errstr(status));
862 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
863 if(!NT_STATUS_IS_OK(status)) {
864 printf("read failed (%s)\n", nt_errstr(status));
867 } else if (bytes_read != buf_size) {
868 printf("read failed\n");
869 printf("read %ld, expected %ld\n",
870 (unsigned long)bytes_read,
871 (unsigned long)buf_size);
876 if (memcmp(buf_rd, buf, buf_size) != 0)
878 printf("read/write compare failed\n");
884 status = cli_close(c2, fnum2);
885 if (!NT_STATUS_IS_OK(status)) {
886 printf("close failed (%s)\n", nt_errstr(status));
890 status = cli_close(c1, fnum1);
891 if (!NT_STATUS_IS_OK(status)) {
892 printf("close failed (%s)\n", nt_errstr(status));
896 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
897 if (!NT_STATUS_IS_OK(status)) {
898 printf("unlink failed (%s)\n", nt_errstr(status));
905 static bool run_readwritetest(int dummy)
907 struct cli_state *cli1, *cli2;
908 bool test1, test2 = False;
910 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
913 cli_sockopt(cli1, sockops);
914 cli_sockopt(cli2, sockops);
916 printf("starting readwritetest\n");
918 test1 = rw_torture2(cli1, cli2);
919 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
922 test2 = rw_torture2(cli1, cli1);
923 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
926 if (!torture_close_connection(cli1)) {
930 if (!torture_close_connection(cli2)) {
934 return (test1 && test2);
937 static bool run_readwritemulti(int dummy)
939 struct cli_state *cli;
944 cli_sockopt(cli, sockops);
946 printf("run_readwritemulti: fname %s\n", randomfname);
947 test = rw_torture3(cli, randomfname);
949 if (!torture_close_connection(cli)) {
956 static bool run_readwritelarge_internal(int max_xmit_k)
958 static struct cli_state *cli1;
960 const char *lockfname = "\\large.dat";
966 if (!torture_open_connection(&cli1, 0)) {
969 cli_sockopt(cli1, sockops);
970 memset(buf,'\0',sizeof(buf));
972 cli1->max_xmit = max_xmit_k*1024;
974 if (signing_state == Required) {
975 /* Horrible cheat to force
976 multiple signed outstanding
977 packets against a Samba server.
979 cli1->is_samba = false;
982 printf("starting readwritelarge_internal\n");
984 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
986 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
988 if (!NT_STATUS_IS_OK(status)) {
989 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
993 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
995 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
997 if (!NT_STATUS_IS_OK(status)) {
998 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1002 if (fsize == sizeof(buf))
1003 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1004 (unsigned long)fsize);
1006 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1007 (unsigned long)fsize);
1011 status = cli_close(cli1, fnum1);
1012 if (!NT_STATUS_IS_OK(status)) {
1013 printf("close failed (%s)\n", nt_errstr(status));
1017 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1018 if (!NT_STATUS_IS_OK(status)) {
1019 printf("unlink failed (%s)\n", nt_errstr(status));
1023 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1025 if (!NT_STATUS_IS_OK(status)) {
1026 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1030 cli1->max_xmit = 4*1024;
1032 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1034 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1036 if (!NT_STATUS_IS_OK(status)) {
1037 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1041 if (fsize == sizeof(buf))
1042 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1043 (unsigned long)fsize);
1045 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1046 (unsigned long)fsize);
1051 /* ToDo - set allocation. JRA */
1052 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1053 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1056 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1058 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1062 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1065 status = cli_close(cli1, fnum1);
1066 if (!NT_STATUS_IS_OK(status)) {
1067 printf("close failed (%s)\n", nt_errstr(status));
1071 if (!torture_close_connection(cli1)) {
1077 static bool run_readwritelarge(int dummy)
1079 return run_readwritelarge_internal(128);
1082 static bool run_readwritelarge_signtest(int dummy)
1085 signing_state = Required;
1086 ret = run_readwritelarge_internal(2);
1087 signing_state = Undefined;
1094 #define ival(s) strtol(s, NULL, 0)
1096 /* run a test that simulates an approximate netbench client load */
1097 static bool run_netbench(int client)
1099 struct cli_state *cli;
1104 const char *params[20];
1105 bool correct = True;
1111 cli_sockopt(cli, sockops);
1115 slprintf(cname,sizeof(cname)-1, "client%d", client);
1117 f = fopen(client_txt, "r");
1124 while (fgets(line, sizeof(line)-1, f)) {
1128 line[strlen(line)-1] = 0;
1130 /* printf("[%d] %s\n", line_count, line); */
1132 all_string_sub(line,"client1", cname, sizeof(line));
1134 /* parse the command parameters */
1135 params[0] = strtok_r(line, " ", &saveptr);
1137 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1141 if (i < 2) continue;
1143 if (!strncmp(params[0],"SMB", 3)) {
1144 printf("ERROR: You are using a dbench 1 load file\n");
1148 if (!strcmp(params[0],"NTCreateX")) {
1149 nb_createx(params[1], ival(params[2]), ival(params[3]),
1151 } else if (!strcmp(params[0],"Close")) {
1152 nb_close(ival(params[1]));
1153 } else if (!strcmp(params[0],"Rename")) {
1154 nb_rename(params[1], params[2]);
1155 } else if (!strcmp(params[0],"Unlink")) {
1156 nb_unlink(params[1]);
1157 } else if (!strcmp(params[0],"Deltree")) {
1158 nb_deltree(params[1]);
1159 } else if (!strcmp(params[0],"Rmdir")) {
1160 nb_rmdir(params[1]);
1161 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1162 nb_qpathinfo(params[1]);
1163 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1164 nb_qfileinfo(ival(params[1]));
1165 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1166 nb_qfsinfo(ival(params[1]));
1167 } else if (!strcmp(params[0],"FIND_FIRST")) {
1168 nb_findfirst(params[1]);
1169 } else if (!strcmp(params[0],"WriteX")) {
1170 nb_writex(ival(params[1]),
1171 ival(params[2]), ival(params[3]), ival(params[4]));
1172 } else if (!strcmp(params[0],"ReadX")) {
1173 nb_readx(ival(params[1]),
1174 ival(params[2]), ival(params[3]), ival(params[4]));
1175 } else if (!strcmp(params[0],"Flush")) {
1176 nb_flush(ival(params[1]));
1178 printf("Unknown operation %s\n", params[0]);
1186 if (!torture_close_connection(cli)) {
1194 /* run a test that simulates an approximate netbench client load */
1195 static bool run_nbench(int dummy)
1198 bool correct = True;
1204 signal(SIGALRM, nb_alarm);
1206 t = create_procs(run_netbench, &correct);
1209 printf("\nThroughput %g MB/sec\n",
1210 1.0e-6 * nbio_total() / t);
1216 This test checks for two things:
1218 1) correct support for retaining locks over a close (ie. the server
1219 must not use posix semantics)
1220 2) support for lock timeouts
1222 static bool run_locktest1(int dummy)
1224 struct cli_state *cli1, *cli2;
1225 const char *fname = "\\lockt1.lck";
1226 uint16_t fnum1, fnum2, fnum3;
1228 unsigned lock_timeout;
1231 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1234 cli_sockopt(cli1, sockops);
1235 cli_sockopt(cli2, sockops);
1237 printf("starting locktest1\n");
1239 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1241 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1243 if (!NT_STATUS_IS_OK(status)) {
1244 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1248 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1254 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1260 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 printf("lock1 failed (%s)\n", nt_errstr(status));
1266 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1267 if (NT_STATUS_IS_OK(status)) {
1268 printf("lock2 succeeded! This is a locking bug\n");
1271 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1272 NT_STATUS_LOCK_NOT_GRANTED)) {
1277 lock_timeout = (1 + (random() % 20));
1278 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1280 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1281 if (NT_STATUS_IS_OK(status)) {
1282 printf("lock3 succeeded! This is a locking bug\n");
1285 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1286 NT_STATUS_FILE_LOCK_CONFLICT)) {
1292 if (ABS(t2 - t1) < lock_timeout-1) {
1293 printf("error: This server appears not to support timed lock requests\n");
1296 printf("server slept for %u seconds for a %u second timeout\n",
1297 (unsigned int)(t2-t1), lock_timeout);
1299 status = cli_close(cli1, fnum2);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("close1 failed (%s)\n", nt_errstr(status));
1305 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1306 if (NT_STATUS_IS_OK(status)) {
1307 printf("lock4 succeeded! This is a locking bug\n");
1310 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1311 NT_STATUS_FILE_LOCK_CONFLICT)) {
1316 status = cli_close(cli1, fnum1);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("close2 failed (%s)\n", nt_errstr(status));
1322 status = cli_close(cli2, fnum3);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 printf("close3 failed (%s)\n", nt_errstr(status));
1328 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1329 if (!NT_STATUS_IS_OK(status)) {
1330 printf("unlink failed (%s)\n", nt_errstr(status));
1335 if (!torture_close_connection(cli1)) {
1339 if (!torture_close_connection(cli2)) {
1343 printf("Passed locktest1\n");
1348 this checks to see if a secondary tconx can use open files from an
1351 static bool run_tcon_test(int dummy)
1353 static struct cli_state *cli;
1354 const char *fname = "\\tcontest.tmp";
1356 uint16 cnum1, cnum2, cnum3;
1357 uint16 vuid1, vuid2;
1362 memset(buf, '\0', sizeof(buf));
1364 if (!torture_open_connection(&cli, 0)) {
1367 cli_sockopt(cli, sockops);
1369 printf("starting tcontest\n");
1371 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1373 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1374 if (!NT_STATUS_IS_OK(status)) {
1375 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1379 cnum1 = cli_state_get_tid(cli);
1380 vuid1 = cli_state_get_uid(cli);
1382 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1383 if (!NT_STATUS_IS_OK(status)) {
1384 printf("initial write failed (%s)", nt_errstr(status));
1388 status = cli_tcon_andx(cli, share, "?????",
1389 password, strlen(password)+1);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 printf("%s refused 2nd tree connect (%s)\n", host,
1397 cnum2 = cli_state_get_tid(cli);
1398 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1399 vuid2 = cli_state_get_uid(cli) + 1;
1401 /* try a write with the wrong tid */
1402 cli_state_set_tid(cli, cnum2);
1404 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1405 if (NT_STATUS_IS_OK(status)) {
1406 printf("* server allows write with wrong TID\n");
1409 printf("server fails write with wrong TID : %s\n",
1414 /* try a write with an invalid tid */
1415 cli_state_set_tid(cli, cnum3);
1417 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1418 if (NT_STATUS_IS_OK(status)) {
1419 printf("* server allows write with invalid TID\n");
1422 printf("server fails write with invalid TID : %s\n",
1426 /* try a write with an invalid vuid */
1427 cli_state_set_uid(cli, vuid2);
1428 cli_state_set_tid(cli, cnum1);
1430 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1431 if (NT_STATUS_IS_OK(status)) {
1432 printf("* server allows write with invalid VUID\n");
1435 printf("server fails write with invalid VUID : %s\n",
1439 cli_state_set_tid(cli, cnum1);
1440 cli_state_set_uid(cli, vuid1);
1442 status = cli_close(cli, fnum1);
1443 if (!NT_STATUS_IS_OK(status)) {
1444 printf("close failed (%s)\n", nt_errstr(status));
1448 cli_state_set_tid(cli, cnum2);
1450 status = cli_tdis(cli);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1456 cli_state_set_tid(cli, cnum1);
1458 if (!torture_close_connection(cli)) {
1467 checks for old style tcon support
1469 static bool run_tcon2_test(int dummy)
1471 static struct cli_state *cli;
1472 uint16 cnum, max_xmit;
1476 if (!torture_open_connection(&cli, 0)) {
1479 cli_sockopt(cli, sockops);
1481 printf("starting tcon2 test\n");
1483 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1487 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 printf("tcon2 failed : %s\n", nt_errstr(status));
1494 printf("tcon OK : max_xmit=%d cnum=%d\n",
1495 (int)max_xmit, (int)cnum);
1498 if (!torture_close_connection(cli)) {
1502 printf("Passed tcon2 test\n");
1506 static bool tcon_devtest(struct cli_state *cli,
1507 const char *myshare, const char *devtype,
1508 const char *return_devtype,
1509 NTSTATUS expected_error)
1514 status = cli_tcon_andx(cli, myshare, devtype,
1515 password, strlen(password)+1);
1517 if (NT_STATUS_IS_OK(expected_error)) {
1518 if (NT_STATUS_IS_OK(status)) {
1519 if (strcmp(cli->dev, return_devtype) == 0) {
1522 printf("tconX to share %s with type %s "
1523 "succeeded but returned the wrong "
1524 "device type (got [%s] but should have got [%s])\n",
1525 myshare, devtype, cli->dev, return_devtype);
1529 printf("tconX to share %s with type %s "
1530 "should have succeeded but failed\n",
1536 if (NT_STATUS_IS_OK(status)) {
1537 printf("tconx to share %s with type %s "
1538 "should have failed but succeeded\n",
1542 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1546 printf("Returned unexpected error\n");
1555 checks for correct tconX support
1557 static bool run_tcon_devtype_test(int dummy)
1559 static struct cli_state *cli1 = NULL;
1564 status = cli_full_connection(&cli1, myname,
1565 host, NULL, port_to_use,
1567 username, workgroup,
1568 password, flags, signing_state);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 printf("could not open connection\n");
1575 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1578 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1581 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1584 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1587 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1590 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1593 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1596 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1599 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1602 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1608 printf("Passed tcondevtest\n");
1615 This test checks that
1617 1) the server supports multiple locking contexts on the one SMB
1618 connection, distinguished by PID.
1620 2) the server correctly fails overlapping locks made by the same PID (this
1621 goes against POSIX behaviour, which is why it is tricky to implement)
1623 3) the server denies unlock requests by an incorrect client PID
1625 static bool run_locktest2(int dummy)
1627 static struct cli_state *cli;
1628 const char *fname = "\\lockt2.lck";
1629 uint16_t fnum1, fnum2, fnum3;
1630 bool correct = True;
1633 if (!torture_open_connection(&cli, 0)) {
1637 cli_sockopt(cli, sockops);
1639 printf("starting locktest2\n");
1641 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1645 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1651 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1659 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1667 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1668 if (!NT_STATUS_IS_OK(status)) {
1669 printf("lock1 failed (%s)\n", nt_errstr(status));
1673 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1674 if (NT_STATUS_IS_OK(status)) {
1675 printf("WRITE lock1 succeeded! This is a locking bug\n");
1678 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1679 NT_STATUS_LOCK_NOT_GRANTED)) {
1684 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1685 if (NT_STATUS_IS_OK(status)) {
1686 printf("WRITE lock2 succeeded! This is a locking bug\n");
1689 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1690 NT_STATUS_LOCK_NOT_GRANTED)) {
1695 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1696 if (NT_STATUS_IS_OK(status)) {
1697 printf("READ lock2 succeeded! This is a locking bug\n");
1700 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1701 NT_STATUS_FILE_LOCK_CONFLICT)) {
1706 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1711 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1712 printf("unlock at 100 succeeded! This is a locking bug\n");
1716 status = cli_unlock(cli, fnum1, 0, 4);
1717 if (NT_STATUS_IS_OK(status)) {
1718 printf("unlock1 succeeded! This is a locking bug\n");
1721 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1722 NT_STATUS_RANGE_NOT_LOCKED)) {
1727 status = cli_unlock(cli, fnum1, 0, 8);
1728 if (NT_STATUS_IS_OK(status)) {
1729 printf("unlock2 succeeded! This is a locking bug\n");
1732 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1733 NT_STATUS_RANGE_NOT_LOCKED)) {
1738 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1739 if (NT_STATUS_IS_OK(status)) {
1740 printf("lock3 succeeded! This is a locking bug\n");
1743 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1744 NT_STATUS_LOCK_NOT_GRANTED)) {
1751 status = cli_close(cli, fnum1);
1752 if (!NT_STATUS_IS_OK(status)) {
1753 printf("close1 failed (%s)\n", nt_errstr(status));
1757 status = cli_close(cli, fnum2);
1758 if (!NT_STATUS_IS_OK(status)) {
1759 printf("close2 failed (%s)\n", nt_errstr(status));
1763 status = cli_close(cli, fnum3);
1764 if (!NT_STATUS_IS_OK(status)) {
1765 printf("close3 failed (%s)\n", nt_errstr(status));
1769 if (!torture_close_connection(cli)) {
1773 printf("locktest2 finished\n");
1780 This test checks that
1782 1) the server supports the full offset range in lock requests
1784 static bool run_locktest3(int dummy)
1786 static struct cli_state *cli1, *cli2;
1787 const char *fname = "\\lockt3.lck";
1788 uint16_t fnum1, fnum2;
1791 bool correct = True;
1794 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1796 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1799 cli_sockopt(cli1, sockops);
1800 cli_sockopt(cli2, sockops);
1802 printf("starting locktest3\n");
1804 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1806 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1808 if (!NT_STATUS_IS_OK(status)) {
1809 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1813 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1814 if (!NT_STATUS_IS_OK(status)) {
1815 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1819 for (offset=i=0;i<torture_numops;i++) {
1822 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1823 if (!NT_STATUS_IS_OK(status)) {
1824 printf("lock1 %d failed (%s)\n",
1830 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1831 if (!NT_STATUS_IS_OK(status)) {
1832 printf("lock2 %d failed (%s)\n",
1839 for (offset=i=0;i<torture_numops;i++) {
1842 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1843 if (NT_STATUS_IS_OK(status)) {
1844 printf("error: lock1 %d succeeded!\n", i);
1848 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1849 if (NT_STATUS_IS_OK(status)) {
1850 printf("error: lock2 %d succeeded!\n", i);
1854 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1855 if (NT_STATUS_IS_OK(status)) {
1856 printf("error: lock3 %d succeeded!\n", i);
1860 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1861 if (NT_STATUS_IS_OK(status)) {
1862 printf("error: lock4 %d succeeded!\n", i);
1867 for (offset=i=0;i<torture_numops;i++) {
1870 status = cli_unlock(cli1, fnum1, offset-1, 1);
1871 if (!NT_STATUS_IS_OK(status)) {
1872 printf("unlock1 %d failed (%s)\n",
1878 status = cli_unlock(cli2, fnum2, offset-2, 1);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 printf("unlock2 %d failed (%s)\n",
1887 status = cli_close(cli1, fnum1);
1888 if (!NT_STATUS_IS_OK(status)) {
1889 printf("close1 failed (%s)\n", nt_errstr(status));
1893 status = cli_close(cli2, fnum2);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("close2 failed (%s)\n", nt_errstr(status));
1899 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1900 if (!NT_STATUS_IS_OK(status)) {
1901 printf("unlink failed (%s)\n", nt_errstr(status));
1905 if (!torture_close_connection(cli1)) {
1909 if (!torture_close_connection(cli2)) {
1913 printf("finished locktest3\n");
1918 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1919 char *buf, off_t offset, size_t size,
1920 size_t *nread, size_t expect)
1925 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1927 if(!NT_STATUS_IS_OK(status)) {
1929 } else if (l_nread != expect) {
1940 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1941 printf("** "); correct = False; \
1945 looks at overlapping locks
1947 static bool run_locktest4(int dummy)
1949 static struct cli_state *cli1, *cli2;
1950 const char *fname = "\\lockt4.lck";
1951 uint16_t fnum1, fnum2, f;
1954 bool correct = True;
1957 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1961 cli_sockopt(cli1, sockops);
1962 cli_sockopt(cli2, sockops);
1964 printf("starting locktest4\n");
1966 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1968 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1969 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1971 memset(buf, 0, sizeof(buf));
1973 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1975 if (!NT_STATUS_IS_OK(status)) {
1976 printf("Failed to create file: %s\n", nt_errstr(status));
1981 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1982 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1983 EXPECTED(ret, False);
1984 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1986 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1987 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1988 EXPECTED(ret, True);
1989 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1991 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1992 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1993 EXPECTED(ret, False);
1994 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1996 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1998 EXPECTED(ret, True);
1999 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
2001 ret = (cli_setpid(cli1, 1),
2002 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
2003 (cli_setpid(cli1, 2),
2004 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
2005 EXPECTED(ret, False);
2006 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
2008 ret = (cli_setpid(cli1, 1),
2009 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
2010 (cli_setpid(cli1, 2),
2011 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
2012 EXPECTED(ret, True);
2013 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
2015 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
2016 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
2017 EXPECTED(ret, True);
2018 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
2020 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
2021 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
2022 EXPECTED(ret, False);
2023 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
2025 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
2026 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
2027 EXPECTED(ret, False);
2028 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2030 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2031 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2032 EXPECTED(ret, True);
2033 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2035 ret = (cli_setpid(cli1, 1),
2036 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2037 (cli_setpid(cli1, 2),
2038 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2039 EXPECTED(ret, False);
2040 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2042 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2043 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2044 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2045 EXPECTED(ret, False);
2046 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2049 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2050 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2051 EXPECTED(ret, False);
2052 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2054 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2055 ret = NT_STATUS_IS_OK(status);
2057 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2059 ret = NT_STATUS_IS_OK(status);
2061 EXPECTED(ret, False);
2062 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2065 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2066 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2067 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2068 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2069 EXPECTED(ret, True);
2070 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2073 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2074 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2075 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2076 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2077 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2079 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2080 EXPECTED(ret, True);
2081 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2083 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2084 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2085 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2087 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2088 EXPECTED(ret, True);
2089 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2091 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2092 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2093 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2095 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2096 EXPECTED(ret, True);
2097 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2099 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2100 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2101 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2102 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2104 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2105 EXPECTED(ret, True);
2106 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2108 cli_close(cli1, fnum1);
2109 cli_close(cli2, fnum2);
2110 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2111 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2112 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2113 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2114 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2115 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2116 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2118 cli_close(cli1, fnum1);
2119 EXPECTED(ret, True);
2120 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2123 cli_close(cli1, fnum1);
2124 cli_close(cli2, fnum2);
2125 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2126 torture_close_connection(cli1);
2127 torture_close_connection(cli2);
2129 printf("finished locktest4\n");
2134 looks at lock upgrade/downgrade.
2136 static bool run_locktest5(int dummy)
2138 static struct cli_state *cli1, *cli2;
2139 const char *fname = "\\lockt5.lck";
2140 uint16_t fnum1, fnum2, fnum3;
2143 bool correct = True;
2146 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2150 cli_sockopt(cli1, sockops);
2151 cli_sockopt(cli2, sockops);
2153 printf("starting locktest5\n");
2155 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2157 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2158 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2159 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2161 memset(buf, 0, sizeof(buf));
2163 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2165 if (!NT_STATUS_IS_OK(status)) {
2166 printf("Failed to create file: %s\n", nt_errstr(status));
2171 /* Check for NT bug... */
2172 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2173 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2174 cli_close(cli1, fnum1);
2175 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2176 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2177 ret = NT_STATUS_IS_OK(status);
2178 EXPECTED(ret, True);
2179 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2180 cli_close(cli1, fnum1);
2181 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2182 cli_unlock(cli1, fnum3, 0, 1);
2184 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2185 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2186 EXPECTED(ret, True);
2187 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2189 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2190 ret = NT_STATUS_IS_OK(status);
2191 EXPECTED(ret, False);
2193 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2195 /* Unlock the process 2 lock. */
2196 cli_unlock(cli2, fnum2, 0, 4);
2198 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2199 ret = NT_STATUS_IS_OK(status);
2200 EXPECTED(ret, False);
2202 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2204 /* Unlock the process 1 fnum3 lock. */
2205 cli_unlock(cli1, fnum3, 0, 4);
2207 /* Stack 2 more locks here. */
2208 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2209 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2211 EXPECTED(ret, True);
2212 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2214 /* Unlock the first process lock, then check this was the WRITE lock that was
2217 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2218 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2220 EXPECTED(ret, True);
2221 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2223 /* Unlock the process 2 lock. */
2224 cli_unlock(cli2, fnum2, 0, 4);
2226 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2228 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2229 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2230 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2232 EXPECTED(ret, True);
2233 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2235 /* Ensure the next unlock fails. */
2236 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2237 EXPECTED(ret, False);
2238 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2240 /* Ensure connection 2 can get a write lock. */
2241 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2242 ret = NT_STATUS_IS_OK(status);
2243 EXPECTED(ret, True);
2245 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2249 cli_close(cli1, fnum1);
2250 cli_close(cli2, fnum2);
2251 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2252 if (!torture_close_connection(cli1)) {
2255 if (!torture_close_connection(cli2)) {
2259 printf("finished locktest5\n");
2265 tries the unusual lockingX locktype bits
2267 static bool run_locktest6(int dummy)
2269 static struct cli_state *cli;
2270 const char *fname[1] = { "\\lock6.txt" };
2275 if (!torture_open_connection(&cli, 0)) {
2279 cli_sockopt(cli, sockops);
2281 printf("starting locktest6\n");
2284 printf("Testing %s\n", fname[i]);
2286 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2288 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2289 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2290 cli_close(cli, fnum);
2291 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2293 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2294 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2295 cli_close(cli, fnum);
2296 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2298 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2301 torture_close_connection(cli);
2303 printf("finished locktest6\n");
2307 static bool run_locktest7(int dummy)
2309 struct cli_state *cli1;
2310 const char *fname = "\\lockt7.lck";
2313 bool correct = False;
2317 if (!torture_open_connection(&cli1, 0)) {
2321 cli_sockopt(cli1, sockops);
2323 printf("starting locktest7\n");
2325 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2327 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2329 memset(buf, 0, sizeof(buf));
2331 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2333 if (!NT_STATUS_IS_OK(status)) {
2334 printf("Failed to create file: %s\n", nt_errstr(status));
2338 cli_setpid(cli1, 1);
2340 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 printf("Unable to apply read lock on range 130:4, "
2343 "error was %s\n", nt_errstr(status));
2346 printf("pid1 successfully locked range 130:4 for READ\n");
2349 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 printf("pid1 unable to read the range 130:4, error was %s\n",
2354 } else if (nread != 4) {
2355 printf("pid1 unable to read the range 130:4, "
2356 "recv %ld req %d\n", (unsigned long)nread, 4);
2359 printf("pid1 successfully read the range 130:4\n");
2362 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2363 if (!NT_STATUS_IS_OK(status)) {
2364 printf("pid1 unable to write to the range 130:4, error was "
2365 "%s\n", nt_errstr(status));
2366 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2367 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2371 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2375 cli_setpid(cli1, 2);
2377 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 printf("pid2 unable to read the range 130:4, error was %s\n",
2382 } else if (nread != 4) {
2383 printf("pid2 unable to read the range 130:4, "
2384 "recv %ld req %d\n", (unsigned long)nread, 4);
2387 printf("pid2 successfully read the range 130:4\n");
2390 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2391 if (!NT_STATUS_IS_OK(status)) {
2392 printf("pid2 unable to write to the range 130:4, error was "
2393 "%s\n", nt_errstr(status));
2394 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2395 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2399 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2403 cli_setpid(cli1, 1);
2404 cli_unlock(cli1, fnum1, 130, 4);
2406 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2407 if (!NT_STATUS_IS_OK(status)) {
2408 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2411 printf("pid1 successfully locked range 130:4 for WRITE\n");
2414 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2415 if (!NT_STATUS_IS_OK(status)) {
2416 printf("pid1 unable to read the range 130:4, error was %s\n",
2419 } else if (nread != 4) {
2420 printf("pid1 unable to read the range 130:4, "
2421 "recv %ld req %d\n", (unsigned long)nread, 4);
2424 printf("pid1 successfully read the range 130:4\n");
2427 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2428 if (!NT_STATUS_IS_OK(status)) {
2429 printf("pid1 unable to write to the range 130:4, error was "
2430 "%s\n", nt_errstr(status));
2433 printf("pid1 successfully wrote to the range 130:4\n");
2436 cli_setpid(cli1, 2);
2438 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2439 if (!NT_STATUS_IS_OK(status)) {
2440 printf("pid2 unable to read the range 130:4, error was "
2441 "%s\n", nt_errstr(status));
2442 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2443 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2447 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2448 (unsigned long)nread);
2452 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2453 if (!NT_STATUS_IS_OK(status)) {
2454 printf("pid2 unable to write to the range 130:4, error was "
2455 "%s\n", nt_errstr(status));
2456 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2457 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2461 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2465 cli_unlock(cli1, fnum1, 130, 0);
2469 cli_close(cli1, fnum1);
2470 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2471 torture_close_connection(cli1);
2473 printf("finished locktest7\n");
2478 * This demonstrates a problem with our use of GPFS share modes: A file
2479 * descriptor sitting in the pending close queue holding a GPFS share mode
2480 * blocks opening a file another time. Happens with Word 2007 temp files.
2481 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2482 * open is denied with NT_STATUS_SHARING_VIOLATION.
2485 static bool run_locktest8(int dummy)
2487 struct cli_state *cli1;
2488 const char *fname = "\\lockt8.lck";
2489 uint16_t fnum1, fnum2;
2491 bool correct = False;
2494 if (!torture_open_connection(&cli1, 0)) {
2498 cli_sockopt(cli1, sockops);
2500 printf("starting locktest8\n");
2502 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2504 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2506 if (!NT_STATUS_IS_OK(status)) {
2507 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2511 memset(buf, 0, sizeof(buf));
2513 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2514 if (!NT_STATUS_IS_OK(status)) {
2515 d_fprintf(stderr, "cli_open second time returned %s\n",
2520 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2521 if (!NT_STATUS_IS_OK(status)) {
2522 printf("Unable to apply read lock on range 1:1, error was "
2523 "%s\n", nt_errstr(status));
2527 status = cli_close(cli1, fnum1);
2528 if (!NT_STATUS_IS_OK(status)) {
2529 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2533 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 d_fprintf(stderr, "cli_open third time returned %s\n",
2543 cli_close(cli1, fnum1);
2544 cli_close(cli1, fnum2);
2545 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2546 torture_close_connection(cli1);
2548 printf("finished locktest8\n");
2553 * This test is designed to be run in conjunction with
2554 * external NFS or POSIX locks taken in the filesystem.
2555 * It checks that the smbd server will block until the
2556 * lock is released and then acquire it. JRA.
2559 static bool got_alarm;
2560 static struct cli_state *alarm_cli;
2562 static void alarm_handler(int dummy)
2567 static void alarm_handler_parent(int dummy)
2569 cli_state_disconnect(alarm_cli);
2572 static void do_local_lock(int read_fd, int write_fd)
2577 const char *local_pathname = NULL;
2580 local_pathname = talloc_asprintf(talloc_tos(),
2581 "%s/lockt9.lck", local_path);
2582 if (!local_pathname) {
2583 printf("child: alloc fail\n");
2587 unlink(local_pathname);
2588 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2590 printf("child: open of %s failed %s.\n",
2591 local_pathname, strerror(errno));
2595 /* Now take a fcntl lock. */
2596 lock.l_type = F_WRLCK;
2597 lock.l_whence = SEEK_SET;
2600 lock.l_pid = getpid();
2602 ret = fcntl(fd,F_SETLK,&lock);
2604 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2605 local_pathname, strerror(errno));
2608 printf("child: got lock 0:4 on file %s.\n",
2613 CatchSignal(SIGALRM, alarm_handler);
2615 /* Signal the parent. */
2616 if (write(write_fd, &c, 1) != 1) {
2617 printf("child: start signal fail %s.\n",
2624 /* Wait for the parent to be ready. */
2625 if (read(read_fd, &c, 1) != 1) {
2626 printf("child: reply signal fail %s.\n",
2634 printf("child: released lock 0:4 on file %s.\n",
2640 static bool run_locktest9(int dummy)
2642 struct cli_state *cli1;
2643 const char *fname = "\\lockt9.lck";
2645 bool correct = False;
2646 int pipe_in[2], pipe_out[2];
2650 struct timeval start;
2654 printf("starting locktest9\n");
2656 if (local_path == NULL) {
2657 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2661 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2666 if (child_pid == -1) {
2670 if (child_pid == 0) {
2672 do_local_lock(pipe_out[0], pipe_in[1]);
2682 ret = read(pipe_in[0], &c, 1);
2684 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2689 if (!torture_open_connection(&cli1, 0)) {
2693 cli_sockopt(cli1, sockops);
2695 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2697 if (!NT_STATUS_IS_OK(status)) {
2698 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2702 /* Ensure the child has the lock. */
2703 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2704 if (NT_STATUS_IS_OK(status)) {
2705 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2708 d_printf("Child has the lock.\n");
2711 /* Tell the child to wait 5 seconds then exit. */
2712 ret = write(pipe_out[1], &c, 1);
2714 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2719 /* Wait 20 seconds for the lock. */
2721 CatchSignal(SIGALRM, alarm_handler_parent);
2724 start = timeval_current();
2726 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2727 if (!NT_STATUS_IS_OK(status)) {
2728 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2729 "%s\n", nt_errstr(status));
2734 seconds = timeval_elapsed(&start);
2736 printf("Parent got the lock after %.2f seconds.\n",
2739 status = cli_close(cli1, fnum);
2740 if (!NT_STATUS_IS_OK(status)) {
2741 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2748 cli_close(cli1, fnum);
2749 torture_close_connection(cli1);
2753 printf("finished locktest9\n");
2758 test whether fnums and tids open on one VC are available on another (a major
2761 static bool run_fdpasstest(int dummy)
2763 struct cli_state *cli1, *cli2;
2764 const char *fname = "\\fdpass.tst";
2769 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2772 cli_sockopt(cli1, sockops);
2773 cli_sockopt(cli2, sockops);
2775 printf("starting fdpasstest\n");
2777 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2779 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2781 if (!NT_STATUS_IS_OK(status)) {
2782 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2786 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2788 if (!NT_STATUS_IS_OK(status)) {
2789 printf("write failed (%s)\n", nt_errstr(status));
2793 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2794 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2795 cli_setpid(cli2, cli_getpid(cli1));
2797 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2798 printf("read succeeded! nasty security hole [%s]\n", buf);
2802 cli_close(cli1, fnum1);
2803 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2805 torture_close_connection(cli1);
2806 torture_close_connection(cli2);
2808 printf("finished fdpasstest\n");
2812 static bool run_fdsesstest(int dummy)
2814 struct cli_state *cli;
2819 const char *fname = "\\fdsess.tst";
2820 const char *fname1 = "\\fdsess1.tst";
2827 if (!torture_open_connection(&cli, 0))
2829 cli_sockopt(cli, sockops);
2831 if (!torture_cli_session_setup2(cli, &new_vuid))
2834 saved_cnum = cli_state_get_tid(cli);
2835 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2837 new_cnum = cli_state_get_tid(cli);
2838 cli_state_set_tid(cli, saved_cnum);
2840 printf("starting fdsesstest\n");
2842 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2843 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2845 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2851 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2853 if (!NT_STATUS_IS_OK(status)) {
2854 printf("write failed (%s)\n", nt_errstr(status));
2858 saved_vuid = cli_state_get_uid(cli);
2859 cli_state_set_uid(cli, new_vuid);
2861 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2862 printf("read succeeded with different vuid! "
2863 "nasty security hole [%s]\n", buf);
2866 /* Try to open a file with different vuid, samba cnum. */
2867 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2868 printf("create with different vuid, same cnum succeeded.\n");
2869 cli_close(cli, fnum2);
2870 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2872 printf("create with different vuid, same cnum failed.\n");
2873 printf("This will cause problems with service clients.\n");
2877 cli_state_set_uid(cli, saved_vuid);
2879 /* Try with same vuid, different cnum. */
2880 cli_state_set_tid(cli, new_cnum);
2882 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2883 printf("read succeeded with different cnum![%s]\n", buf);
2887 cli_state_set_tid(cli, saved_cnum);
2888 cli_close(cli, fnum1);
2889 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2891 torture_close_connection(cli);
2893 printf("finished fdsesstest\n");
2898 This test checks that
2900 1) the server does not allow an unlink on a file that is open
2902 static bool run_unlinktest(int dummy)
2904 struct cli_state *cli;
2905 const char *fname = "\\unlink.tst";
2907 bool correct = True;
2910 if (!torture_open_connection(&cli, 0)) {
2914 cli_sockopt(cli, sockops);
2916 printf("starting unlink test\n");
2918 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2922 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2923 if (!NT_STATUS_IS_OK(status)) {
2924 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2928 status = cli_unlink(cli, fname,
2929 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2930 if (NT_STATUS_IS_OK(status)) {
2931 printf("error: server allowed unlink on an open file\n");
2934 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2935 NT_STATUS_SHARING_VIOLATION);
2938 cli_close(cli, fnum);
2939 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2941 if (!torture_close_connection(cli)) {
2945 printf("unlink test finished\n");
2952 test how many open files this server supports on the one socket
2954 static bool run_maxfidtest(int dummy)
2956 struct cli_state *cli;
2958 uint16_t fnums[0x11000];
2961 bool correct = True;
2967 printf("failed to connect\n");
2971 cli_sockopt(cli, sockops);
2973 for (i=0; i<0x11000; i++) {
2974 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2975 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2977 if (!NT_STATUS_IS_OK(status)) {
2978 printf("open of %s failed (%s)\n",
2979 fname, nt_errstr(status));
2980 printf("maximum fnum is %d\n", i);
2988 printf("cleaning up\n");
2990 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2991 cli_close(cli, fnums[i]);
2993 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("unlink of %s failed (%s)\n",
2996 fname, nt_errstr(status));
3003 printf("maxfid test finished\n");
3004 if (!torture_close_connection(cli)) {
3010 /* generate a random buffer */
3011 static void rand_buf(char *buf, int len)
3014 *buf = (char)sys_random();
3019 /* send smb negprot commands, not reading the response */
3020 static bool run_negprot_nowait(int dummy)
3022 struct tevent_context *ev;
3024 struct cli_state *cli;
3025 bool correct = True;
3027 printf("starting negprot nowait test\n");
3029 ev = tevent_context_init(talloc_tos());
3034 if (!(cli = open_nbt_connection())) {
3039 for (i=0;i<50000;i++) {
3040 struct tevent_req *req;
3042 req = cli_negprot_send(ev, ev, cli);
3047 if (!tevent_req_poll(req, ev)) {
3048 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3056 if (torture_close_connection(cli)) {
3060 printf("finished negprot nowait test\n");
3065 /* send smb negprot commands, not reading the response */
3066 static bool run_bad_nbt_session(int dummy)
3068 struct nmb_name called, calling;
3069 struct sockaddr_storage ss;
3074 printf("starting bad nbt session test\n");
3076 make_nmb_name(&calling, myname, 0x0);
3077 make_nmb_name(&called , host, 0x20);
3079 if (!resolve_name(host, &ss, 0x20, true)) {
3080 d_fprintf(stderr, "Could not resolve name %s\n", host);
3084 status = open_socket_out(&ss, 139, 10000, &fd);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 d_fprintf(stderr, "open_socket_out failed: %s\n",
3091 ret = cli_bad_session_request(fd, &calling, &called);
3094 d_fprintf(stderr, "open_socket_out failed: %s\n",
3099 printf("finished bad nbt session test\n");
3103 /* send random IPC commands */
3104 static bool run_randomipc(int dummy)
3106 char *rparam = NULL;
3108 unsigned int rdrcnt,rprcnt;
3110 int api, param_len, i;
3111 struct cli_state *cli;
3112 bool correct = True;
3115 printf("starting random ipc test\n");
3117 if (!torture_open_connection(&cli, 0)) {
3121 for (i=0;i<count;i++) {
3122 api = sys_random() % 500;
3123 param_len = (sys_random() % 64);
3125 rand_buf(param, param_len);
3130 param, param_len, 8,
3131 NULL, 0, BUFFER_SIZE,
3135 printf("%d/%d\r", i,count);
3138 printf("%d/%d\n", i, count);
3140 if (!torture_close_connection(cli)) {
3144 printf("finished random ipc test\n");
3151 static void browse_callback(const char *sname, uint32 stype,
3152 const char *comment, void *state)
3154 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3160 This test checks the browse list code
3163 static bool run_browsetest(int dummy)
3165 static struct cli_state *cli;
3166 bool correct = True;
3168 printf("starting browse test\n");
3170 if (!torture_open_connection(&cli, 0)) {
3174 printf("domain list:\n");
3175 cli_NetServerEnum(cli, cli->server_domain,
3176 SV_TYPE_DOMAIN_ENUM,
3177 browse_callback, NULL);
3179 printf("machine list:\n");
3180 cli_NetServerEnum(cli, cli->server_domain,
3182 browse_callback, NULL);
3184 if (!torture_close_connection(cli)) {
3188 printf("browse test finished\n");
3196 This checks how the getatr calls works
3198 static bool run_attrtest(int dummy)
3200 struct cli_state *cli;
3203 const char *fname = "\\attrib123456789.tst";
3204 bool correct = True;
3207 printf("starting attrib test\n");
3209 if (!torture_open_connection(&cli, 0)) {
3213 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3214 cli_open(cli, fname,
3215 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3216 cli_close(cli, fnum);
3218 status = cli_getatr(cli, fname, NULL, NULL, &t);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 printf("getatr failed (%s)\n", nt_errstr(status));
3224 if (abs(t - time(NULL)) > 60*60*24*10) {
3225 printf("ERROR: SMBgetatr bug. time is %s",
3231 t2 = t-60*60*24; /* 1 day ago */
3233 status = cli_setatr(cli, fname, 0, t2);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 printf("setatr failed (%s)\n", nt_errstr(status));
3239 status = cli_getatr(cli, fname, NULL, NULL, &t);
3240 if (!NT_STATUS_IS_OK(status)) {
3241 printf("getatr failed (%s)\n", nt_errstr(status));
3246 printf("ERROR: getatr/setatr bug. times are\n%s",
3248 printf("%s", ctime(&t2));
3252 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3254 if (!torture_close_connection(cli)) {
3258 printf("attrib test finished\n");
3265 This checks a couple of trans2 calls
3267 static bool run_trans2test(int dummy)
3269 struct cli_state *cli;
3272 time_t c_time, a_time, m_time;
3273 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3274 const char *fname = "\\trans2.tst";
3275 const char *dname = "\\trans2";
3276 const char *fname2 = "\\trans2\\trans2.tst";
3278 bool correct = True;
3282 printf("starting trans2 test\n");
3284 if (!torture_open_connection(&cli, 0)) {
3288 status = cli_get_fs_attr_info(cli, &fs_attr);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3295 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3296 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3297 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3298 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3299 if (!NT_STATUS_IS_OK(status)) {
3300 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3304 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3305 if (!NT_STATUS_IS_OK(status)) {
3306 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3310 if (strcmp(pname, fname)) {
3311 printf("qfilename gave different name? [%s] [%s]\n",
3316 cli_close(cli, fnum);
3320 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3321 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3323 if (!NT_STATUS_IS_OK(status)) {
3324 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3327 cli_close(cli, fnum);
3329 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3331 if (!NT_STATUS_IS_OK(status)) {
3332 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3335 time_t t = time(NULL);
3337 if (c_time != m_time) {
3338 printf("create time=%s", ctime(&c_time));
3339 printf("modify time=%s", ctime(&m_time));
3340 printf("This system appears to have sticky create times\n");
3342 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3343 printf("access time=%s", ctime(&a_time));
3344 printf("This system appears to set a midnight access time\n");
3348 if (abs(m_time - t) > 60*60*24*7) {
3349 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3355 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3356 cli_open(cli, fname,
3357 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3358 cli_close(cli, fnum);
3359 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3360 &m_time_ts, &size, NULL, NULL);
3361 if (!NT_STATUS_IS_OK(status)) {
3362 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3365 if (w_time_ts.tv_sec < 60*60*24*2) {
3366 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3367 printf("This system appears to set a initial 0 write time\n");
3372 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3375 /* check if the server updates the directory modification time
3376 when creating a new file */
3377 status = cli_mkdir(cli, dname);
3378 if (!NT_STATUS_IS_OK(status)) {
3379 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3383 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3384 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3385 if (!NT_STATUS_IS_OK(status)) {
3386 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3390 cli_open(cli, fname2,
3391 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3392 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3393 cli_close(cli, fnum);
3394 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3395 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3396 if (!NT_STATUS_IS_OK(status)) {
3397 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3400 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3402 printf("This system does not update directory modification times\n");
3406 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3407 cli_rmdir(cli, dname);
3409 if (!torture_close_connection(cli)) {
3413 printf("trans2 test finished\n");
3419 This checks new W2K calls.
3422 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3424 uint8_t *buf = NULL;
3428 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3429 pcli->max_xmit, NULL, &buf, &len);
3430 if (!NT_STATUS_IS_OK(status)) {
3431 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3434 printf("qfileinfo: level %d, len = %u\n", level, len);
3435 dump_data(0, (uint8 *)buf, len);
3442 static bool run_w2ktest(int dummy)
3444 struct cli_state *cli;
3446 const char *fname = "\\w2ktest\\w2k.tst";
3448 bool correct = True;
3450 printf("starting w2k test\n");
3452 if (!torture_open_connection(&cli, 0)) {
3456 cli_open(cli, fname,
3457 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3459 for (level = 1004; level < 1040; level++) {
3460 new_trans(cli, fnum, level);
3463 cli_close(cli, fnum);
3465 if (!torture_close_connection(cli)) {
3469 printf("w2k test finished\n");
3476 this is a harness for some oplock tests
3478 static bool run_oplock1(int dummy)
3480 struct cli_state *cli1;
3481 const char *fname = "\\lockt1.lck";
3483 bool correct = True;
3486 printf("starting oplock test 1\n");
3488 if (!torture_open_connection(&cli1, 0)) {
3492 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3494 cli_sockopt(cli1, sockops);
3496 cli1->use_oplocks = True;
3498 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3500 if (!NT_STATUS_IS_OK(status)) {
3501 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3505 cli1->use_oplocks = False;
3507 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3508 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3510 status = cli_close(cli1, fnum1);
3511 if (!NT_STATUS_IS_OK(status)) {
3512 printf("close2 failed (%s)\n", nt_errstr(status));
3516 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3517 if (!NT_STATUS_IS_OK(status)) {
3518 printf("unlink failed (%s)\n", nt_errstr(status));
3522 if (!torture_close_connection(cli1)) {
3526 printf("finished oplock test 1\n");
3531 static bool run_oplock2(int dummy)
3533 struct cli_state *cli1, *cli2;
3534 const char *fname = "\\lockt2.lck";
3535 uint16_t fnum1, fnum2;
3536 int saved_use_oplocks = use_oplocks;
3538 bool correct = True;
3539 volatile bool *shared_correct;
3543 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3544 *shared_correct = True;
3546 use_level_II_oplocks = True;
3549 printf("starting oplock test 2\n");
3551 if (!torture_open_connection(&cli1, 0)) {
3552 use_level_II_oplocks = False;
3553 use_oplocks = saved_use_oplocks;
3557 if (!torture_open_connection(&cli2, 1)) {
3558 use_level_II_oplocks = False;
3559 use_oplocks = saved_use_oplocks;
3563 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3565 cli_sockopt(cli1, sockops);
3566 cli_sockopt(cli2, sockops);
3568 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3570 if (!NT_STATUS_IS_OK(status)) {
3571 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3575 /* Don't need the globals any more. */
3576 use_level_II_oplocks = False;
3577 use_oplocks = saved_use_oplocks;
3581 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3582 if (!NT_STATUS_IS_OK(status)) {
3583 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3584 *shared_correct = False;
3590 status = cli_close(cli2, fnum2);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 printf("close2 failed (%s)\n", nt_errstr(status));
3593 *shared_correct = False;
3601 /* Ensure cli1 processes the break. Empty file should always return 0
3603 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3604 if (!NT_STATUS_IS_OK(status)) {
3605 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3607 } else if (nread != 0) {
3608 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3609 (unsigned long)nread, 0);
3613 /* Should now be at level II. */
3614 /* Test if sending a write locks causes a break to none. */
3615 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3616 if (!NT_STATUS_IS_OK(status)) {
3617 printf("lock failed (%s)\n", nt_errstr(status));
3621 cli_unlock(cli1, fnum1, 0, 4);
3625 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3626 if (!NT_STATUS_IS_OK(status)) {
3627 printf("lock failed (%s)\n", nt_errstr(status));
3631 cli_unlock(cli1, fnum1, 0, 4);
3635 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3637 status = cli_close(cli1, fnum1);
3638 if (!NT_STATUS_IS_OK(status)) {
3639 printf("close1 failed (%s)\n", nt_errstr(status));
3645 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3646 if (!NT_STATUS_IS_OK(status)) {
3647 printf("unlink failed (%s)\n", nt_errstr(status));
3651 if (!torture_close_connection(cli1)) {
3655 if (!*shared_correct) {
3659 printf("finished oplock test 2\n");
3664 struct oplock4_state {
3665 struct tevent_context *ev;
3666 struct cli_state *cli;
3671 static void oplock4_got_break(struct tevent_req *req);
3672 static void oplock4_got_open(struct tevent_req *req);
3674 static bool run_oplock4(int dummy)
3676 struct tevent_context *ev;
3677 struct cli_state *cli1, *cli2;
3678 struct tevent_req *oplock_req, *open_req;
3679 const char *fname = "\\lockt4.lck";
3680 const char *fname_ln = "\\lockt4_ln.lck";
3681 uint16_t fnum1, fnum2;
3682 int saved_use_oplocks = use_oplocks;
3684 bool correct = true;
3688 struct oplock4_state *state;
3690 printf("starting oplock test 4\n");
3692 if (!torture_open_connection(&cli1, 0)) {
3693 use_level_II_oplocks = false;
3694 use_oplocks = saved_use_oplocks;
3698 if (!torture_open_connection(&cli2, 1)) {
3699 use_level_II_oplocks = false;
3700 use_oplocks = saved_use_oplocks;
3704 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3705 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3707 cli_sockopt(cli1, sockops);
3708 cli_sockopt(cli2, sockops);
3710 /* Create the file. */
3711 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3713 if (!NT_STATUS_IS_OK(status)) {
3714 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3718 status = cli_close(cli1, fnum1);
3719 if (!NT_STATUS_IS_OK(status)) {
3720 printf("close1 failed (%s)\n", nt_errstr(status));
3724 /* Now create a hardlink. */
3725 status = cli_nt_hardlink(cli1, fname, fname_ln);
3726 if (!NT_STATUS_IS_OK(status)) {
3727 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3731 /* Prove that opening hardlinks cause deny modes to conflict. */
3732 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3733 if (!NT_STATUS_IS_OK(status)) {
3734 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3738 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3739 if (NT_STATUS_IS_OK(status)) {
3740 printf("open of %s succeeded - should fail with sharing violation.\n",
3745 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3746 printf("open of %s should fail with sharing violation. Got %s\n",
3747 fname_ln, nt_errstr(status));
3751 status = cli_close(cli1, fnum1);
3752 if (!NT_STATUS_IS_OK(status)) {
3753 printf("close1 failed (%s)\n", nt_errstr(status));
3757 cli1->use_oplocks = true;
3758 cli1->use_level_II_oplocks = true;
3760 cli2->use_oplocks = true;
3761 cli2->use_level_II_oplocks = true;
3763 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3764 if (!NT_STATUS_IS_OK(status)) {
3765 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3769 ev = tevent_context_init(talloc_tos());
3771 printf("tevent_req_create failed\n");
3775 state = talloc(ev, struct oplock4_state);
3776 if (state == NULL) {
3777 printf("talloc failed\n");
3782 state->got_break = &got_break;
3783 state->fnum2 = &fnum2;
3785 oplock_req = cli_smb_oplock_break_waiter_send(
3786 talloc_tos(), ev, cli1);
3787 if (oplock_req == NULL) {
3788 printf("cli_smb_oplock_break_waiter_send failed\n");
3791 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3793 open_req = cli_open_send(
3794 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3795 if (oplock_req == NULL) {
3796 printf("cli_open_send failed\n");
3799 tevent_req_set_callback(open_req, oplock4_got_open, state);
3804 while (!got_break || fnum2 == 0xffff) {
3806 ret = tevent_loop_once(ev);
3808 printf("tevent_loop_once failed: %s\n",
3814 status = cli_close(cli2, fnum2);
3815 if (!NT_STATUS_IS_OK(status)) {
3816 printf("close2 failed (%s)\n", nt_errstr(status));
3820 status = cli_close(cli1, fnum1);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 printf("close1 failed (%s)\n", nt_errstr(status));
3826 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3827 if (!NT_STATUS_IS_OK(status)) {
3828 printf("unlink failed (%s)\n", nt_errstr(status));
3832 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("unlink failed (%s)\n", nt_errstr(status));
3838 if (!torture_close_connection(cli1)) {
3846 printf("finished oplock test 4\n");
3851 static void oplock4_got_break(struct tevent_req *req)
3853 struct oplock4_state *state = tevent_req_callback_data(
3854 req, struct oplock4_state);
3859 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3866 *state->got_break = true;
3868 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3871 printf("cli_oplock_ack_send failed\n");
3876 static void oplock4_got_open(struct tevent_req *req)
3878 struct oplock4_state *state = tevent_req_callback_data(
3879 req, struct oplock4_state);
3882 status = cli_open_recv(req, state->fnum2);
3883 if (!NT_STATUS_IS_OK(status)) {
3884 printf("cli_open_recv returned %s\n", nt_errstr(status));
3885 *state->fnum2 = 0xffff;
3890 Test delete on close semantics.
3892 static bool run_deletetest(int dummy)
3894 struct cli_state *cli1 = NULL;
3895 struct cli_state *cli2 = NULL;
3896 const char *fname = "\\delete.file";
3897 uint16_t fnum1 = (uint16_t)-1;
3898 uint16_t fnum2 = (uint16_t)-1;
3899 bool correct = True;
3902 printf("starting delete test\n");
3904 if (!torture_open_connection(&cli1, 0)) {
3908 cli_sockopt(cli1, sockops);
3910 /* Test 1 - this should delete the file on close. */
3912 cli_setatr(cli1, fname, 0, 0);
3913 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3915 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3916 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3917 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3924 status = cli_close(cli1, fnum1);
3925 if (!NT_STATUS_IS_OK(status)) {
3926 printf("[1] close failed (%s)\n", nt_errstr(status));
3931 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3932 printf("[1] open of %s succeeded (should fail)\n", fname);
3937 printf("first delete on close test succeeded.\n");
3939 /* Test 2 - this should delete the file on close. */
3941 cli_setatr(cli1, fname, 0, 0);
3942 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3944 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3945 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3946 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3947 if (!NT_STATUS_IS_OK(status)) {
3948 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3953 status = cli_nt_delete_on_close(cli1, fnum1, true);
3954 if (!NT_STATUS_IS_OK(status)) {
3955 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3960 status = cli_close(cli1, fnum1);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 printf("[2] close failed (%s)\n", nt_errstr(status));
3967 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3968 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3969 status = cli_close(cli1, fnum1);
3970 if (!NT_STATUS_IS_OK(status)) {
3971 printf("[2] close failed (%s)\n", nt_errstr(status));
3975 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3977 printf("second delete on close test succeeded.\n");
3980 cli_setatr(cli1, fname, 0, 0);
3981 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3983 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3984 FILE_ATTRIBUTE_NORMAL,
3985 FILE_SHARE_READ|FILE_SHARE_WRITE,
3986 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3987 if (!NT_STATUS_IS_OK(status)) {
3988 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3993 /* This should fail with a sharing violation - open for delete is only compatible
3994 with SHARE_DELETE. */
3996 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3997 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3998 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4003 /* This should succeed. */
4004 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4005 FILE_ATTRIBUTE_NORMAL,
4006 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4007 FILE_OPEN, 0, 0, &fnum2);
4008 if (!NT_STATUS_IS_OK(status)) {
4009 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4014 status = cli_nt_delete_on_close(cli1, fnum1, true);
4015 if (!NT_STATUS_IS_OK(status)) {
4016 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4021 status = cli_close(cli1, fnum1);
4022 if (!NT_STATUS_IS_OK(status)) {
4023 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4028 status = cli_close(cli1, fnum2);
4029 if (!NT_STATUS_IS_OK(status)) {
4030 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4035 /* This should fail - file should no longer be there. */
4037 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4038 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4039 status = cli_close(cli1, fnum1);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("[3] close failed (%s)\n", nt_errstr(status));
4043 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4047 printf("third delete on close test succeeded.\n");
4050 cli_setatr(cli1, fname, 0, 0);
4051 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4053 status = cli_ntcreate(cli1, fname, 0,
4054 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4055 FILE_ATTRIBUTE_NORMAL,
4056 FILE_SHARE_READ|FILE_SHARE_WRITE,
4057 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4058 if (!NT_STATUS_IS_OK(status)) {
4059 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4064 /* This should succeed. */
4065 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4066 FILE_ATTRIBUTE_NORMAL,
4067 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4068 FILE_OPEN, 0, 0, &fnum2);
4069 if (!NT_STATUS_IS_OK(status)) {
4070 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4075 status = cli_close(cli1, fnum2);
4076 if (!NT_STATUS_IS_OK(status)) {
4077 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4082 status = cli_nt_delete_on_close(cli1, fnum1, true);
4083 if (!NT_STATUS_IS_OK(status)) {
4084 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4089 /* This should fail - no more opens once delete on close set. */
4090 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4091 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4092 FILE_OPEN, 0, 0, &fnum2))) {
4093 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4097 printf("fourth delete on close test succeeded.\n");
4099 status = cli_close(cli1, fnum1);
4100 if (!NT_STATUS_IS_OK(status)) {
4101 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4107 cli_setatr(cli1, fname, 0, 0);
4108 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4110 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4117 /* This should fail - only allowed on NT opens with DELETE access. */
4119 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4120 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4125 status = cli_close(cli1, fnum1);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4132 printf("fifth delete on close test succeeded.\n");
4135 cli_setatr(cli1, fname, 0, 0);
4136 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4138 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4139 FILE_ATTRIBUTE_NORMAL,
4140 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4141 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 printf("[6] open of %s failed (%s)\n", fname,
4149 /* This should fail - only allowed on NT opens with DELETE access. */
4151 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4152 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4157 status = cli_close(cli1, fnum1);
4158 if (!NT_STATUS_IS_OK(status)) {
4159 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4164 printf("sixth delete on close test succeeded.\n");
4167 cli_setatr(cli1, fname, 0, 0);
4168 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4170 status = cli_ntcreate(cli1, fname, 0,
4171 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4172 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4174 if (!NT_STATUS_IS_OK(status)) {
4175 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4180 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4181 printf("[7] setting delete_on_close on file failed !\n");
4186 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4187 printf("[7] unsetting delete_on_close on file failed !\n");
4192 status = cli_close(cli1, fnum1);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4199 /* This next open should succeed - we reset the flag. */
4200 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4201 if (!NT_STATUS_IS_OK(status)) {
4202 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4207 status = cli_close(cli1, fnum1);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4214 printf("seventh delete on close test succeeded.\n");
4217 cli_setatr(cli1, fname, 0, 0);
4218 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4220 if (!torture_open_connection(&cli2, 1)) {
4221 printf("[8] failed to open second connection.\n");
4226 cli_sockopt(cli1, sockops);
4228 status = cli_ntcreate(cli1, fname, 0,
4229 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4230 FILE_ATTRIBUTE_NORMAL,
4231 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4232 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4233 if (!NT_STATUS_IS_OK(status)) {
4234 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4239 status = cli_ntcreate(cli2, fname, 0,
4240 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4241 FILE_ATTRIBUTE_NORMAL,
4242 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4243 FILE_OPEN, 0, 0, &fnum2);
4244 if (!NT_STATUS_IS_OK(status)) {
4245 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4250 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4251 printf("[8] setting delete_on_close on file failed !\n");
4256 status = cli_close(cli1, fnum1);
4257 if (!NT_STATUS_IS_OK(status)) {
4258 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4263 status = cli_close(cli2, fnum2);
4264 if (!NT_STATUS_IS_OK(status)) {
4265 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4270 /* This should fail.. */
4271 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4272 if (NT_STATUS_IS_OK(status)) {
4273 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4277 printf("eighth delete on close test succeeded.\n");
4279 /* This should fail - we need to set DELETE_ACCESS. */
4280 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4281 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4282 printf("[9] open of %s succeeded should have failed!\n", fname);
4287 printf("ninth delete on close test succeeded.\n");
4289 status = cli_ntcreate(cli1, fname, 0,
4290 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4291 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4292 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4300 /* This should delete the file. */
4301 status = cli_close(cli1, fnum1);
4302 if (!NT_STATUS_IS_OK(status)) {
4303 printf("[10] close failed (%s)\n", nt_errstr(status));
4308 /* This should fail.. */
4309 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4310 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4314 printf("tenth delete on close test succeeded.\n");
4316 cli_setatr(cli1, fname, 0, 0);
4317 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4319 /* What error do we get when attempting to open a read-only file with
4322 /* Create a readonly file. */
4323 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4324 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4325 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4326 if (!NT_STATUS_IS_OK(status)) {
4327 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4332 status = cli_close(cli1, fnum1);
4333 if (!NT_STATUS_IS_OK(status)) {
4334 printf("[11] close failed (%s)\n", nt_errstr(status));
4339 /* Now try open for delete access. */
4340 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4341 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4342 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4343 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4344 cli_close(cli1, fnum1);
4348 NTSTATUS nterr = cli_nt_error(cli1);
4349 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4350 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4354 printf("eleventh delete on close test succeeded.\n");
4358 printf("finished delete test\n");
4361 /* FIXME: This will crash if we aborted before cli2 got
4362 * intialized, because these functions don't handle
4363 * uninitialized connections. */
4365 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4366 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4367 cli_setatr(cli1, fname, 0, 0);
4368 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4370 if (cli1 && !torture_close_connection(cli1)) {
4373 if (cli2 && !torture_close_connection(cli2)) {
4379 static bool run_deletetest_ln(int dummy)
4381 struct cli_state *cli;
4382 const char *fname = "\\delete1";
4383 const char *fname_ln = "\\delete1_ln";
4387 bool correct = true;
4390 printf("starting deletetest-ln\n");
4392 if (!torture_open_connection(&cli, 0)) {
4396 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4397 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4399 cli_sockopt(cli, sockops);
4401 /* Create the file. */
4402 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4403 if (!NT_STATUS_IS_OK(status)) {
4404 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4408 status = cli_close(cli, fnum);
4409 if (!NT_STATUS_IS_OK(status)) {
4410 printf("close1 failed (%s)\n", nt_errstr(status));
4414 /* Now create a hardlink. */
4415 status = cli_nt_hardlink(cli, fname, fname_ln);
4416 if (!NT_STATUS_IS_OK(status)) {
4417 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4421 /* Open the original file. */
4422 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4423 FILE_ATTRIBUTE_NORMAL,
4424 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4425 FILE_OPEN_IF, 0, 0, &fnum);
4426 if (!NT_STATUS_IS_OK(status)) {
4427 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4431 /* Unlink the hard link path. */
4432 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4433 FILE_ATTRIBUTE_NORMAL,
4434 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4435 FILE_OPEN_IF, 0, 0, &fnum1);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4440 status = cli_nt_delete_on_close(cli, fnum1, true);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4443 __location__, fname_ln, nt_errstr(status));
4447 status = cli_close(cli, fnum1);
4448 if (!NT_STATUS_IS_OK(status)) {
4449 printf("close %s failed (%s)\n",
4450 fname_ln, nt_errstr(status));
4454 status = cli_close(cli, fnum);
4455 if (!NT_STATUS_IS_OK(status)) {
4456 printf("close %s failed (%s)\n",
4457 fname, nt_errstr(status));
4461 /* Ensure the original file is still there. */
4462 status = cli_getatr(cli, fname, NULL, NULL, &t);
4463 if (!NT_STATUS_IS_OK(status)) {
4464 printf("%s getatr on file %s failed (%s)\n",
4471 /* Ensure the link path is gone. */
4472 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4473 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4474 printf("%s, getatr for file %s returned wrong error code %s "
4475 "- should have been deleted\n",
4477 fname_ln, nt_errstr(status));
4481 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4482 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4484 if (!torture_close_connection(cli)) {
4488 printf("finished deletetest-ln\n");
4494 print out server properties
4496 static bool run_properties(int dummy)
4498 struct cli_state *cli;
4499 bool correct = True;
4501 printf("starting properties test\n");
4505 if (!torture_open_connection(&cli, 0)) {
4509 cli_sockopt(cli, sockops);
4511 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli));
4513 if (!torture_close_connection(cli)) {
4522 /* FIRST_DESIRED_ACCESS 0xf019f */
4523 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4524 FILE_READ_EA| /* 0xf */ \
4525 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4526 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4527 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4528 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4529 /* SECOND_DESIRED_ACCESS 0xe0080 */
4530 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4531 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4532 WRITE_OWNER_ACCESS /* 0xe0000 */
4535 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4536 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4538 WRITE_OWNER_ACCESS /* */
4542 Test ntcreate calls made by xcopy
4544 static bool run_xcopy(int dummy)
4546 static struct cli_state *cli1;
4547 const char *fname = "\\test.txt";
4548 bool correct = True;
4549 uint16_t fnum1, fnum2;
4552 printf("starting xcopy test\n");
4554 if (!torture_open_connection(&cli1, 0)) {
4558 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4559 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4560 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 printf("First open failed - %s\n", nt_errstr(status));
4566 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4567 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4568 FILE_OPEN, 0x200000, 0, &fnum2);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 printf("second open failed - %s\n", nt_errstr(status));
4574 if (!torture_close_connection(cli1)) {
4582 Test rename on files open with share delete and no share delete.
4584 static bool run_rename(int dummy)
4586 static struct cli_state *cli1;
4587 const char *fname = "\\test.txt";
4588 const char *fname1 = "\\test1.txt";
4589 bool correct = True;
4594 printf("starting rename test\n");
4596 if (!torture_open_connection(&cli1, 0)) {
4600 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4601 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4603 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4604 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4605 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("First open failed - %s\n", nt_errstr(status));
4611 status = cli_rename(cli1, fname, fname1);
4612 if (!NT_STATUS_IS_OK(status)) {
4613 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4615 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4619 status = cli_close(cli1, fnum1);
4620 if (!NT_STATUS_IS_OK(status)) {
4621 printf("close - 1 failed (%s)\n", nt_errstr(status));
4625 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4626 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4627 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4629 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4631 FILE_SHARE_DELETE|FILE_SHARE_READ,
4633 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4634 if (!NT_STATUS_IS_OK(status)) {
4635 printf("Second open failed - %s\n", nt_errstr(status));
4639 status = cli_rename(cli1, fname, fname1);
4640 if (!NT_STATUS_IS_OK(status)) {
4641 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4644 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4647 status = cli_close(cli1, fnum1);
4648 if (!NT_STATUS_IS_OK(status)) {
4649 printf("close - 2 failed (%s)\n", nt_errstr(status));
4653 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4654 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4656 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4657 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4658 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4659 if (!NT_STATUS_IS_OK(status)) {
4660 printf("Third open failed - %s\n", nt_errstr(status));
4669 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4670 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4671 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4674 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4675 printf("[8] setting delete_on_close on file failed !\n");
4679 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4680 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4686 status = cli_rename(cli1, fname, fname1);
4687 if (!NT_STATUS_IS_OK(status)) {
4688 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4691 printf("Third rename succeeded (SHARE_NONE)\n");
4694 status = cli_close(cli1, fnum1);
4695 if (!NT_STATUS_IS_OK(status)) {
4696 printf("close - 3 failed (%s)\n", nt_errstr(status));
4700 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4701 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4705 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4706 FILE_ATTRIBUTE_NORMAL,
4707 FILE_SHARE_READ | FILE_SHARE_WRITE,
4708 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4709 if (!NT_STATUS_IS_OK(status)) {
4710 printf("Fourth open failed - %s\n", nt_errstr(status));
4714 status = cli_rename(cli1, fname, fname1);
4715 if (!NT_STATUS_IS_OK(status)) {
4716 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4718 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4722 status = cli_close(cli1, fnum1);
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("close - 4 failed (%s)\n", nt_errstr(status));
4728 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4729 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4733 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4734 FILE_ATTRIBUTE_NORMAL,
4735 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4736 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("Fifth open failed - %s\n", nt_errstr(status));
4742 status = cli_rename(cli1, fname, fname1);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4747 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4751 * Now check if the first name still exists ...
4754 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4755 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4756 printf("Opening original file after rename of open file fails: %s\n",
4760 printf("Opening original file after rename of open file works ...\n");
4761 (void)cli_close(cli1, fnum2);
4765 status = cli_close(cli1, fnum1);
4766 if (!NT_STATUS_IS_OK(status)) {
4767 printf("close - 5 failed (%s)\n", nt_errstr(status));
4771 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4772 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 printf("getatr on file %s failed - %s ! \n",
4775 fname1, nt_errstr(status));
4778 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4779 printf("Renamed file %s has wrong attr 0x%x "
4780 "(should be 0x%x)\n",
4783 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4786 printf("Renamed file %s has archive bit set\n", fname1);
4790 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4791 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4793 if (!torture_close_connection(cli1)) {
4800 static bool run_pipe_number(int dummy)
4802 struct cli_state *cli1;
4803 const char *pipe_name = "\\SPOOLSS";
4808 printf("starting pipenumber test\n");
4809 if (!torture_open_connection(&cli1, 0)) {
4813 cli_sockopt(cli1, sockops);
4815 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4816 FILE_ATTRIBUTE_NORMAL,
4817 FILE_SHARE_READ|FILE_SHARE_WRITE,
4818 FILE_OPEN_IF, 0, 0, &fnum);
4819 if (!NT_STATUS_IS_OK(status)) {
4820 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4824 printf("\r%6d", num_pipes);
4827 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4828 torture_close_connection(cli1);
4833 Test open mode returns on read-only files.
4835 static bool run_opentest(int dummy)
4837 static struct cli_state *cli1;
4838 static struct cli_state *cli2;
4839 const char *fname = "\\readonly.file";
4840 uint16_t fnum1, fnum2;
4843 bool correct = True;
4847 printf("starting open test\n");
4849 if (!torture_open_connection(&cli1, 0)) {
4853 cli_setatr(cli1, fname, 0, 0);
4854 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4856 cli_sockopt(cli1, sockops);
4858 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4859 if (!NT_STATUS_IS_OK(status)) {
4860 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4864 status = cli_close(cli1, fnum1);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("close2 failed (%s)\n", nt_errstr(status));
4870 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4871 if (!NT_STATUS_IS_OK(status)) {
4872 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4876 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4877 if (!NT_STATUS_IS_OK(status)) {
4878 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4882 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4883 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4885 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4886 NT_STATUS_ACCESS_DENIED)) {
4887 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4890 printf("finished open test 1\n");
4892 cli_close(cli1, fnum1);
4894 /* Now try not readonly and ensure ERRbadshare is returned. */
4896 cli_setatr(cli1, fname, 0, 0);
4898 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4899 if (!NT_STATUS_IS_OK(status)) {
4900 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4904 /* This will fail - but the error should be ERRshare. */
4905 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4907 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4908 NT_STATUS_SHARING_VIOLATION)) {
4909 printf("correct error code ERRDOS/ERRbadshare returned\n");
4912 status = cli_close(cli1, fnum1);
4913 if (!NT_STATUS_IS_OK(status)) {
4914 printf("close2 failed (%s)\n", nt_errstr(status));
4918 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4920 printf("finished open test 2\n");
4922 /* Test truncate open disposition on file opened for read. */
4923 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4924 if (!NT_STATUS_IS_OK(status)) {
4925 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4929 /* write 20 bytes. */
4931 memset(buf, '\0', 20);
4933 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4934 if (!NT_STATUS_IS_OK(status)) {
4935 printf("write failed (%s)\n", nt_errstr(status));
4939 status = cli_close(cli1, fnum1);
4940 if (!NT_STATUS_IS_OK(status)) {
4941 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4945 /* Ensure size == 20. */
4946 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4947 if (!NT_STATUS_IS_OK(status)) {
4948 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4953 printf("(3) file size != 20\n");
4957 /* Now test if we can truncate a file opened for readonly. */
4958 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4959 if (!NT_STATUS_IS_OK(status)) {
4960 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4964 status = cli_close(cli1, fnum1);
4965 if (!NT_STATUS_IS_OK(status)) {
4966 printf("close2 failed (%s)\n", nt_errstr(status));
4970 /* Ensure size == 0. */
4971 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4978 printf("(3) file size != 0\n");
4981 printf("finished open test 3\n");
4983 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4985 printf("Do ctemp tests\n");
4986 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4987 if (!NT_STATUS_IS_OK(status)) {
4988 printf("ctemp failed (%s)\n", nt_errstr(status));
4992 printf("ctemp gave path %s\n", tmp_path);
4993 status = cli_close(cli1, fnum1);
4994 if (!NT_STATUS_IS_OK(status)) {
4995 printf("close of temp failed (%s)\n", nt_errstr(status));
4998 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5003 /* Test the non-io opens... */
5005 if (!torture_open_connection(&cli2, 1)) {
5009 cli_setatr(cli2, fname, 0, 0);
5010 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5012 cli_sockopt(cli2, sockops);
5014 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5015 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5016 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5017 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5018 if (!NT_STATUS_IS_OK(status)) {
5019 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5023 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5024 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5025 FILE_OPEN_IF, 0, 0, &fnum2);
5026 if (!NT_STATUS_IS_OK(status)) {
5027 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5031 status = cli_close(cli1, fnum1);
5032 if (!NT_STATUS_IS_OK(status)) {
5033 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5037 status = cli_close(cli2, fnum2);
5038 if (!NT_STATUS_IS_OK(status)) {
5039 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5043 printf("non-io open test #1 passed.\n");
5045 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5047 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5049 status = cli_ntcreate(cli1, fname, 0,
5050 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5051 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5052 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5053 if (!NT_STATUS_IS_OK(status)) {
5054 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5058 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5059 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5060 FILE_OPEN_IF, 0, 0, &fnum2);
5061 if (!NT_STATUS_IS_OK(status)) {
5062 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5066 status = cli_close(cli1, fnum1);
5067 if (!NT_STATUS_IS_OK(status)) {
5068 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5072 status = cli_close(cli2, fnum2);
5073 if (!NT_STATUS_IS_OK(status)) {
5074 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5078 printf("non-io open test #2 passed.\n");
5080 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5082 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5084 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5085 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5086 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5087 if (!NT_STATUS_IS_OK(status)) {
5088 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5092 status = cli_ntcreate(cli2, fname, 0,
5093 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5094 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5095 FILE_OPEN_IF, 0, 0, &fnum2);
5096 if (!NT_STATUS_IS_OK(status)) {
5097 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5101 status = cli_close(cli1, fnum1);
5102 if (!NT_STATUS_IS_OK(status)) {
5103 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5107 status = cli_close(cli2, fnum2);
5108 if (!NT_STATUS_IS_OK(status)) {
5109 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5113 printf("non-io open test #3 passed.\n");
5115 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5117 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5119 status = cli_ntcreate(cli1, fname, 0,
5120 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5121 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5122 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5123 if (!NT_STATUS_IS_OK(status)) {
5124 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5128 status = cli_ntcreate(cli2, fname, 0,
5129 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5130 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5131 FILE_OPEN_IF, 0, 0, &fnum2);
5132 if (NT_STATUS_IS_OK(status)) {
5133 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5137 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5139 status = cli_close(cli1, fnum1);
5140 if (!NT_STATUS_IS_OK(status)) {
5141 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5145 printf("non-io open test #4 passed.\n");
5147 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5149 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5151 status = cli_ntcreate(cli1, fname, 0,
5152 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5153 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5154 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5155 if (!NT_STATUS_IS_OK(status)) {
5156 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5160 status = cli_ntcreate(cli2, fname, 0,
5161 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5162 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5163 FILE_OPEN_IF, 0, 0, &fnum2);
5164 if (!NT_STATUS_IS_OK(status)) {
5165 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5169 status = cli_close(cli1, fnum1);
5170 if (!NT_STATUS_IS_OK(status)) {
5171 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5175 status = cli_close(cli2, fnum2);
5176 if (!NT_STATUS_IS_OK(status)) {
5177 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5181 printf("non-io open test #5 passed.\n");
5183 printf("TEST #6 testing 1 non-io open, one io open\n");
5185 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5187 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5188 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5189 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5190 if (!NT_STATUS_IS_OK(status)) {
5191 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5195 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5196 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5197 FILE_OPEN_IF, 0, 0, &fnum2);
5198 if (!NT_STATUS_IS_OK(status)) {
5199 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5203 status = cli_close(cli1, fnum1);
5204 if (!NT_STATUS_IS_OK(status)) {
5205 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5209 status = cli_close(cli2, fnum2);
5210 if (!NT_STATUS_IS_OK(status)) {
5211 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5215 printf("non-io open test #6 passed.\n");
5217 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5219 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5221 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5222 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5223 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5224 if (!NT_STATUS_IS_OK(status)) {
5225 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5229 status = cli_ntcreate(cli2, fname, 0,
5230 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5231 FILE_ATTRIBUTE_NORMAL,
5232 FILE_SHARE_READ|FILE_SHARE_DELETE,
5233 FILE_OPEN_IF, 0, 0, &fnum2);
5234 if (NT_STATUS_IS_OK(status)) {
5235 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5239 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5241 status = cli_close(cli1, fnum1);
5242 if (!NT_STATUS_IS_OK(status)) {
5243 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5247 printf("non-io open test #7 passed.\n");
5249 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5251 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5252 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5253 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5254 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5261 /* Write to ensure we have to update the file time. */
5262 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5270 status = cli_close(cli1, fnum1);
5271 if (!NT_STATUS_IS_OK(status)) {
5272 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5278 if (!torture_close_connection(cli1)) {
5281 if (!torture_close_connection(cli2)) {
5288 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5290 uint16 major, minor;
5291 uint32 caplow, caphigh;
5294 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5295 printf("Server doesn't support UNIX CIFS extensions.\n");
5296 return NT_STATUS_NOT_SUPPORTED;
5299 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5301 if (!NT_STATUS_IS_OK(status)) {
5302 printf("Server didn't return UNIX CIFS extensions: %s\n",
5307 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5309 if (!NT_STATUS_IS_OK(status)) {
5310 printf("Server doesn't support setting UNIX CIFS extensions: "
5311 "%s.\n", nt_errstr(status));
5315 return NT_STATUS_OK;
5319 Test POSIX open /mkdir calls.
5321 static bool run_simple_posix_open_test(int dummy)
5323 static struct cli_state *cli1;
5324 const char *fname = "posix:file";
5325 const char *hname = "posix:hlink";
5326 const char *sname = "posix:symlink";
5327 const char *dname = "posix:dir";
5330 uint16_t fnum1 = (uint16_t)-1;
5331 SMB_STRUCT_STAT sbuf;
5332 bool correct = false;
5336 printf("Starting simple POSIX open test\n");
5338 if (!torture_open_connection(&cli1, 0)) {
5342 cli_sockopt(cli1, sockops);
5344 status = torture_setup_unix_extensions(cli1);
5345 if (!NT_STATUS_IS_OK(status)) {
5349 cli_setatr(cli1, fname, 0, 0);
5350 cli_posix_unlink(cli1, fname);
5351 cli_setatr(cli1, dname, 0, 0);
5352 cli_posix_rmdir(cli1, dname);
5353 cli_setatr(cli1, hname, 0, 0);
5354 cli_posix_unlink(cli1, hname);
5355 cli_setatr(cli1, sname, 0, 0);
5356 cli_posix_unlink(cli1, sname);
5358 /* Create a directory. */
5359 status = cli_posix_mkdir(cli1, dname, 0777);
5360 if (!NT_STATUS_IS_OK(status)) {
5361 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5365 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5367 if (!NT_STATUS_IS_OK(status)) {
5368 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5372 /* Test ftruncate - set file size. */
5373 status = cli_ftruncate(cli1, fnum1, 1000);
5374 if (!NT_STATUS_IS_OK(status)) {
5375 printf("ftruncate failed (%s)\n", nt_errstr(status));
5379 /* Ensure st_size == 1000 */
5380 status = cli_posix_stat(cli1, fname, &sbuf);
5381 if (!NT_STATUS_IS_OK(status)) {
5382 printf("stat failed (%s)\n", nt_errstr(status));
5386 if (sbuf.st_ex_size != 1000) {
5387 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5391 /* Test ftruncate - set file size back to zero. */
5392 status = cli_ftruncate(cli1, fnum1, 0);
5393 if (!NT_STATUS_IS_OK(status)) {
5394 printf("ftruncate failed (%s)\n", nt_errstr(status));
5398 status = cli_close(cli1, fnum1);
5399 if (!NT_STATUS_IS_OK(status)) {
5400 printf("close failed (%s)\n", nt_errstr(status));
5404 /* Now open the file again for read only. */
5405 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5406 if (!NT_STATUS_IS_OK(status)) {
5407 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5411 /* Now unlink while open. */
5412 status = cli_posix_unlink(cli1, fname);
5413 if (!NT_STATUS_IS_OK(status)) {
5414 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5418 status = cli_close(cli1, fnum1);
5419 if (!NT_STATUS_IS_OK(status)) {
5420 printf("close(2) failed (%s)\n", nt_errstr(status));
5424 /* Ensure the file has gone. */
5425 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5426 if (NT_STATUS_IS_OK(status)) {
5427 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5431 /* Create again to test open with O_TRUNC. */
5432 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5433 if (!NT_STATUS_IS_OK(status)) {
5434 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5438 /* Test ftruncate - set file size. */
5439 status = cli_ftruncate(cli1, fnum1, 1000);
5440 if (!NT_STATUS_IS_OK(status)) {
5441 printf("ftruncate failed (%s)\n", nt_errstr(status));
5445 /* Ensure st_size == 1000 */
5446 status = cli_posix_stat(cli1, fname, &sbuf);
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("stat failed (%s)\n", nt_errstr(status));
5452 if (sbuf.st_ex_size != 1000) {
5453 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5457 status = cli_close(cli1, fnum1);
5458 if (!NT_STATUS_IS_OK(status)) {
5459 printf("close(2) failed (%s)\n", nt_errstr(status));
5463 /* Re-open with O_TRUNC. */
5464 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5465 if (!NT_STATUS_IS_OK(status)) {
5466 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5470 /* Ensure st_size == 0 */
5471 status = cli_posix_stat(cli1, fname, &sbuf);
5472 if (!NT_STATUS_IS_OK(status)) {
5473 printf("stat failed (%s)\n", nt_errstr(status));
5477 if (sbuf.st_ex_size != 0) {
5478 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5482 status = cli_close(cli1, fnum1);
5483 if (!NT_STATUS_IS_OK(status)) {
5484 printf("close failed (%s)\n", nt_errstr(status));
5488 status = cli_posix_unlink(cli1, fname);
5489 if (!NT_STATUS_IS_OK(status)) {
5490 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5494 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5495 if (!NT_STATUS_IS_OK(status)) {
5496 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5497 dname, nt_errstr(status));
5501 cli_close(cli1, fnum1);
5503 /* What happens when we try and POSIX open a directory for write ? */
5504 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5505 if (NT_STATUS_IS_OK(status)) {
5506 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5509 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5510 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5515 /* Create the file. */
5516 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5518 if (!NT_STATUS_IS_OK(status)) {
5519 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5523 /* Write some data into it. */
5524 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5526 if (!NT_STATUS_IS_OK(status)) {
5527 printf("cli_write failed: %s\n", nt_errstr(status));
5531 cli_close(cli1, fnum1);
5533 /* Now create a hardlink. */
5534 status = cli_posix_hardlink(cli1, fname, hname);
5535 if (!NT_STATUS_IS_OK(status)) {
5536 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5540 /* Now create a symlink. */
5541 status = cli_posix_symlink(cli1, fname, sname);
5542 if (!NT_STATUS_IS_OK(status)) {
5543 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5547 /* Open the hardlink for read. */
5548 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5549 if (!NT_STATUS_IS_OK(status)) {
5550 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5554 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5555 if (!NT_STATUS_IS_OK(status)) {
5556 printf("POSIX read of %s failed (%s)\n", hname,
5559 } else if (nread != 10) {
5560 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5561 hname, (unsigned long)nread, 10);
5565 if (memcmp(buf, "TEST DATA\n", 10)) {
5566 printf("invalid data read from hardlink\n");
5570 /* Do a POSIX lock/unlock. */
5571 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 printf("POSIX lock failed %s\n", nt_errstr(status));
5577 /* Punch a hole in the locked area. */
5578 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5579 if (!NT_STATUS_IS_OK(status)) {
5580 printf("POSIX unlock failed %s\n", nt_errstr(status));
5584 cli_close(cli1, fnum1);
5586 /* Open the symlink for read - this should fail. A POSIX
5587 client should not be doing opens on a symlink. */
5588 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5589 if (NT_STATUS_IS_OK(status)) {
5590 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5593 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5594 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5595 printf("POSIX open of %s should have failed "
5596 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5597 "failed with %s instead.\n",
5598 sname, nt_errstr(status));
5603 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5604 if (!NT_STATUS_IS_OK(status)) {
5605 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5609 if (strcmp(namebuf, fname) != 0) {
5610 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5611 sname, fname, namebuf);
5615 status = cli_posix_rmdir(cli1, dname);
5616 if (!NT_STATUS_IS_OK(status)) {
5617 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5621 printf("Simple POSIX open test passed\n");
5626 if (fnum1 != (uint16_t)-1) {
5627 cli_close(cli1, fnum1);
5628 fnum1 = (uint16_t)-1;
5631 cli_setatr(cli1, sname, 0, 0);
5632 cli_posix_unlink(cli1, sname);
5633 cli_setatr(cli1, hname, 0, 0);
5634 cli_posix_unlink(cli1, hname);
5635 cli_setatr(cli1, fname, 0, 0);
5636 cli_posix_unlink(cli1, fname);
5637 cli_setatr(cli1, dname, 0, 0);
5638 cli_posix_rmdir(cli1, dname);
5640 if (!torture_close_connection(cli1)) {
5648 static uint32 open_attrs_table[] = {
5649 FILE_ATTRIBUTE_NORMAL,
5650 FILE_ATTRIBUTE_ARCHIVE,
5651 FILE_ATTRIBUTE_READONLY,
5652 FILE_ATTRIBUTE_HIDDEN,
5653 FILE_ATTRIBUTE_SYSTEM,
5655 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5656 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5657 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5658 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5659 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5660 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5662 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5663 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5664 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5665 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5668 struct trunc_open_results {
5675 static struct trunc_open_results attr_results[] = {
5676 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5677 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5678 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5679 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5680 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5681 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5682 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5683 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5684 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5685 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5686 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5687 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5688 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5689 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5690 { 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 },
5691 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5692 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5693 { 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 },
5694 { 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 },
5695 { 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 },
5696 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5697 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5698 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5699 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5700 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5701 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5704 static bool run_openattrtest(int dummy)
5706 static struct cli_state *cli1;
5707 const char *fname = "\\openattr.file";
5709 bool correct = True;
5711 unsigned int i, j, k, l;
5714 printf("starting open attr test\n");
5716 if (!torture_open_connection(&cli1, 0)) {
5720 cli_sockopt(cli1, sockops);
5722 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5723 cli_setatr(cli1, fname, 0, 0);
5724 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5726 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5727 open_attrs_table[i], FILE_SHARE_NONE,
5728 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5729 if (!NT_STATUS_IS_OK(status)) {
5730 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5734 status = cli_close(cli1, fnum1);
5735 if (!NT_STATUS_IS_OK(status)) {
5736 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5740 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5741 status = cli_ntcreate(cli1, fname, 0,
5742 FILE_READ_DATA|FILE_WRITE_DATA,
5743 open_attrs_table[j],
5744 FILE_SHARE_NONE, FILE_OVERWRITE,
5746 if (!NT_STATUS_IS_OK(status)) {
5747 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5748 if (attr_results[l].num == k) {
5749 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5750 k, open_attrs_table[i],
5751 open_attrs_table[j],
5752 fname, NT_STATUS_V(status), nt_errstr(status));
5757 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5758 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5759 k, open_attrs_table[i], open_attrs_table[j],
5764 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5770 status = cli_close(cli1, fnum1);
5771 if (!NT_STATUS_IS_OK(status)) {
5772 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5776 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5777 if (!NT_STATUS_IS_OK(status)) {
5778 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5783 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5784 k, open_attrs_table[i], open_attrs_table[j], attr );
5787 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5788 if (attr_results[l].num == k) {
5789 if (attr != attr_results[l].result_attr ||
5790 open_attrs_table[i] != attr_results[l].init_attr ||
5791 open_attrs_table[j] != attr_results[l].trunc_attr) {
5792 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5793 open_attrs_table[i],
5794 open_attrs_table[j],
5796 attr_results[l].result_attr);
5806 cli_setatr(cli1, fname, 0, 0);
5807 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5809 printf("open attr test %s.\n", correct ? "passed" : "failed");
5811 if (!torture_close_connection(cli1)) {
5817 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5818 const char *name, void *state)
5820 int *matched = (int *)state;
5821 if (matched != NULL) {
5824 return NT_STATUS_OK;
5828 test directory listing speed
5830 static bool run_dirtest(int dummy)
5833 static struct cli_state *cli;
5835 struct timeval core_start;
5836 bool correct = True;
5839 printf("starting directory test\n");
5841 if (!torture_open_connection(&cli, 0)) {
5845 cli_sockopt(cli, sockops);
5848 for (i=0;i<torture_numops;i++) {
5850 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5851 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5852 fprintf(stderr,"Failed to open %s\n", fname);
5855 cli_close(cli, fnum);
5858 core_start = timeval_current();
5861 cli_list(cli, "a*.*", 0, list_fn, &matched);
5862 printf("Matched %d\n", matched);
5865 cli_list(cli, "b*.*", 0, list_fn, &matched);
5866 printf("Matched %d\n", matched);
5869 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5870 printf("Matched %d\n", matched);
5872 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5875 for (i=0;i<torture_numops;i++) {
5877 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5878 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5881 if (!torture_close_connection(cli)) {
5885 printf("finished dirtest\n");
5890 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5893 struct cli_state *pcli = (struct cli_state *)state;
5895 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5897 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5898 return NT_STATUS_OK;
5900 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5901 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5902 printf("del_fn: failed to rmdir %s\n,", fname );
5904 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5905 printf("del_fn: failed to unlink %s\n,", fname );
5907 return NT_STATUS_OK;
5912 sees what IOCTLs are supported
5914 bool torture_ioctl_test(int dummy)
5916 static struct cli_state *cli;
5917 uint16_t device, function;
5919 const char *fname = "\\ioctl.dat";
5923 if (!torture_open_connection(&cli, 0)) {
5927 printf("starting ioctl test\n");
5929 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5931 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5932 if (!NT_STATUS_IS_OK(status)) {
5933 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5937 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5938 printf("ioctl device info: %s\n", nt_errstr(status));
5940 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5941 printf("ioctl job info: %s\n", nt_errstr(status));
5943 for (device=0;device<0x100;device++) {
5944 printf("ioctl test with device = 0x%x\n", device);
5945 for (function=0;function<0x100;function++) {
5946 uint32 code = (device<<16) | function;
5948 status = cli_raw_ioctl(cli, fnum, code, &blob);
5950 if (NT_STATUS_IS_OK(status)) {
5951 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5953 data_blob_free(&blob);
5958 if (!torture_close_connection(cli)) {
5967 tries varients of chkpath
5969 bool torture_chkpath_test(int dummy)
5971 static struct cli_state *cli;
5976 if (!torture_open_connection(&cli, 0)) {
5980 printf("starting chkpath test\n");
5982 /* cleanup from an old run */
5983 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5984 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5985 cli_rmdir(cli, "\\chkpath.dir");
5987 status = cli_mkdir(cli, "\\chkpath.dir");
5988 if (!NT_STATUS_IS_OK(status)) {
5989 printf("mkdir1 failed : %s\n", nt_errstr(status));
5993 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5994 if (!NT_STATUS_IS_OK(status)) {
5995 printf("mkdir2 failed : %s\n", nt_errstr(status));
5999 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6001 if (!NT_STATUS_IS_OK(status)) {
6002 printf("open1 failed (%s)\n", nt_errstr(status));
6005 cli_close(cli, fnum);
6007 status = cli_chkpath(cli, "\\chkpath.dir");
6008 if (!NT_STATUS_IS_OK(status)) {
6009 printf("chkpath1 failed: %s\n", nt_errstr(status));
6013 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6014 if (!NT_STATUS_IS_OK(status)) {
6015 printf("chkpath2 failed: %s\n", nt_errstr(status));
6019 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6020 if (!NT_STATUS_IS_OK(status)) {
6021 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6022 NT_STATUS_NOT_A_DIRECTORY);
6024 printf("* chkpath on a file should fail\n");
6028 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6029 if (!NT_STATUS_IS_OK(status)) {
6030 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6031 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6033 printf("* chkpath on a non existant file should fail\n");
6037 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6038 if (!NT_STATUS_IS_OK(status)) {
6039 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6040 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6042 printf("* chkpath on a non existent component should fail\n");
6046 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6047 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6048 cli_rmdir(cli, "\\chkpath.dir");
6050 if (!torture_close_connection(cli)) {
6057 static bool run_eatest(int dummy)
6059 static struct cli_state *cli;
6060 const char *fname = "\\eatest.txt";
6061 bool correct = True;
6065 struct ea_struct *ea_list = NULL;
6066 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6069 printf("starting eatest\n");
6071 if (!torture_open_connection(&cli, 0)) {
6072 talloc_destroy(mem_ctx);
6076 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6078 status = cli_ntcreate(cli, fname, 0,
6079 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6080 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6082 if (!NT_STATUS_IS_OK(status)) {
6083 printf("open failed - %s\n", nt_errstr(status));
6084 talloc_destroy(mem_ctx);
6088 for (i = 0; i < 10; i++) {
6089 fstring ea_name, ea_val;
6091 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6092 memset(ea_val, (char)i+1, i+1);
6093 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6094 if (!NT_STATUS_IS_OK(status)) {
6095 printf("ea_set of name %s failed - %s\n", ea_name,
6097 talloc_destroy(mem_ctx);
6102 cli_close(cli, fnum);
6103 for (i = 0; i < 10; i++) {
6104 fstring ea_name, ea_val;
6106 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6107 memset(ea_val, (char)i+1, i+1);
6108 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6109 if (!NT_STATUS_IS_OK(status)) {
6110 printf("ea_set of name %s failed - %s\n", ea_name,
6112 talloc_destroy(mem_ctx);
6117 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6118 if (!NT_STATUS_IS_OK(status)) {
6119 printf("ea_get list failed - %s\n", nt_errstr(status));
6123 printf("num_eas = %d\n", (int)num_eas);
6125 if (num_eas != 20) {
6126 printf("Should be 20 EA's stored... failing.\n");
6130 for (i = 0; i < num_eas; i++) {
6131 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6132 dump_data(0, ea_list[i].value.data,
6133 ea_list[i].value.length);
6136 /* Setting EA's to zero length deletes them. Test this */
6137 printf("Now deleting all EA's - case indepenent....\n");
6140 cli_set_ea_path(cli, fname, "", "", 0);
6142 for (i = 0; i < 20; i++) {
6144 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6145 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6146 if (!NT_STATUS_IS_OK(status)) {
6147 printf("ea_set of name %s failed - %s\n", ea_name,
6149 talloc_destroy(mem_ctx);
6155 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6156 if (!NT_STATUS_IS_OK(status)) {
6157 printf("ea_get list failed - %s\n", nt_errstr(status));
6161 printf("num_eas = %d\n", (int)num_eas);
6162 for (i = 0; i < num_eas; i++) {
6163 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6164 dump_data(0, ea_list[i].value.data,
6165 ea_list[i].value.length);
6169 printf("deleting EA's failed.\n");
6173 /* Try and delete a non existant EA. */
6174 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6175 if (!NT_STATUS_IS_OK(status)) {
6176 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6181 talloc_destroy(mem_ctx);
6182 if (!torture_close_connection(cli)) {
6189 static bool run_dirtest1(int dummy)
6192 static struct cli_state *cli;
6195 bool correct = True;
6197 printf("starting directory test\n");
6199 if (!torture_open_connection(&cli, 0)) {
6203 cli_sockopt(cli, sockops);
6205 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6206 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6207 cli_rmdir(cli, "\\LISTDIR");
6208 cli_mkdir(cli, "\\LISTDIR");
6210 /* Create 1000 files and 1000 directories. */
6211 for (i=0;i<1000;i++) {
6213 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6214 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6215 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6216 fprintf(stderr,"Failed to open %s\n", fname);
6219 cli_close(cli, fnum);
6221 for (i=0;i<1000;i++) {
6223 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6224 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6225 fprintf(stderr,"Failed to open %s\n", fname);
6230 /* Now ensure that doing an old list sees both files and directories. */
6232 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6233 printf("num_seen = %d\n", num_seen );
6234 /* We should see 100 files + 1000 directories + . and .. */
6235 if (num_seen != 2002)
6238 /* Ensure if we have the "must have" bits we only see the
6242 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6243 printf("num_seen = %d\n", num_seen );
6244 if (num_seen != 1002)
6248 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6249 printf("num_seen = %d\n", num_seen );
6250 if (num_seen != 1000)
6253 /* Delete everything. */
6254 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6255 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6256 cli_rmdir(cli, "\\LISTDIR");
6259 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6260 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6261 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6264 if (!torture_close_connection(cli)) {
6268 printf("finished dirtest1\n");
6273 static bool run_error_map_extract(int dummy) {
6275 static struct cli_state *c_dos;
6276 static struct cli_state *c_nt;
6288 /* NT-Error connection */
6290 if (!(c_nt = open_nbt_connection())) {
6294 c_nt->use_spnego = False;
6296 status = cli_negprot(c_nt);
6298 if (!NT_STATUS_IS_OK(status)) {
6299 printf("%s rejected the NT-error negprot (%s)\n", host,
6305 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6306 if (!NT_STATUS_IS_OK(status)) {
6307 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6311 /* DOS-Error connection */
6313 if (!(c_dos = open_nbt_connection())) {
6317 c_dos->use_spnego = False;
6318 c_dos->force_dos_errors = True;
6320 status = cli_negprot(c_dos);
6321 if (!NT_STATUS_IS_OK(status)) {
6322 printf("%s rejected the DOS-error negprot (%s)\n", host,
6324 cli_shutdown(c_dos);
6328 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6329 if (!NT_STATUS_IS_OK(status)) {
6330 printf("%s rejected the DOS-error initial session setup (%s)\n",
6331 host, nt_errstr(status));
6335 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6336 fstr_sprintf(user, "%X", error);
6338 status = cli_session_setup(c_nt, user,
6339 password, strlen(password),
6340 password, strlen(password),
6342 if (NT_STATUS_IS_OK(status)) {
6343 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6346 /* Case #1: 32-bit NT errors */
6347 if (cli_is_nt_error(c_nt)) {
6348 nt_status = cli_nt_error(c_nt);
6350 printf("/** Dos error on NT connection! (%s) */\n",
6352 nt_status = NT_STATUS(0xc0000000);
6355 status = cli_session_setup(c_dos, user,
6356 password, strlen(password),
6357 password, strlen(password),
6359 if (NT_STATUS_IS_OK(status)) {
6360 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6363 /* Case #1: 32-bit NT errors */
6364 if (!cli_is_dos_error(c_dos)) {
6365 printf("/** NT error on DOS connection! (%s) */\n",
6367 errnum = errclass = 0;
6369 cli_dos_error(c_dos, &errclass, &errnum);
6372 if (NT_STATUS_V(nt_status) != error) {
6373 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6374 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6375 get_nt_error_c_code(talloc_tos(), nt_status));
6378 printf("\t{%s,\t%s,\t%s},\n",
6379 smb_dos_err_class(errclass),
6380 smb_dos_err_name(errclass, errnum),
6381 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6386 static bool run_sesssetup_bench(int dummy)
6388 static struct cli_state *c;
6389 const char *fname = "\\file.dat";
6394 if (!torture_open_connection(&c, 0)) {
6398 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6399 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6400 FILE_DELETE_ON_CLOSE, 0, &fnum);
6401 if (!NT_STATUS_IS_OK(status)) {
6402 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6406 for (i=0; i<torture_numops; i++) {
6407 status = cli_session_setup(
6409 password, strlen(password),
6410 password, strlen(password),
6412 if (!NT_STATUS_IS_OK(status)) {
6413 d_printf("(%s) cli_session_setup failed: %s\n",
6414 __location__, nt_errstr(status));
6418 d_printf("\r%d ", (int)cli_state_get_uid(c));
6420 status = cli_ulogoff(c);
6421 if (!NT_STATUS_IS_OK(status)) {
6422 d_printf("(%s) cli_ulogoff failed: %s\n",
6423 __location__, nt_errstr(status));
6431 static bool subst_test(const char *str, const char *user, const char *domain,
6432 uid_t uid, gid_t gid, const char *expected)
6437 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6439 if (strcmp(subst, expected) != 0) {
6440 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6441 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6450 static void chain1_open_completion(struct tevent_req *req)
6454 status = cli_open_recv(req, &fnum);
6457 d_printf("cli_open_recv returned %s: %d\n",
6459 NT_STATUS_IS_OK(status) ? fnum : -1);
6462 static void chain1_write_completion(struct tevent_req *req)
6466 status = cli_write_andx_recv(req, &written);
6469 d_printf("cli_write_andx_recv returned %s: %d\n",
6471 NT_STATUS_IS_OK(status) ? (int)written : -1);
6474 static void chain1_close_completion(struct tevent_req *req)
6477 bool *done = (bool *)tevent_req_callback_data_void(req);
6479 status = cli_close_recv(req);
6484 d_printf("cli_close returned %s\n", nt_errstr(status));
6487 static bool run_chain1(int dummy)
6489 struct cli_state *cli1;
6490 struct event_context *evt = event_context_init(NULL);
6491 struct tevent_req *reqs[3], *smbreqs[3];
6493 const char *str = "foobar";
6496 printf("starting chain1 test\n");
6497 if (!torture_open_connection(&cli1, 0)) {
6501 cli_sockopt(cli1, sockops);
6503 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6504 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6505 if (reqs[0] == NULL) return false;
6506 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6509 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6510 (const uint8_t *)str, 0, strlen(str)+1,
6511 smbreqs, 1, &smbreqs[1]);
6512 if (reqs[1] == NULL) return false;
6513 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6515 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6516 if (reqs[2] == NULL) return false;
6517 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6519 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6520 if (!NT_STATUS_IS_OK(status)) {
6525 tevent_loop_once(evt);
6528 torture_close_connection(cli1);
6532 static void chain2_sesssetup_completion(struct tevent_req *req)
6535 status = cli_session_setup_guest_recv(req);
6536 d_printf("sesssetup returned %s\n", nt_errstr(status));
6539 static void chain2_tcon_completion(struct tevent_req *req)
6541 bool *done = (bool *)tevent_req_callback_data_void(req);
6543 status = cli_tcon_andx_recv(req);
6544 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6548 static bool run_chain2(int dummy)
6550 struct cli_state *cli1;
6551 struct event_context *evt = event_context_init(NULL);
6552 struct tevent_req *reqs[2], *smbreqs[2];
6556 printf("starting chain2 test\n");
6557 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6558 port_to_use, Undefined, 0);
6559 if (!NT_STATUS_IS_OK(status)) {
6563 cli_sockopt(cli1, sockops);
6565 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6567 if (reqs[0] == NULL) return false;
6568 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6570 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6571 "?????", NULL, 0, &smbreqs[1]);
6572 if (reqs[1] == NULL) return false;
6573 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6575 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6576 if (!NT_STATUS_IS_OK(status)) {
6581 tevent_loop_once(evt);
6584 torture_close_connection(cli1);
6589 struct torture_createdel_state {
6590 struct tevent_context *ev;
6591 struct cli_state *cli;
6594 static void torture_createdel_created(struct tevent_req *subreq);
6595 static void torture_createdel_closed(struct tevent_req *subreq);
6597 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6598 struct tevent_context *ev,
6599 struct cli_state *cli,
6602 struct tevent_req *req, *subreq;
6603 struct torture_createdel_state *state;
6605 req = tevent_req_create(mem_ctx, &state,
6606 struct torture_createdel_state);
6613 subreq = cli_ntcreate_send(
6614 state, ev, cli, name, 0,
6615 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6616 FILE_ATTRIBUTE_NORMAL,
6617 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6618 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6620 if (tevent_req_nomem(subreq, req)) {
6621 return tevent_req_post(req, ev);
6623 tevent_req_set_callback(subreq, torture_createdel_created, req);
6627 static void torture_createdel_created(struct tevent_req *subreq)
6629 struct tevent_req *req = tevent_req_callback_data(
6630 subreq, struct tevent_req);
6631 struct torture_createdel_state *state = tevent_req_data(
6632 req, struct torture_createdel_state);
6636 status = cli_ntcreate_recv(subreq, &fnum);
6637 TALLOC_FREE(subreq);
6638 if (!NT_STATUS_IS_OK(status)) {
6639 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6640 nt_errstr(status)));
6641 tevent_req_nterror(req, status);
6645 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6646 if (tevent_req_nomem(subreq, req)) {
6649 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6652 static void torture_createdel_closed(struct tevent_req *subreq)
6654 struct tevent_req *req = tevent_req_callback_data(
6655 subreq, struct tevent_req);
6658 status = cli_close_recv(subreq);
6659 if (!NT_STATUS_IS_OK(status)) {
6660 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6661 tevent_req_nterror(req, status);
6664 tevent_req_done(req);
6667 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6669 return tevent_req_simple_recv_ntstatus(req);
6672 struct torture_createdels_state {
6673 struct tevent_context *ev;
6674 struct cli_state *cli;
6675 const char *base_name;
6679 struct tevent_req **reqs;
6682 static void torture_createdels_done(struct tevent_req *subreq);
6684 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6685 struct tevent_context *ev,
6686 struct cli_state *cli,
6687 const char *base_name,
6691 struct tevent_req *req;
6692 struct torture_createdels_state *state;
6695 req = tevent_req_create(mem_ctx, &state,
6696 struct torture_createdels_state);
6702 state->base_name = talloc_strdup(state, base_name);
6703 if (tevent_req_nomem(state->base_name, req)) {
6704 return tevent_req_post(req, ev);
6706 state->num_files = MAX(num_parallel, num_files);
6708 state->received = 0;
6710 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6711 if (tevent_req_nomem(state->reqs, req)) {
6712 return tevent_req_post(req, ev);
6715 for (i=0; i<num_parallel; i++) {
6718 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6720 if (tevent_req_nomem(name, req)) {
6721 return tevent_req_post(req, ev);
6723 state->reqs[i] = torture_createdel_send(
6724 state->reqs, state->ev, state->cli, name);
6725 if (tevent_req_nomem(state->reqs[i], req)) {
6726 return tevent_req_post(req, ev);
6728 name = talloc_move(state->reqs[i], &name);
6729 tevent_req_set_callback(state->reqs[i],
6730 torture_createdels_done, req);
6736 static void torture_createdels_done(struct tevent_req *subreq)
6738 struct tevent_req *req = tevent_req_callback_data(
6739 subreq, struct tevent_req);
6740 struct torture_createdels_state *state = tevent_req_data(
6741 req, struct torture_createdels_state);
6742 size_t num_parallel = talloc_array_length(state->reqs);
6747 status = torture_createdel_recv(subreq);
6748 if (!NT_STATUS_IS_OK(status)){
6749 DEBUG(10, ("torture_createdel_recv returned %s\n",
6750 nt_errstr(status)));
6751 TALLOC_FREE(subreq);
6752 tevent_req_nterror(req, status);
6756 for (i=0; i<num_parallel; i++) {
6757 if (subreq == state->reqs[i]) {
6761 if (i == num_parallel) {
6762 DEBUG(10, ("received something we did not send\n"));
6763 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6766 TALLOC_FREE(state->reqs[i]);
6768 if (state->sent >= state->num_files) {
6769 tevent_req_done(req);
6773 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6775 if (tevent_req_nomem(name, req)) {
6778 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6780 if (tevent_req_nomem(state->reqs[i], req)) {
6783 name = talloc_move(state->reqs[i], &name);
6784 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6788 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6790 return tevent_req_simple_recv_ntstatus(req);
6793 struct swallow_notify_state {
6794 struct tevent_context *ev;
6795 struct cli_state *cli;
6797 uint32_t completion_filter;
6799 bool (*fn)(uint32_t action, const char *name, void *priv);
6803 static void swallow_notify_done(struct tevent_req *subreq);
6805 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6806 struct tevent_context *ev,
6807 struct cli_state *cli,
6809 uint32_t completion_filter,
6811 bool (*fn)(uint32_t action,
6816 struct tevent_req *req, *subreq;
6817 struct swallow_notify_state *state;
6819 req = tevent_req_create(mem_ctx, &state,
6820 struct swallow_notify_state);
6827 state->completion_filter = completion_filter;
6828 state->recursive = recursive;
6832 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6833 0xffff, state->completion_filter,
6835 if (tevent_req_nomem(subreq, req)) {
6836 return tevent_req_post(req, ev);
6838 tevent_req_set_callback(subreq, swallow_notify_done, req);
6842 static void swallow_notify_done(struct tevent_req *subreq)
6844 struct tevent_req *req = tevent_req_callback_data(
6845 subreq, struct tevent_req);
6846 struct swallow_notify_state *state = tevent_req_data(
6847 req, struct swallow_notify_state);
6849 uint32_t i, num_changes;
6850 struct notify_change *changes;
6852 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6853 TALLOC_FREE(subreq);
6854 if (!NT_STATUS_IS_OK(status)) {
6855 DEBUG(10, ("cli_notify_recv returned %s\n",
6856 nt_errstr(status)));
6857 tevent_req_nterror(req, status);
6861 for (i=0; i<num_changes; i++) {
6862 state->fn(changes[i].action, changes[i].name, state->priv);
6864 TALLOC_FREE(changes);
6866 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6867 0xffff, state->completion_filter,
6869 if (tevent_req_nomem(subreq, req)) {
6872 tevent_req_set_callback(subreq, swallow_notify_done, req);
6875 static bool print_notifies(uint32_t action, const char *name, void *priv)
6877 if (DEBUGLEVEL > 5) {
6878 d_printf("%d %s\n", (int)action, name);
6883 static void notify_bench_done(struct tevent_req *req)
6885 int *num_finished = (int *)tevent_req_callback_data_void(req);
6889 static bool run_notify_bench(int dummy)
6891 const char *dname = "\\notify-bench";
6892 struct tevent_context *ev;
6895 struct tevent_req *req1;
6896 struct tevent_req *req2 = NULL;
6897 int i, num_unc_names;
6898 int num_finished = 0;
6900 printf("starting notify-bench test\n");
6902 if (use_multishare_conn) {
6904 unc_list = file_lines_load(multishare_conn_fname,
6905 &num_unc_names, 0, NULL);
6906 if (!unc_list || num_unc_names <= 0) {
6907 d_printf("Failed to load unc names list from '%s'\n",
6908 multishare_conn_fname);
6911 TALLOC_FREE(unc_list);
6916 ev = tevent_context_init(talloc_tos());
6918 d_printf("tevent_context_init failed\n");
6922 for (i=0; i<num_unc_names; i++) {
6923 struct cli_state *cli;
6926 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6928 if (base_fname == NULL) {
6932 if (!torture_open_connection(&cli, i)) {
6936 status = cli_ntcreate(cli, dname, 0,
6937 MAXIMUM_ALLOWED_ACCESS,
6938 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6940 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6943 if (!NT_STATUS_IS_OK(status)) {
6944 d_printf("Could not create %s: %s\n", dname,
6949 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6950 FILE_NOTIFY_CHANGE_FILE_NAME |
6951 FILE_NOTIFY_CHANGE_DIR_NAME |
6952 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6953 FILE_NOTIFY_CHANGE_LAST_WRITE,
6954 false, print_notifies, NULL);
6956 d_printf("Could not create notify request\n");
6960 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6961 base_fname, 10, torture_numops);
6963 d_printf("Could not create createdels request\n");
6966 TALLOC_FREE(base_fname);
6968 tevent_req_set_callback(req2, notify_bench_done,
6972 while (num_finished < num_unc_names) {
6974 ret = tevent_loop_once(ev);
6976 d_printf("tevent_loop_once failed\n");
6981 if (!tevent_req_poll(req2, ev)) {
6982 d_printf("tevent_req_poll failed\n");
6985 status = torture_createdels_recv(req2);
6986 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6991 static bool run_mangle1(int dummy)
6993 struct cli_state *cli;
6994 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6998 time_t change_time, access_time, write_time;
7002 printf("starting mangle1 test\n");
7003 if (!torture_open_connection(&cli, 0)) {
7007 cli_sockopt(cli, sockops);
7009 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7010 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7012 if (!NT_STATUS_IS_OK(status)) {
7013 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7016 cli_close(cli, fnum);
7018 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7019 if (!NT_STATUS_IS_OK(status)) {
7020 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7024 d_printf("alt_name: %s\n", alt_name);
7026 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7027 if (!NT_STATUS_IS_OK(status)) {
7028 d_printf("cli_open(%s) failed: %s\n", alt_name,
7032 cli_close(cli, fnum);
7034 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7035 &write_time, &size, &mode);
7036 if (!NT_STATUS_IS_OK(status)) {
7037 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7045 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7047 size_t *to_pull = (size_t *)priv;
7048 size_t thistime = *to_pull;
7050 thistime = MIN(thistime, n);
7051 if (thistime == 0) {
7055 memset(buf, 0, thistime);
7056 *to_pull -= thistime;
7060 static bool run_windows_write(int dummy)
7062 struct cli_state *cli1;
7066 const char *fname = "\\writetest.txt";
7067 struct timeval start_time;
7072 printf("starting windows_write test\n");
7073 if (!torture_open_connection(&cli1, 0)) {
7077 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7078 if (!NT_STATUS_IS_OK(status)) {
7079 printf("open failed (%s)\n", nt_errstr(status));
7083 cli_sockopt(cli1, sockops);
7085 start_time = timeval_current();
7087 for (i=0; i<torture_numops; i++) {
7089 off_t start = i * torture_blocksize;
7090 size_t to_pull = torture_blocksize - 1;
7092 status = cli_writeall(cli1, fnum, 0, &c,
7093 start + torture_blocksize - 1, 1, NULL);
7094 if (!NT_STATUS_IS_OK(status)) {
7095 printf("cli_write failed: %s\n", nt_errstr(status));
7099 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7100 null_source, &to_pull);
7101 if (!NT_STATUS_IS_OK(status)) {
7102 printf("cli_push returned: %s\n", nt_errstr(status));
7107 seconds = timeval_elapsed(&start_time);
7108 kbytes = (double)torture_blocksize * torture_numops;
7111 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7112 (double)seconds, (int)(kbytes/seconds));
7116 cli_close(cli1, fnum);
7117 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7118 torture_close_connection(cli1);
7122 static bool run_cli_echo(int dummy)
7124 struct cli_state *cli;
7127 printf("starting cli_echo test\n");
7128 if (!torture_open_connection(&cli, 0)) {
7131 cli_sockopt(cli, sockops);
7133 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7135 d_printf("cli_echo returned %s\n", nt_errstr(status));
7137 torture_close_connection(cli);
7138 return NT_STATUS_IS_OK(status);
7141 static bool run_uid_regression_test(int dummy)
7143 static struct cli_state *cli;
7146 bool correct = True;
7149 printf("starting uid regression test\n");
7151 if (!torture_open_connection(&cli, 0)) {
7155 cli_sockopt(cli, sockops);
7157 /* Ok - now save then logoff our current user. */
7158 old_vuid = cli_state_get_uid(cli);
7160 status = cli_ulogoff(cli);
7161 if (!NT_STATUS_IS_OK(status)) {
7162 d_printf("(%s) cli_ulogoff failed: %s\n",
7163 __location__, nt_errstr(status));
7168 cli_state_set_uid(cli, old_vuid);
7170 /* Try an operation. */
7171 status = cli_mkdir(cli, "\\uid_reg_test");
7172 if (NT_STATUS_IS_OK(status)) {
7173 d_printf("(%s) cli_mkdir succeeded\n",
7178 /* Should be bad uid. */
7179 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7180 NT_STATUS_USER_SESSION_DELETED)) {
7186 old_cnum = cli_state_get_tid(cli);
7188 /* Now try a SMBtdis with the invald vuid set to zero. */
7189 cli_state_set_uid(cli, 0);
7191 /* This should succeed. */
7192 status = cli_tdis(cli);
7194 if (NT_STATUS_IS_OK(status)) {
7195 d_printf("First tdis with invalid vuid should succeed.\n");
7197 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7202 cli_state_set_uid(cli, old_vuid);
7203 cli_state_set_tid(cli, old_cnum);
7205 /* This should fail. */
7206 status = cli_tdis(cli);
7207 if (NT_STATUS_IS_OK(status)) {
7208 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7212 /* Should be bad tid. */
7213 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7214 NT_STATUS_NETWORK_NAME_DELETED)) {
7220 cli_rmdir(cli, "\\uid_reg_test");
7229 static const char *illegal_chars = "*\\/?<>|\":";
7230 static char force_shortname_chars[] = " +,.[];=\177";
7232 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7233 const char *mask, void *state)
7235 struct cli_state *pcli = (struct cli_state *)state;
7237 NTSTATUS status = NT_STATUS_OK;
7239 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7241 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7242 return NT_STATUS_OK;
7244 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7245 status = cli_rmdir(pcli, fname);
7246 if (!NT_STATUS_IS_OK(status)) {
7247 printf("del_fn: failed to rmdir %s\n,", fname );
7250 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7251 if (!NT_STATUS_IS_OK(status)) {
7252 printf("del_fn: failed to unlink %s\n,", fname );
7264 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7265 const char *name, void *state)
7267 struct sn_state *s = (struct sn_state *)state;
7271 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7272 i, finfo->name, finfo->short_name);
7275 if (strchr(force_shortname_chars, i)) {
7276 if (!finfo->short_name) {
7277 /* Shortname not created when it should be. */
7278 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7279 __location__, finfo->name, i);
7282 } else if (finfo->short_name){
7283 /* Shortname created when it should not be. */
7284 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7285 __location__, finfo->short_name, finfo->name);
7289 return NT_STATUS_OK;
7292 static bool run_shortname_test(int dummy)
7294 static struct cli_state *cli;
7295 bool correct = True;
7301 printf("starting shortname test\n");
7303 if (!torture_open_connection(&cli, 0)) {
7307 cli_sockopt(cli, sockops);
7309 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7310 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7311 cli_rmdir(cli, "\\shortname");
7313 status = cli_mkdir(cli, "\\shortname");
7314 if (!NT_STATUS_IS_OK(status)) {
7315 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7316 __location__, nt_errstr(status));
7321 strlcpy(fname, "\\shortname\\", sizeof(fname));
7322 strlcat(fname, "test .txt", sizeof(fname));
7326 for (i = 32; i < 128; i++) {
7327 uint16_t fnum = (uint16_t)-1;
7331 if (strchr(illegal_chars, i)) {
7336 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7337 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7338 if (!NT_STATUS_IS_OK(status)) {
7339 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7340 __location__, fname, nt_errstr(status));
7344 cli_close(cli, fnum);
7347 status = cli_list(cli, "\\shortname\\test*.*", 0,
7348 shortname_list_fn, &s);
7349 if (s.matched != 1) {
7350 d_printf("(%s) failed to list %s: %s\n",
7351 __location__, fname, nt_errstr(status));
7356 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7357 if (!NT_STATUS_IS_OK(status)) {
7358 d_printf("(%s) failed to delete %s: %s\n",
7359 __location__, fname, nt_errstr(status));
7372 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7373 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7374 cli_rmdir(cli, "\\shortname");
7375 torture_close_connection(cli);
7379 static void pagedsearch_cb(struct tevent_req *req)
7382 struct tldap_message *msg;
7385 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7386 if (rc != TLDAP_SUCCESS) {
7387 d_printf("tldap_search_paged_recv failed: %s\n",
7388 tldap_err2string(rc));
7391 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7395 if (!tldap_entry_dn(msg, &dn)) {
7396 d_printf("tldap_entry_dn failed\n");
7399 d_printf("%s\n", dn);
7403 static bool run_tldap(int dummy)
7405 struct tldap_context *ld;
7408 struct sockaddr_storage addr;
7409 struct tevent_context *ev;
7410 struct tevent_req *req;
7414 if (!resolve_name(host, &addr, 0, false)) {
7415 d_printf("could not find host %s\n", host);
7418 status = open_socket_out(&addr, 389, 9999, &fd);
7419 if (!NT_STATUS_IS_OK(status)) {
7420 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7424 ld = tldap_context_create(talloc_tos(), fd);
7427 d_printf("tldap_context_create failed\n");
7431 rc = tldap_fetch_rootdse(ld);
7432 if (rc != TLDAP_SUCCESS) {
7433 d_printf("tldap_fetch_rootdse failed: %s\n",
7434 tldap_errstr(talloc_tos(), ld, rc));
7438 basedn = tldap_talloc_single_attribute(
7439 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7440 if (basedn == NULL) {
7441 d_printf("no defaultNamingContext\n");
7444 d_printf("defaultNamingContext: %s\n", basedn);
7446 ev = tevent_context_init(talloc_tos());
7448 d_printf("tevent_context_init failed\n");
7452 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7453 TLDAP_SCOPE_SUB, "(objectclass=*)",
7455 NULL, 0, NULL, 0, 0, 0, 0, 5);
7457 d_printf("tldap_search_paged_send failed\n");
7460 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7462 tevent_req_poll(req, ev);
7466 /* test search filters against rootDSE */
7467 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7468 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7470 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7471 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7472 talloc_tos(), NULL, NULL);
7473 if (rc != TLDAP_SUCCESS) {
7474 d_printf("tldap_search with complex filter failed: %s\n",
7475 tldap_errstr(talloc_tos(), ld, rc));
7483 /* Torture test to ensure no regression of :
7484 https://bugzilla.samba.org/show_bug.cgi?id=7084
7487 static bool run_dir_createtime(int dummy)
7489 struct cli_state *cli;
7490 const char *dname = "\\testdir";
7491 const char *fname = "\\testdir\\testfile";
7493 struct timespec create_time;
7494 struct timespec create_time1;
7498 if (!torture_open_connection(&cli, 0)) {
7502 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7503 cli_rmdir(cli, dname);
7505 status = cli_mkdir(cli, dname);
7506 if (!NT_STATUS_IS_OK(status)) {
7507 printf("mkdir failed: %s\n", nt_errstr(status));
7511 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7513 if (!NT_STATUS_IS_OK(status)) {
7514 printf("cli_qpathinfo2 returned %s\n",
7519 /* Sleep 3 seconds, then create a file. */
7522 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7524 if (!NT_STATUS_IS_OK(status)) {
7525 printf("cli_open failed: %s\n", nt_errstr(status));
7529 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7531 if (!NT_STATUS_IS_OK(status)) {
7532 printf("cli_qpathinfo2 (2) returned %s\n",
7537 if (timespec_compare(&create_time1, &create_time)) {
7538 printf("run_dir_createtime: create time was updated (error)\n");
7540 printf("run_dir_createtime: create time was not updated (correct)\n");
7546 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7547 cli_rmdir(cli, dname);
7548 if (!torture_close_connection(cli)) {
7555 static bool run_streamerror(int dummy)
7557 struct cli_state *cli;
7558 const char *dname = "\\testdir";
7559 const char *streamname =
7560 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7562 time_t change_time, access_time, write_time;
7564 uint16_t mode, fnum;
7567 if (!torture_open_connection(&cli, 0)) {
7571 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7572 cli_rmdir(cli, dname);
7574 status = cli_mkdir(cli, dname);
7575 if (!NT_STATUS_IS_OK(status)) {
7576 printf("mkdir failed: %s\n", nt_errstr(status));
7580 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7582 status = cli_nt_error(cli);
7584 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7585 printf("pathinfo returned %s, expected "
7586 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7591 status = cli_ntcreate(cli, streamname, 0x16,
7592 FILE_READ_DATA|FILE_READ_EA|
7593 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7594 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7595 FILE_OPEN, 0, 0, &fnum);
7597 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7598 printf("ntcreate returned %s, expected "
7599 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7605 cli_rmdir(cli, dname);
7609 static bool run_local_substitute(int dummy)
7613 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7614 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7615 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7616 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7617 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7618 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7619 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7620 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7622 /* Different captialization rules in sub_basic... */
7624 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7630 static bool run_local_base64(int dummy)
7635 for (i=1; i<2000; i++) {
7636 DATA_BLOB blob1, blob2;
7639 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7641 generate_random_buffer(blob1.data, blob1.length);
7643 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7645 d_fprintf(stderr, "base64_encode_data_blob failed "
7646 "for %d bytes\n", i);
7649 blob2 = base64_decode_data_blob(b64);
7652 if (data_blob_cmp(&blob1, &blob2)) {
7653 d_fprintf(stderr, "data_blob_cmp failed for %d "
7657 TALLOC_FREE(blob1.data);
7658 data_blob_free(&blob2);
7663 static bool run_local_gencache(int dummy)
7669 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7670 d_printf("%s: gencache_set() failed\n", __location__);
7674 if (!gencache_get("foo", NULL, NULL)) {
7675 d_printf("%s: gencache_get() failed\n", __location__);
7679 if (!gencache_get("foo", &val, &tm)) {
7680 d_printf("%s: gencache_get() failed\n", __location__);
7684 if (strcmp(val, "bar") != 0) {
7685 d_printf("%s: gencache_get() returned %s, expected %s\n",
7686 __location__, val, "bar");
7693 if (!gencache_del("foo")) {
7694 d_printf("%s: gencache_del() failed\n", __location__);
7697 if (gencache_del("foo")) {
7698 d_printf("%s: second gencache_del() succeeded\n",
7703 if (gencache_get("foo", &val, &tm)) {
7704 d_printf("%s: gencache_get() on deleted entry "
7705 "succeeded\n", __location__);
7709 blob = data_blob_string_const_null("bar");
7710 tm = time(NULL) + 60;
7712 if (!gencache_set_data_blob("foo", &blob, tm)) {
7713 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7717 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7718 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7722 if (strcmp((const char *)blob.data, "bar") != 0) {
7723 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7724 __location__, (const char *)blob.data, "bar");
7725 data_blob_free(&blob);
7729 data_blob_free(&blob);
7731 if (!gencache_del("foo")) {
7732 d_printf("%s: gencache_del() failed\n", __location__);
7735 if (gencache_del("foo")) {
7736 d_printf("%s: second gencache_del() succeeded\n",
7741 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7742 d_printf("%s: gencache_get_data_blob() on deleted entry "
7743 "succeeded\n", __location__);
7750 static bool rbt_testval(struct db_context *db, const char *key,
7753 struct db_record *rec;
7754 TDB_DATA data = string_tdb_data(value);
7758 rec = db->fetch_locked(db, db, string_tdb_data(key));
7760 d_fprintf(stderr, "fetch_locked failed\n");
7763 status = rec->store(rec, data, 0);
7764 if (!NT_STATUS_IS_OK(status)) {
7765 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7770 rec = db->fetch_locked(db, db, string_tdb_data(key));
7772 d_fprintf(stderr, "second fetch_locked failed\n");
7775 if ((rec->value.dsize != data.dsize)
7776 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7777 d_fprintf(stderr, "Got wrong data back\n");
7787 static bool run_local_rbtree(int dummy)
7789 struct db_context *db;
7793 db = db_open_rbt(NULL);
7796 d_fprintf(stderr, "db_open_rbt failed\n");
7800 for (i=0; i<1000; i++) {
7803 if (asprintf(&key, "key%ld", random()) == -1) {
7806 if (asprintf(&value, "value%ld", random()) == -1) {
7811 if (!rbt_testval(db, key, value)) {
7818 if (asprintf(&value, "value%ld", random()) == -1) {
7823 if (!rbt_testval(db, key, value)) {
7842 local test for character set functions
7844 This is a very simple test for the functionality in convert_string_error()
7846 static bool run_local_convert_string(int dummy)
7848 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7849 const char *test_strings[2] = { "March", "M\303\244rz" };
7853 for (i=0; i<2; i++) {
7854 const char *str = test_strings[i];
7855 int len = strlen(str);
7856 size_t converted_size;
7859 memset(dst, 'X', sizeof(dst));
7861 /* first try with real source length */
7862 ret = convert_string_error(CH_UNIX, CH_UTF8,
7867 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7871 if (converted_size != len) {
7872 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7873 str, len, (int)converted_size);
7877 if (strncmp(str, dst, converted_size) != 0) {
7878 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7882 if (strlen(str) != converted_size) {
7883 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7884 (int)strlen(str), (int)converted_size);
7888 if (dst[converted_size] != 'X') {
7889 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7893 /* now with srclen==-1, this causes the nul to be
7895 ret = convert_string_error(CH_UNIX, CH_UTF8,
7900 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7904 if (converted_size != len+1) {
7905 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7906 str, len, (int)converted_size);
7910 if (strncmp(str, dst, converted_size) != 0) {
7911 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7915 if (len+1 != converted_size) {
7916 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7917 len+1, (int)converted_size);
7921 if (dst[converted_size] != 'X') {
7922 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7929 TALLOC_FREE(tmp_ctx);
7932 TALLOC_FREE(tmp_ctx);
7937 struct talloc_dict_test {
7941 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7943 int *count = (int *)priv;
7948 static bool run_local_talloc_dict(int dummy)
7950 struct talloc_dict *dict;
7951 struct talloc_dict_test *t;
7954 dict = talloc_dict_init(talloc_tos());
7959 t = talloc(talloc_tos(), struct talloc_dict_test);
7966 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7971 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7984 static bool run_local_string_to_sid(int dummy) {
7987 if (string_to_sid(&sid, "S--1-5-32-545")) {
7988 printf("allowing S--1-5-32-545\n");
7991 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7992 printf("allowing S-1-5-32-+545\n");
7995 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")) {
7996 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7999 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
8000 printf("allowing S-1-5-32-545-abc\n");
8003 if (!string_to_sid(&sid, "S-1-5-32-545")) {
8004 printf("could not parse S-1-5-32-545\n");
8007 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8008 printf("mis-parsed S-1-5-32-545 as %s\n",
8009 sid_string_tos(&sid));
8015 static bool run_local_binary_to_sid(int dummy) {
8016 struct dom_sid *sid = talloc(NULL, struct dom_sid);
8017 static const char good_binary_sid[] = {
8018 0x1, /* revision number */
8020 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8021 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8022 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8023 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8024 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8025 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8026 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8027 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8028 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8029 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8030 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8031 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8032 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8033 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8034 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8035 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8038 static const char long_binary_sid[] = {
8039 0x1, /* revision number */
8041 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8042 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8043 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8044 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8045 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8046 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8047 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8048 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8049 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8050 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8051 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8052 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8053 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8054 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8055 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8056 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8057 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8058 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8059 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8062 static const char long_binary_sid2[] = {
8063 0x1, /* revision number */
8065 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8066 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8067 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8068 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8069 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8070 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8071 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8072 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8073 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8074 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8075 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8076 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8077 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8078 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8079 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8080 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8081 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8082 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8083 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8084 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8100 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8103 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8106 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8112 /* Split a path name into filename and stream name components. Canonicalise
8113 * such that an implicit $DATA token is always explicit.
8115 * The "specification" of this function can be found in the
8116 * run_local_stream_name() function in torture.c, I've tried those
8117 * combinations against a W2k3 server.
8120 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8121 char **pbase, char **pstream)
8124 char *stream = NULL;
8125 char *sname; /* stream name */
8126 const char *stype; /* stream type */
8128 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8130 sname = strchr_m(fname, ':');
8132 if (lp_posix_pathnames() || (sname == NULL)) {
8133 if (pbase != NULL) {
8134 base = talloc_strdup(mem_ctx, fname);
8135 NT_STATUS_HAVE_NO_MEMORY(base);
8140 if (pbase != NULL) {
8141 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8142 NT_STATUS_HAVE_NO_MEMORY(base);
8147 stype = strchr_m(sname, ':');
8149 if (stype == NULL) {
8150 sname = talloc_strdup(mem_ctx, sname);
8154 if (strcasecmp_m(stype, ":$DATA") != 0) {
8156 * If there is an explicit stream type, so far we only
8157 * allow $DATA. Is there anything else allowed? -- vl
8159 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8161 return NT_STATUS_OBJECT_NAME_INVALID;
8163 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8167 if (sname == NULL) {
8169 return NT_STATUS_NO_MEMORY;
8172 if (sname[0] == '\0') {
8174 * no stream name, so no stream
8179 if (pstream != NULL) {
8180 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8181 if (stream == NULL) {
8184 return NT_STATUS_NO_MEMORY;
8187 * upper-case the type field
8189 strupper_m(strchr_m(stream, ':')+1);
8193 if (pbase != NULL) {
8196 if (pstream != NULL) {
8199 return NT_STATUS_OK;
8202 static bool test_stream_name(const char *fname, const char *expected_base,
8203 const char *expected_stream,
8204 NTSTATUS expected_status)
8208 char *stream = NULL;
8210 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8211 if (!NT_STATUS_EQUAL(status, expected_status)) {
8215 if (!NT_STATUS_IS_OK(status)) {
8219 if (base == NULL) goto error;
8221 if (strcmp(expected_base, base) != 0) goto error;
8223 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8224 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8226 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8230 TALLOC_FREE(stream);
8234 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8235 fname, expected_base ? expected_base : "<NULL>",
8236 expected_stream ? expected_stream : "<NULL>",
8237 nt_errstr(expected_status));
8238 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8239 base ? base : "<NULL>", stream ? stream : "<NULL>",
8242 TALLOC_FREE(stream);
8246 static bool run_local_stream_name(int dummy)
8250 ret &= test_stream_name(
8251 "bla", "bla", NULL, NT_STATUS_OK);
8252 ret &= test_stream_name(
8253 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8254 ret &= test_stream_name(
8255 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8256 ret &= test_stream_name(
8257 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8258 ret &= test_stream_name(
8259 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8260 ret &= test_stream_name(
8261 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8262 ret &= test_stream_name(
8263 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8264 ret &= test_stream_name(
8265 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8270 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8272 if (a.length != b.length) {
8273 printf("a.length=%d != b.length=%d\n",
8274 (int)a.length, (int)b.length);
8277 if (memcmp(a.data, b.data, a.length) != 0) {
8278 printf("a.data and b.data differ\n");
8284 static bool run_local_memcache(int dummy)
8286 struct memcache *cache;
8288 DATA_BLOB d1, d2, d3;
8289 DATA_BLOB v1, v2, v3;
8291 TALLOC_CTX *mem_ctx;
8293 size_t size1, size2;
8296 cache = memcache_init(NULL, 100);
8298 if (cache == NULL) {
8299 printf("memcache_init failed\n");
8303 d1 = data_blob_const("d1", 2);
8304 d2 = data_blob_const("d2", 2);
8305 d3 = data_blob_const("d3", 2);
8307 k1 = data_blob_const("d1", 2);
8308 k2 = data_blob_const("d2", 2);
8310 memcache_add(cache, STAT_CACHE, k1, d1);
8311 memcache_add(cache, GETWD_CACHE, k2, d2);
8313 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8314 printf("could not find k1\n");
8317 if (!data_blob_equal(d1, v1)) {
8321 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8322 printf("could not find k2\n");
8325 if (!data_blob_equal(d2, v2)) {
8329 memcache_add(cache, STAT_CACHE, k1, d3);
8331 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8332 printf("could not find replaced k1\n");
8335 if (!data_blob_equal(d3, v3)) {
8339 memcache_add(cache, GETWD_CACHE, k1, d1);
8341 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8342 printf("Did find k2, should have been purged\n");
8348 cache = memcache_init(NULL, 0);
8350 mem_ctx = talloc_init("foo");
8352 str1 = talloc_strdup(mem_ctx, "string1");
8353 str2 = talloc_strdup(mem_ctx, "string2");
8355 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8356 data_blob_string_const("torture"), &str1);
8357 size1 = talloc_total_size(cache);
8359 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8360 data_blob_string_const("torture"), &str2);
8361 size2 = talloc_total_size(cache);
8363 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8365 if (size2 > size1) {
8366 printf("memcache leaks memory!\n");
8376 static void wbclient_done(struct tevent_req *req)
8379 struct winbindd_response *wb_resp;
8380 int *i = (int *)tevent_req_callback_data_void(req);
8382 wbc_err = wb_trans_recv(req, req, &wb_resp);
8385 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8388 static bool run_local_wbclient(int dummy)
8390 struct event_context *ev;
8391 struct wb_context **wb_ctx;
8392 struct winbindd_request wb_req;
8393 bool result = false;
8396 BlockSignals(True, SIGPIPE);
8398 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8403 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8404 if (wb_ctx == NULL) {
8408 ZERO_STRUCT(wb_req);
8409 wb_req.cmd = WINBINDD_PING;
8411 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8413 for (i=0; i<nprocs; i++) {
8414 wb_ctx[i] = wb_context_init(ev, NULL);
8415 if (wb_ctx[i] == NULL) {
8418 for (j=0; j<torture_numops; j++) {
8419 struct tevent_req *req;
8420 req = wb_trans_send(ev, ev, wb_ctx[i],
8421 (j % 2) == 0, &wb_req);
8425 tevent_req_set_callback(req, wbclient_done, &i);
8431 while (i < nprocs * torture_numops) {
8432 tevent_loop_once(ev);
8441 static void getaddrinfo_finished(struct tevent_req *req)
8443 char *name = (char *)tevent_req_callback_data_void(req);
8444 struct addrinfo *ainfo;
8447 res = getaddrinfo_recv(req, &ainfo);
8449 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8452 d_printf("gai(%s) succeeded\n", name);
8453 freeaddrinfo(ainfo);
8456 static bool run_getaddrinfo_send(int dummy)
8458 TALLOC_CTX *frame = talloc_stackframe();
8459 struct fncall_context *ctx;
8460 struct tevent_context *ev;
8461 bool result = false;
8462 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8463 "www.slashdot.org", "heise.de" };
8464 struct tevent_req *reqs[4];
8467 ev = event_context_init(frame);
8472 ctx = fncall_context_init(frame, 4);
8474 for (i=0; i<ARRAY_SIZE(names); i++) {
8475 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8477 if (reqs[i] == NULL) {
8480 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8481 discard_const_p(void, names[i]));
8484 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8485 tevent_loop_once(ev);
8494 static bool dbtrans_inc(struct db_context *db)
8496 struct db_record *rec;
8501 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8503 printf(__location__ "fetch_lock failed\n");
8507 if (rec->value.dsize != sizeof(uint32_t)) {
8508 printf(__location__ "value.dsize = %d\n",
8509 (int)rec->value.dsize);
8513 val = (uint32_t *)rec->value.dptr;
8516 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8519 if (!NT_STATUS_IS_OK(status)) {
8520 printf(__location__ "store failed: %s\n",
8531 static bool run_local_dbtrans(int dummy)
8533 struct db_context *db;
8534 struct db_record *rec;
8539 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8540 O_RDWR|O_CREAT, 0600);
8542 printf("Could not open transtest.db\n");
8546 res = db->transaction_start(db);
8548 printf(__location__ "transaction_start failed\n");
8552 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8554 printf(__location__ "fetch_lock failed\n");
8558 if (rec->value.dptr == NULL) {
8560 status = rec->store(
8561 rec, make_tdb_data((uint8_t *)&initial,
8564 if (!NT_STATUS_IS_OK(status)) {
8565 printf(__location__ "store returned %s\n",
8573 res = db->transaction_commit(db);
8575 printf(__location__ "transaction_commit failed\n");
8583 res = db->transaction_start(db);
8585 printf(__location__ "transaction_start failed\n");
8589 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8590 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8594 for (i=0; i<10; i++) {
8595 if (!dbtrans_inc(db)) {
8600 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8601 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8605 if (val2 != val + 10) {
8606 printf(__location__ "val=%d, val2=%d\n",
8607 (int)val, (int)val2);
8611 printf("val2=%d\r", val2);
8613 res = db->transaction_commit(db);
8615 printf(__location__ "transaction_commit failed\n");
8625 * Just a dummy test to be run under a debugger. There's no real way
8626 * to inspect the tevent_select specific function from outside of
8630 static bool run_local_tevent_select(int dummy)
8632 struct tevent_context *ev;
8633 struct tevent_fd *fd1, *fd2;
8634 bool result = false;
8636 ev = tevent_context_init_byname(NULL, "select");
8638 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8642 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8644 d_fprintf(stderr, "tevent_add_fd failed\n");
8647 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8649 d_fprintf(stderr, "tevent_add_fd failed\n");
8654 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8656 d_fprintf(stderr, "tevent_add_fd failed\n");
8666 static double create_procs(bool (*fn)(int), bool *result)
8669 volatile pid_t *child_status;
8670 volatile bool *child_status_out;
8673 struct timeval start;
8677 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8678 if (!child_status) {
8679 printf("Failed to setup shared memory\n");
8683 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8684 if (!child_status_out) {
8685 printf("Failed to setup result status shared memory\n");
8689 for (i = 0; i < nprocs; i++) {
8690 child_status[i] = 0;
8691 child_status_out[i] = True;
8694 start = timeval_current();
8696 for (i=0;i<nprocs;i++) {
8699 pid_t mypid = getpid();
8700 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8702 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8705 if (torture_open_connection(¤t_cli, i)) break;
8707 printf("pid %d failed to start\n", (int)getpid());
8713 child_status[i] = getpid();
8715 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8717 child_status_out[i] = fn(i);
8724 for (i=0;i<nprocs;i++) {
8725 if (child_status[i]) synccount++;
8727 if (synccount == nprocs) break;
8729 } while (timeval_elapsed(&start) < 30);
8731 if (synccount != nprocs) {
8732 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8734 return timeval_elapsed(&start);
8737 /* start the client load */
8738 start = timeval_current();
8740 for (i=0;i<nprocs;i++) {
8741 child_status[i] = 0;
8744 printf("%d clients started\n", nprocs);
8746 for (i=0;i<nprocs;i++) {
8747 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8752 for (i=0;i<nprocs;i++) {
8753 if (!child_status_out[i]) {
8757 return timeval_elapsed(&start);
8760 #define FLAG_MULTIPROC 1
8767 {"FDPASS", run_fdpasstest, 0},
8768 {"LOCK1", run_locktest1, 0},
8769 {"LOCK2", run_locktest2, 0},
8770 {"LOCK3", run_locktest3, 0},
8771 {"LOCK4", run_locktest4, 0},
8772 {"LOCK5", run_locktest5, 0},
8773 {"LOCK6", run_locktest6, 0},
8774 {"LOCK7", run_locktest7, 0},
8775 {"LOCK8", run_locktest8, 0},
8776 {"LOCK9", run_locktest9, 0},
8777 {"UNLINK", run_unlinktest, 0},
8778 {"BROWSE", run_browsetest, 0},
8779 {"ATTR", run_attrtest, 0},
8780 {"TRANS2", run_trans2test, 0},
8781 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8782 {"TORTURE",run_torture, FLAG_MULTIPROC},
8783 {"RANDOMIPC", run_randomipc, 0},
8784 {"NEGNOWAIT", run_negprot_nowait, 0},
8785 {"NBENCH", run_nbench, 0},
8786 {"NBENCH2", run_nbench2, 0},
8787 {"OPLOCK1", run_oplock1, 0},
8788 {"OPLOCK2", run_oplock2, 0},
8789 {"OPLOCK4", run_oplock4, 0},
8790 {"DIR", run_dirtest, 0},
8791 {"DIR1", run_dirtest1, 0},
8792 {"DIR-CREATETIME", run_dir_createtime, 0},
8793 {"DENY1", torture_denytest1, 0},
8794 {"DENY2", torture_denytest2, 0},
8795 {"TCON", run_tcon_test, 0},
8796 {"TCONDEV", run_tcon_devtype_test, 0},
8797 {"RW1", run_readwritetest, 0},
8798 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8799 {"RW3", run_readwritelarge, 0},
8800 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8801 {"OPEN", run_opentest, 0},
8802 {"POSIX", run_simple_posix_open_test, 0},
8803 {"POSIX-APPEND", run_posix_append, 0},
8804 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8805 {"ASYNC-ECHO", run_async_echo, 0},
8806 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8807 { "SHORTNAME-TEST", run_shortname_test, 0},
8808 { "ADDRCHANGE", run_addrchange, 0},
8810 {"OPENATTR", run_openattrtest, 0},
8812 {"XCOPY", run_xcopy, 0},
8813 {"RENAME", run_rename, 0},
8814 {"DELETE", run_deletetest, 0},
8815 {"DELETE-LN", run_deletetest_ln, 0},
8816 {"PROPERTIES", run_properties, 0},
8817 {"MANGLE", torture_mangle, 0},
8818 {"MANGLE1", run_mangle1, 0},
8819 {"W2K", run_w2ktest, 0},
8820 {"TRANS2SCAN", torture_trans2_scan, 0},
8821 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8822 {"UTABLE", torture_utable, 0},
8823 {"CASETABLE", torture_casetable, 0},
8824 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8825 {"PIPE_NUMBER", run_pipe_number, 0},
8826 {"TCON2", run_tcon2_test, 0},
8827 {"IOCTL", torture_ioctl_test, 0},
8828 {"CHKPATH", torture_chkpath_test, 0},
8829 {"FDSESS", run_fdsesstest, 0},
8830 { "EATEST", run_eatest, 0},
8831 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8832 { "CHAIN1", run_chain1, 0},
8833 { "CHAIN2", run_chain2, 0},
8834 { "WINDOWS-WRITE", run_windows_write, 0},
8835 { "NTTRANS-CREATE", run_nttrans_create, 0},
8836 { "CLI_ECHO", run_cli_echo, 0},
8837 { "GETADDRINFO", run_getaddrinfo_send, 0},
8838 { "TLDAP", run_tldap },
8839 { "STREAMERROR", run_streamerror },
8840 { "NOTIFY-BENCH", run_notify_bench },
8841 { "BAD-NBT-SESSION", run_bad_nbt_session },
8842 { "SMB-ANY-CONNECT", run_smb_any_connect },
8843 { "NOTIFY-ONLINE", run_notify_online },
8844 { "SMB2-BASIC", run_smb2_basic },
8845 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8846 { "LOCAL-GENCACHE", run_local_gencache, 0},
8847 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8848 { "LOCAL-BASE64", run_local_base64, 0},
8849 { "LOCAL-RBTREE", run_local_rbtree, 0},
8850 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8851 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8852 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8853 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8854 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8855 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8856 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8857 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8862 /****************************************************************************
8863 run a specified test or "ALL"
8864 ****************************************************************************/
8865 static bool run_test(const char *name)
8872 if (strequal(name,"ALL")) {
8873 for (i=0;torture_ops[i].name;i++) {
8874 run_test(torture_ops[i].name);
8879 for (i=0;torture_ops[i].name;i++) {
8880 fstr_sprintf(randomfname, "\\XX%x",
8881 (unsigned)random());
8883 if (strequal(name, torture_ops[i].name)) {
8885 printf("Running %s\n", name);
8886 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8887 t = create_procs(torture_ops[i].fn, &result);
8890 printf("TEST %s FAILED!\n", name);
8893 struct timeval start;
8894 start = timeval_current();
8895 if (!torture_ops[i].fn(0)) {
8897 printf("TEST %s FAILED!\n", name);
8899 t = timeval_elapsed(&start);
8901 printf("%s took %g secs\n\n", name, t);
8906 printf("Did not find a test named %s\n", name);
8914 static void usage(void)
8918 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8919 printf("Please use samba4 torture.\n\n");
8921 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8923 printf("\t-d debuglevel\n");
8924 printf("\t-U user%%pass\n");
8925 printf("\t-k use kerberos\n");
8926 printf("\t-N numprocs\n");
8927 printf("\t-n my_netbios_name\n");
8928 printf("\t-W workgroup\n");
8929 printf("\t-o num_operations\n");
8930 printf("\t-O socket_options\n");
8931 printf("\t-m maximum protocol\n");
8932 printf("\t-L use oplocks\n");
8933 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8934 printf("\t-A showall\n");
8935 printf("\t-p port\n");
8936 printf("\t-s seed\n");
8937 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8938 printf("\t-f filename filename to test\n");
8941 printf("tests are:");
8942 for (i=0;torture_ops[i].name;i++) {
8943 printf(" %s", torture_ops[i].name);
8947 printf("default test is ALL\n");
8952 /****************************************************************************
8954 ****************************************************************************/
8955 int main(int argc,char *argv[])
8961 bool correct = True;
8962 TALLOC_CTX *frame = talloc_stackframe();
8963 int seed = time(NULL);
8965 #ifdef HAVE_SETBUFFER
8966 setbuffer(stdout, NULL, 0);
8969 setup_logging("smbtorture", DEBUG_STDOUT);
8973 if (is_default_dyn_CONFIGFILE()) {
8974 if(getenv("SMB_CONF_PATH")) {
8975 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8978 lp_load_global(get_dyn_CONFIGFILE());
8985 for(p = argv[1]; *p; p++)
8989 if (strncmp(argv[1], "//", 2)) {
8993 fstrcpy(host, &argv[1][2]);
8994 p = strchr_m(&host[2],'/');
8999 fstrcpy(share, p+1);
9001 fstrcpy(myname, get_myname(talloc_tos()));
9003 fprintf(stderr, "Failed to get my hostname.\n");
9007 if (*username == 0 && getenv("LOGNAME")) {
9008 fstrcpy(username,getenv("LOGNAME"));
9014 fstrcpy(workgroup, lp_workgroup());
9016 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9020 port_to_use = atoi(optarg);
9023 seed = atoi(optarg);
9026 fstrcpy(workgroup,optarg);
9029 max_protocol = interpret_protocol(optarg, max_protocol);
9032 nprocs = atoi(optarg);
9035 torture_numops = atoi(optarg);
9038 lp_set_cmdline("log level", optarg);
9047 local_path = optarg;
9050 torture_showall = True;
9053 fstrcpy(myname, optarg);
9056 client_txt = optarg;
9063 use_kerberos = True;
9065 d_printf("No kerberos support compiled in\n");
9071 fstrcpy(username,optarg);
9072 p = strchr_m(username,'%');
9075 fstrcpy(password, p+1);
9080 fstrcpy(multishare_conn_fname, optarg);
9081 use_multishare_conn = True;
9084 torture_blocksize = atoi(optarg);
9087 test_filename = SMB_STRDUP(optarg);
9090 printf("Unknown option %c (%d)\n", (char)opt, opt);
9095 d_printf("using seed %d\n", seed);
9099 if(use_kerberos && !gotuser) gotpass = True;
9102 p = getpass("Password:");
9104 fstrcpy(password, p);
9109 printf("host=%s share=%s user=%s myname=%s\n",
9110 host, share, username, myname);
9112 if (argc == optind) {
9113 correct = run_test("ALL");
9115 for (i=optind;i<argc;i++) {
9116 if (!run_test(argv[i])) {