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"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/libsmb.h"
35 #include "libsmb/clirap.h"
37 #include "libsmb/nmblib.h"
38 #include "../lib/util/tevent_ntstatus.h"
40 #include "libsmb/read_smb.h"
45 fstring host, workgroup, share, password, username, myname;
46 static int max_protocol = PROTOCOL_NT1;
47 static const char *sockops="TCP_NODELAY";
49 static int port_to_use=0;
50 int torture_numops=100;
51 int torture_blocksize=1024*1024;
52 static int procnum; /* records process count number when forking */
53 static struct cli_state *current_cli;
54 static fstring randomfname;
55 static bool use_oplocks;
56 static bool use_level_II_oplocks;
57 static const char *client_txt = "client_oplocks.txt";
58 static bool use_kerberos;
59 static fstring multishare_conn_fname;
60 static bool use_multishare_conn = False;
61 static bool do_encrypt;
62 static const char *local_path = NULL;
63 static int signing_state = Undefined;
66 bool torture_showall = False;
68 static double create_procs(bool (*fn)(int), bool *result);
71 /* return a pointer to a anonymous shared memory segment of size "size"
72 which will persist across fork() but will disappear when all processes
75 The memory is not zeroed
77 This function uses system5 shared memory. It takes advantage of a property
78 that the memory is not destroyed if it is attached when the id is removed
80 void *shm_setup(int size)
86 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
88 printf("can't get shared memory\n");
91 shm_unlink("private");
92 if (ftruncate(shmid, size) == -1) {
93 printf("can't set shared memory size\n");
96 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
97 if (ret == MAP_FAILED) {
98 printf("can't map shared memory\n");
102 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
104 printf("can't get shared memory\n");
107 ret = (void *)shmat(shmid, 0, 0);
108 if (!ret || ret == (void *)-1) {
109 printf("can't attach to shared memory\n");
112 /* the following releases the ipc, but note that this process
113 and all its children will still have access to the memory, its
114 just that the shmid is no longer valid for other shm calls. This
115 means we don't leave behind lots of shm segments after we exit
117 See Stevens "advanced programming in unix env" for details
119 shmctl(shmid, IPC_RMID, 0);
125 /********************************************************************
126 Ensure a connection is encrypted.
127 ********************************************************************/
129 static bool force_cli_encryption(struct cli_state *c,
130 const char *sharename)
133 uint32 caplow, caphigh;
136 if (!SERVER_HAS_UNIX_CIFS(c)) {
137 d_printf("Encryption required and "
138 "server that doesn't support "
139 "UNIX extensions - failing connect\n");
143 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
145 if (!NT_STATUS_IS_OK(status)) {
146 d_printf("Encryption required and "
147 "can't get UNIX CIFS extensions "
148 "version from server: %s\n", nt_errstr(status));
152 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
153 d_printf("Encryption required and "
154 "share %s doesn't support "
155 "encryption.\n", sharename);
159 if (c->use_kerberos) {
160 status = cli_gss_smb_encryption_start(c);
162 status = cli_raw_ntlm_smb_encryption_start(c,
168 if (!NT_STATUS_IS_OK(status)) {
169 d_printf("Encryption required and "
170 "setup failed with error %s.\n",
179 static struct cli_state *open_nbt_connection(void)
184 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
186 if (!NT_STATUS_IS_OK(status)) {
187 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191 c->use_kerberos = use_kerberos;
193 c->timeout = 120000; /* set a really long timeout (2 minutes) */
194 if (use_oplocks) c->use_oplocks = True;
195 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
200 /****************************************************************************
201 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
202 ****************************************************************************/
204 static bool cli_bad_session_request(int fd,
205 struct nmb_name *calling, struct nmb_name *called)
214 uint8_t message_type;
217 frame = talloc_stackframe();
219 iov[0].iov_base = len_buf;
220 iov[0].iov_len = sizeof(len_buf);
222 /* put in the destination name */
224 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
226 if (iov[1].iov_base == NULL) {
229 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
230 talloc_get_size(iov[1].iov_base));
234 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
236 if (iov[2].iov_base == NULL) {
239 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
240 talloc_get_size(iov[2].iov_base));
242 /* Deliberately corrupt the name len (first byte) */
243 *((uint8_t *)iov[2].iov_base) = 100;
245 /* send a session request (RFC 1002) */
246 /* setup the packet length
247 * Remove four bytes from the length count, since the length
248 * field in the NBT Session Service header counts the number
249 * of bytes which follow. The cli_send_smb() function knows
250 * about this and accounts for those four bytes.
254 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
255 SCVAL(len_buf,0,0x81);
257 len = write_data_iov(fd, iov, 3);
261 len = read_smb(fd, talloc_tos(), &inbuf, &err);
267 message_type = CVAL(inbuf, 0);
268 if (message_type != 0x83) {
269 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
274 if (smb_len(inbuf) != 1) {
275 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
276 (int)smb_len(inbuf));
280 error = CVAL(inbuf, 4);
282 d_fprintf(stderr, "Expected error 0x82, got %d\n",
293 /* Insert a NULL at the first separator of the given path and return a pointer
294 * to the remainder of the string.
297 terminate_path_at_separator(char * path)
305 if ((p = strchr_m(path, '/'))) {
310 if ((p = strchr_m(path, '\\'))) {
320 parse a //server/share type UNC name
322 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
323 char **hostname, char **sharename)
327 *hostname = *sharename = NULL;
329 if (strncmp(unc_name, "\\\\", 2) &&
330 strncmp(unc_name, "//", 2)) {
334 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
335 p = terminate_path_at_separator(*hostname);
338 *sharename = talloc_strdup(mem_ctx, p);
339 terminate_path_at_separator(*sharename);
342 if (*hostname && *sharename) {
346 TALLOC_FREE(*hostname);
347 TALLOC_FREE(*sharename);
351 static bool torture_open_connection_share(struct cli_state **c,
352 const char *hostname,
353 const char *sharename)
359 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
361 flags |= CLI_FULL_CONNECTION_OPLOCKS;
362 if (use_level_II_oplocks)
363 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
365 status = cli_full_connection(c, myname,
366 hostname, NULL, port_to_use,
369 password, flags, signing_state);
370 if (!NT_STATUS_IS_OK(status)) {
371 printf("failed to open share connection: //%s/%s port:%d - %s\n",
372 hostname, sharename, port_to_use, nt_errstr(status));
376 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
379 return force_cli_encryption(*c,
385 bool torture_open_connection(struct cli_state **c, int conn_index)
387 char **unc_list = NULL;
388 int num_unc_names = 0;
391 if (use_multishare_conn==True) {
393 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
394 if (!unc_list || num_unc_names <= 0) {
395 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
399 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
401 printf("Failed to parse UNC name %s\n",
402 unc_list[conn_index % num_unc_names]);
403 TALLOC_FREE(unc_list);
407 result = torture_open_connection_share(c, h, s);
409 /* h, s were copied earlier */
410 TALLOC_FREE(unc_list);
414 return torture_open_connection_share(c, host, share);
417 bool torture_init_connection(struct cli_state **pcli)
419 struct cli_state *cli;
421 cli = open_nbt_connection();
430 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
432 uint16 old_vuid = cli->vuid;
433 fstring old_user_name;
434 size_t passlen = strlen(password);
438 fstrcpy(old_user_name, cli->user_name);
440 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
444 *new_vuid = cli->vuid;
445 cli->vuid = old_vuid;
446 status = cli_set_username(cli, old_user_name);
447 if (!NT_STATUS_IS_OK(status)) {
454 bool torture_close_connection(struct cli_state *c)
459 status = cli_tdis(c);
460 if (!NT_STATUS_IS_OK(status)) {
461 printf("tdis failed (%s)\n", nt_errstr(status));
471 /* check if the server produced the expected dos or nt error code */
472 static bool check_both_error(int line, NTSTATUS status,
473 uint8 eclass, uint32 ecode, NTSTATUS nterr)
475 if (NT_STATUS_IS_DOS(status)) {
479 /* Check DOS error */
480 cclass = NT_STATUS_DOS_CLASS(status);
481 num = NT_STATUS_DOS_CODE(status);
483 if (eclass != cclass || ecode != num) {
484 printf("unexpected error code class=%d code=%d\n",
485 (int)cclass, (int)num);
486 printf(" expected %d/%d %s (line=%d)\n",
487 (int)eclass, (int)ecode, nt_errstr(nterr), line);
492 if (!NT_STATUS_EQUAL(nterr, status)) {
493 printf("unexpected error code %s\n",
495 printf(" expected %s (line=%d)\n",
496 nt_errstr(nterr), line);
505 /* check if the server produced the expected error code */
506 static bool check_error(int line, struct cli_state *c,
507 uint8 eclass, uint32 ecode, NTSTATUS nterr)
509 if (cli_is_dos_error(c)) {
513 /* Check DOS error */
515 cli_dos_error(c, &cclass, &num);
517 if (eclass != cclass || ecode != num) {
518 printf("unexpected error code class=%d code=%d\n",
519 (int)cclass, (int)num);
520 printf(" expected %d/%d %s (line=%d)\n",
521 (int)eclass, (int)ecode, nt_errstr(nterr), line);
530 status = cli_nt_error(c);
532 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
533 printf("unexpected error code %s\n", nt_errstr(status));
534 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
543 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
547 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
549 while (!NT_STATUS_IS_OK(status)) {
550 if (!check_both_error(__LINE__, status, ERRDOS,
551 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
555 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
562 static bool rw_torture(struct cli_state *c)
564 const char *lockfname = "\\torture.lck";
568 pid_t pid2, pid = getpid();
574 memset(buf, '\0', sizeof(buf));
576 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
578 if (!NT_STATUS_IS_OK(status)) {
579 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
581 if (!NT_STATUS_IS_OK(status)) {
582 printf("open of %s failed (%s)\n",
583 lockfname, nt_errstr(status));
587 for (i=0;i<torture_numops;i++) {
588 unsigned n = (unsigned)sys_random()%10;
591 printf("%d\r", i); fflush(stdout);
593 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
595 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
599 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
601 if (!NT_STATUS_IS_OK(status)) {
602 printf("open failed (%s)\n", nt_errstr(status));
607 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("write failed (%s)\n", nt_errstr(status));
615 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
616 sizeof(pid)+(j*sizeof(buf)),
618 if (!NT_STATUS_IS_OK(status)) {
619 printf("write failed (%s)\n",
627 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
628 printf("read failed (%s)\n", cli_errstr(c));
633 printf("data corruption!\n");
637 status = cli_close(c, fnum);
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("close failed (%s)\n", nt_errstr(status));
643 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
644 if (!NT_STATUS_IS_OK(status)) {
645 printf("unlink failed (%s)\n", nt_errstr(status));
649 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("unlock failed (%s)\n", nt_errstr(status));
657 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
664 static bool run_torture(int dummy)
666 struct cli_state *cli;
671 cli_sockopt(cli, sockops);
673 ret = rw_torture(cli);
675 if (!torture_close_connection(cli)) {
682 static bool rw_torture3(struct cli_state *c, char *lockfname)
684 uint16_t fnum = (uint16_t)-1;
689 unsigned countprev = 0;
692 NTSTATUS status = NT_STATUS_OK;
695 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
697 SIVAL(buf, i, sys_random());
704 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("unlink failed (%s) (normal, this file should "
707 "not exist)\n", nt_errstr(status));
710 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
712 if (!NT_STATUS_IS_OK(status)) {
713 printf("first open read/write of %s failed (%s)\n",
714 lockfname, nt_errstr(status));
720 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
722 status = cli_open(c, lockfname, O_RDONLY,
724 if (!NT_STATUS_IS_OK(status)) {
729 if (!NT_STATUS_IS_OK(status)) {
730 printf("second open read-only of %s failed (%s)\n",
731 lockfname, nt_errstr(status));
737 for (count = 0; count < sizeof(buf); count += sent)
739 if (count >= countprev) {
740 printf("%d %8d\r", i, count);
743 countprev += (sizeof(buf) / 20);
748 sent = ((unsigned)sys_random()%(20))+ 1;
749 if (sent > sizeof(buf) - count)
751 sent = sizeof(buf) - count;
754 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
755 count, (size_t)sent, NULL);
756 if (!NT_STATUS_IS_OK(status)) {
757 printf("write failed (%s)\n",
764 sent = cli_read(c, fnum, buf_rd+count, count,
768 printf("read failed offset:%d size:%ld (%s)\n",
769 count, (unsigned long)sizeof(buf)-count,
776 if (memcmp(buf_rd+count, buf+count, sent) != 0)
778 printf("read/write compare failed\n");
779 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
788 status = cli_close(c, fnum);
789 if (!NT_STATUS_IS_OK(status)) {
790 printf("close failed (%s)\n", nt_errstr(status));
797 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
799 const char *lockfname = "\\torture2.lck";
809 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
810 if (!NT_STATUS_IS_OK(status)) {
811 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
814 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("first open read/write of %s failed (%s)\n",
818 lockfname, nt_errstr(status));
822 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("second open read-only of %s failed (%s)\n",
825 lockfname, nt_errstr(status));
826 cli_close(c1, fnum1);
830 for (i = 0; i < torture_numops; i++)
832 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
834 printf("%d\r", i); fflush(stdout);
837 generate_random_buffer((unsigned char *)buf, buf_size);
839 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("write failed (%s)\n", nt_errstr(status));
847 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
848 printf("read failed (%s)\n", cli_errstr(c2));
849 printf("read %d, expected %ld\n", (int)bytes_read,
850 (unsigned long)buf_size);
855 if (memcmp(buf_rd, buf, buf_size) != 0)
857 printf("read/write compare failed\n");
863 status = cli_close(c2, fnum2);
864 if (!NT_STATUS_IS_OK(status)) {
865 printf("close failed (%s)\n", nt_errstr(status));
869 status = cli_close(c1, fnum1);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("close failed (%s)\n", nt_errstr(status));
875 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
876 if (!NT_STATUS_IS_OK(status)) {
877 printf("unlink failed (%s)\n", nt_errstr(status));
884 static bool run_readwritetest(int dummy)
886 struct cli_state *cli1, *cli2;
887 bool test1, test2 = False;
889 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
892 cli_sockopt(cli1, sockops);
893 cli_sockopt(cli2, sockops);
895 printf("starting readwritetest\n");
897 test1 = rw_torture2(cli1, cli2);
898 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
901 test2 = rw_torture2(cli1, cli1);
902 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
905 if (!torture_close_connection(cli1)) {
909 if (!torture_close_connection(cli2)) {
913 return (test1 && test2);
916 static bool run_readwritemulti(int dummy)
918 struct cli_state *cli;
923 cli_sockopt(cli, sockops);
925 printf("run_readwritemulti: fname %s\n", randomfname);
926 test = rw_torture3(cli, randomfname);
928 if (!torture_close_connection(cli)) {
935 static bool run_readwritelarge_internal(int max_xmit_k)
937 static struct cli_state *cli1;
939 const char *lockfname = "\\large.dat";
945 if (!torture_open_connection(&cli1, 0)) {
948 cli_sockopt(cli1, sockops);
949 memset(buf,'\0',sizeof(buf));
951 cli1->max_xmit = max_xmit_k*1024;
953 if (signing_state == Required) {
954 /* Horrible cheat to force
955 multiple signed outstanding
956 packets against a Samba server.
958 cli1->is_samba = false;
961 printf("starting readwritelarge_internal\n");
963 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
965 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
972 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
974 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
976 if (!NT_STATUS_IS_OK(status)) {
977 printf("qfileinfo failed (%s)\n", nt_errstr(status));
981 if (fsize == sizeof(buf))
982 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
983 (unsigned long)fsize);
985 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
986 (unsigned long)fsize);
990 status = cli_close(cli1, fnum1);
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("close failed (%s)\n", nt_errstr(status));
996 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
997 if (!NT_STATUS_IS_OK(status)) {
998 printf("unlink failed (%s)\n", nt_errstr(status));
1002 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1009 cli1->max_xmit = 4*1024;
1011 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1013 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1015 if (!NT_STATUS_IS_OK(status)) {
1016 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1020 if (fsize == sizeof(buf))
1021 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1022 (unsigned long)fsize);
1024 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1025 (unsigned long)fsize);
1030 /* ToDo - set allocation. JRA */
1031 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1032 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1035 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1037 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1041 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1044 status = cli_close(cli1, fnum1);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 printf("close failed (%s)\n", nt_errstr(status));
1050 if (!torture_close_connection(cli1)) {
1056 static bool run_readwritelarge(int dummy)
1058 return run_readwritelarge_internal(128);
1061 static bool run_readwritelarge_signtest(int dummy)
1064 signing_state = Required;
1065 ret = run_readwritelarge_internal(2);
1066 signing_state = Undefined;
1073 #define ival(s) strtol(s, NULL, 0)
1075 /* run a test that simulates an approximate netbench client load */
1076 static bool run_netbench(int client)
1078 struct cli_state *cli;
1083 const char *params[20];
1084 bool correct = True;
1090 cli_sockopt(cli, sockops);
1094 slprintf(cname,sizeof(cname)-1, "client%d", client);
1096 f = fopen(client_txt, "r");
1103 while (fgets(line, sizeof(line)-1, f)) {
1107 line[strlen(line)-1] = 0;
1109 /* printf("[%d] %s\n", line_count, line); */
1111 all_string_sub(line,"client1", cname, sizeof(line));
1113 /* parse the command parameters */
1114 params[0] = strtok_r(line, " ", &saveptr);
1116 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1120 if (i < 2) continue;
1122 if (!strncmp(params[0],"SMB", 3)) {
1123 printf("ERROR: You are using a dbench 1 load file\n");
1127 if (!strcmp(params[0],"NTCreateX")) {
1128 nb_createx(params[1], ival(params[2]), ival(params[3]),
1130 } else if (!strcmp(params[0],"Close")) {
1131 nb_close(ival(params[1]));
1132 } else if (!strcmp(params[0],"Rename")) {
1133 nb_rename(params[1], params[2]);
1134 } else if (!strcmp(params[0],"Unlink")) {
1135 nb_unlink(params[1]);
1136 } else if (!strcmp(params[0],"Deltree")) {
1137 nb_deltree(params[1]);
1138 } else if (!strcmp(params[0],"Rmdir")) {
1139 nb_rmdir(params[1]);
1140 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1141 nb_qpathinfo(params[1]);
1142 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1143 nb_qfileinfo(ival(params[1]));
1144 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1145 nb_qfsinfo(ival(params[1]));
1146 } else if (!strcmp(params[0],"FIND_FIRST")) {
1147 nb_findfirst(params[1]);
1148 } else if (!strcmp(params[0],"WriteX")) {
1149 nb_writex(ival(params[1]),
1150 ival(params[2]), ival(params[3]), ival(params[4]));
1151 } else if (!strcmp(params[0],"ReadX")) {
1152 nb_readx(ival(params[1]),
1153 ival(params[2]), ival(params[3]), ival(params[4]));
1154 } else if (!strcmp(params[0],"Flush")) {
1155 nb_flush(ival(params[1]));
1157 printf("Unknown operation %s\n", params[0]);
1165 if (!torture_close_connection(cli)) {
1173 /* run a test that simulates an approximate netbench client load */
1174 static bool run_nbench(int dummy)
1177 bool correct = True;
1183 signal(SIGALRM, nb_alarm);
1185 t = create_procs(run_netbench, &correct);
1188 printf("\nThroughput %g MB/sec\n",
1189 1.0e-6 * nbio_total() / t);
1195 This test checks for two things:
1197 1) correct support for retaining locks over a close (ie. the server
1198 must not use posix semantics)
1199 2) support for lock timeouts
1201 static bool run_locktest1(int dummy)
1203 struct cli_state *cli1, *cli2;
1204 const char *fname = "\\lockt1.lck";
1205 uint16_t fnum1, fnum2, fnum3;
1207 unsigned lock_timeout;
1210 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1213 cli_sockopt(cli1, sockops);
1214 cli_sockopt(cli2, sockops);
1216 printf("starting locktest1\n");
1218 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1220 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1227 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1228 if (!NT_STATUS_IS_OK(status)) {
1229 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1233 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1234 if (!NT_STATUS_IS_OK(status)) {
1235 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1239 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 printf("lock1 failed (%s)\n", nt_errstr(status));
1245 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1246 if (NT_STATUS_IS_OK(status)) {
1247 printf("lock2 succeeded! This is a locking bug\n");
1250 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1251 NT_STATUS_LOCK_NOT_GRANTED)) {
1256 lock_timeout = (1 + (random() % 20));
1257 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1259 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1260 if (NT_STATUS_IS_OK(status)) {
1261 printf("lock3 succeeded! This is a locking bug\n");
1264 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1265 NT_STATUS_FILE_LOCK_CONFLICT)) {
1271 if (ABS(t2 - t1) < lock_timeout-1) {
1272 printf("error: This server appears not to support timed lock requests\n");
1275 printf("server slept for %u seconds for a %u second timeout\n",
1276 (unsigned int)(t2-t1), lock_timeout);
1278 status = cli_close(cli1, fnum2);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 printf("close1 failed (%s)\n", nt_errstr(status));
1284 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1285 if (NT_STATUS_IS_OK(status)) {
1286 printf("lock4 succeeded! This is a locking bug\n");
1289 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1290 NT_STATUS_FILE_LOCK_CONFLICT)) {
1295 status = cli_close(cli1, fnum1);
1296 if (!NT_STATUS_IS_OK(status)) {
1297 printf("close2 failed (%s)\n", nt_errstr(status));
1301 status = cli_close(cli2, fnum3);
1302 if (!NT_STATUS_IS_OK(status)) {
1303 printf("close3 failed (%s)\n", nt_errstr(status));
1307 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1308 if (!NT_STATUS_IS_OK(status)) {
1309 printf("unlink failed (%s)\n", nt_errstr(status));
1314 if (!torture_close_connection(cli1)) {
1318 if (!torture_close_connection(cli2)) {
1322 printf("Passed locktest1\n");
1327 this checks to see if a secondary tconx can use open files from an
1330 static bool run_tcon_test(int dummy)
1332 static struct cli_state *cli;
1333 const char *fname = "\\tcontest.tmp";
1335 uint16 cnum1, cnum2, cnum3;
1336 uint16 vuid1, vuid2;
1341 memset(buf, '\0', sizeof(buf));
1343 if (!torture_open_connection(&cli, 0)) {
1346 cli_sockopt(cli, sockops);
1348 printf("starting tcontest\n");
1350 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1352 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1361 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1362 if (!NT_STATUS_IS_OK(status)) {
1363 printf("initial write failed (%s)", nt_errstr(status));
1367 status = cli_tcon_andx(cli, share, "?????",
1368 password, strlen(password)+1);
1369 if (!NT_STATUS_IS_OK(status)) {
1370 printf("%s refused 2nd tree connect (%s)\n", host,
1377 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1378 vuid2 = cli->vuid + 1;
1380 /* try a write with the wrong tid */
1383 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1384 if (NT_STATUS_IS_OK(status)) {
1385 printf("* server allows write with wrong TID\n");
1388 printf("server fails write with wrong TID : %s\n",
1393 /* try a write with an invalid tid */
1396 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1397 if (NT_STATUS_IS_OK(status)) {
1398 printf("* server allows write with invalid TID\n");
1401 printf("server fails write with invalid TID : %s\n",
1405 /* try a write with an invalid vuid */
1409 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1410 if (NT_STATUS_IS_OK(status)) {
1411 printf("* server allows write with invalid VUID\n");
1414 printf("server fails write with invalid VUID : %s\n",
1421 status = cli_close(cli, fnum1);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 printf("close failed (%s)\n", nt_errstr(status));
1429 status = cli_tdis(cli);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1437 if (!torture_close_connection(cli)) {
1446 checks for old style tcon support
1448 static bool run_tcon2_test(int dummy)
1450 static struct cli_state *cli;
1451 uint16 cnum, max_xmit;
1455 if (!torture_open_connection(&cli, 0)) {
1458 cli_sockopt(cli, sockops);
1460 printf("starting tcon2 test\n");
1462 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1466 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 printf("tcon2 failed : %s\n", nt_errstr(status));
1473 printf("tcon OK : max_xmit=%d cnum=%d\n",
1474 (int)max_xmit, (int)cnum);
1477 if (!torture_close_connection(cli)) {
1481 printf("Passed tcon2 test\n");
1485 static bool tcon_devtest(struct cli_state *cli,
1486 const char *myshare, const char *devtype,
1487 const char *return_devtype,
1488 NTSTATUS expected_error)
1493 status = cli_tcon_andx(cli, myshare, devtype,
1494 password, strlen(password)+1);
1496 if (NT_STATUS_IS_OK(expected_error)) {
1497 if (NT_STATUS_IS_OK(status)) {
1498 if (strcmp(cli->dev, return_devtype) == 0) {
1501 printf("tconX to share %s with type %s "
1502 "succeeded but returned the wrong "
1503 "device type (got [%s] but should have got [%s])\n",
1504 myshare, devtype, cli->dev, return_devtype);
1508 printf("tconX to share %s with type %s "
1509 "should have succeeded but failed\n",
1515 if (NT_STATUS_IS_OK(status)) {
1516 printf("tconx to share %s with type %s "
1517 "should have failed but succeeded\n",
1521 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1525 printf("Returned unexpected error\n");
1534 checks for correct tconX support
1536 static bool run_tcon_devtype_test(int dummy)
1538 static struct cli_state *cli1 = NULL;
1543 status = cli_full_connection(&cli1, myname,
1544 host, NULL, port_to_use,
1546 username, workgroup,
1547 password, flags, signing_state);
1549 if (!NT_STATUS_IS_OK(status)) {
1550 printf("could not open connection\n");
1554 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1557 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1560 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1563 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1566 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1569 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1572 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1575 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1578 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1581 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1587 printf("Passed tcondevtest\n");
1594 This test checks that
1596 1) the server supports multiple locking contexts on the one SMB
1597 connection, distinguished by PID.
1599 2) the server correctly fails overlapping locks made by the same PID (this
1600 goes against POSIX behaviour, which is why it is tricky to implement)
1602 3) the server denies unlock requests by an incorrect client PID
1604 static bool run_locktest2(int dummy)
1606 static struct cli_state *cli;
1607 const char *fname = "\\lockt2.lck";
1608 uint16_t fnum1, fnum2, fnum3;
1609 bool correct = True;
1612 if (!torture_open_connection(&cli, 0)) {
1616 cli_sockopt(cli, sockops);
1618 printf("starting locktest2\n");
1620 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1624 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1625 if (!NT_STATUS_IS_OK(status)) {
1626 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1630 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1638 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1646 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 printf("lock1 failed (%s)\n", nt_errstr(status));
1652 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1653 if (NT_STATUS_IS_OK(status)) {
1654 printf("WRITE lock1 succeeded! This is a locking bug\n");
1657 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1658 NT_STATUS_LOCK_NOT_GRANTED)) {
1663 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1664 if (NT_STATUS_IS_OK(status)) {
1665 printf("WRITE lock2 succeeded! This is a locking bug\n");
1668 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1669 NT_STATUS_LOCK_NOT_GRANTED)) {
1674 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1675 if (NT_STATUS_IS_OK(status)) {
1676 printf("READ lock2 succeeded! This is a locking bug\n");
1679 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1680 NT_STATUS_FILE_LOCK_CONFLICT)) {
1685 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1686 if (!NT_STATUS_IS_OK(status)) {
1687 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1690 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1691 printf("unlock at 100 succeeded! This is a locking bug\n");
1695 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1696 printf("unlock1 succeeded! This is a locking bug\n");
1699 if (!check_error(__LINE__, cli,
1701 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1704 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1705 printf("unlock2 succeeded! This is a locking bug\n");
1708 if (!check_error(__LINE__, cli,
1710 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1713 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1714 if (NT_STATUS_IS_OK(status)) {
1715 printf("lock3 succeeded! This is a locking bug\n");
1718 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1719 NT_STATUS_LOCK_NOT_GRANTED)) {
1726 status = cli_close(cli, fnum1);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 printf("close1 failed (%s)\n", nt_errstr(status));
1732 status = cli_close(cli, fnum2);
1733 if (!NT_STATUS_IS_OK(status)) {
1734 printf("close2 failed (%s)\n", nt_errstr(status));
1738 status = cli_close(cli, fnum3);
1739 if (!NT_STATUS_IS_OK(status)) {
1740 printf("close3 failed (%s)\n", nt_errstr(status));
1744 if (!torture_close_connection(cli)) {
1748 printf("locktest2 finished\n");
1755 This test checks that
1757 1) the server supports the full offset range in lock requests
1759 static bool run_locktest3(int dummy)
1761 static struct cli_state *cli1, *cli2;
1762 const char *fname = "\\lockt3.lck";
1763 uint16_t fnum1, fnum2;
1766 bool correct = True;
1769 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1771 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1774 cli_sockopt(cli1, sockops);
1775 cli_sockopt(cli2, sockops);
1777 printf("starting locktest3\n");
1779 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1781 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1783 if (!NT_STATUS_IS_OK(status)) {
1784 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1788 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1789 if (!NT_STATUS_IS_OK(status)) {
1790 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1794 for (offset=i=0;i<torture_numops;i++) {
1796 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1797 printf("lock1 %d failed (%s)\n",
1803 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1804 printf("lock2 %d failed (%s)\n",
1811 for (offset=i=0;i<torture_numops;i++) {
1814 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1815 printf("error: lock1 %d succeeded!\n", i);
1819 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1820 printf("error: lock2 %d succeeded!\n", i);
1824 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1825 printf("error: lock3 %d succeeded!\n", i);
1829 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1830 printf("error: lock4 %d succeeded!\n", i);
1835 for (offset=i=0;i<torture_numops;i++) {
1838 status = cli_unlock(cli1, fnum1, offset-1, 1);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 printf("unlock1 %d failed (%s)\n",
1846 status = cli_unlock(cli2, fnum2, offset-2, 1);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 printf("unlock2 %d failed (%s)\n",
1855 status = cli_close(cli1, fnum1);
1856 if (!NT_STATUS_IS_OK(status)) {
1857 printf("close1 failed (%s)\n", nt_errstr(status));
1861 status = cli_close(cli2, fnum2);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 printf("close2 failed (%s)\n", nt_errstr(status));
1867 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 printf("unlink failed (%s)\n", nt_errstr(status));
1873 if (!torture_close_connection(cli1)) {
1877 if (!torture_close_connection(cli2)) {
1881 printf("finished locktest3\n");
1886 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1887 printf("** "); correct = False; \
1891 looks at overlapping locks
1893 static bool run_locktest4(int dummy)
1895 static struct cli_state *cli1, *cli2;
1896 const char *fname = "\\lockt4.lck";
1897 uint16_t fnum1, fnum2, f;
1900 bool correct = True;
1903 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1907 cli_sockopt(cli1, sockops);
1908 cli_sockopt(cli2, sockops);
1910 printf("starting locktest4\n");
1912 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1914 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1915 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1917 memset(buf, 0, sizeof(buf));
1919 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1921 if (!NT_STATUS_IS_OK(status)) {
1922 printf("Failed to create file: %s\n", nt_errstr(status));
1927 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1928 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1929 EXPECTED(ret, False);
1930 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1932 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1933 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1934 EXPECTED(ret, True);
1935 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1937 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1938 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1939 EXPECTED(ret, False);
1940 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1942 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1943 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1944 EXPECTED(ret, True);
1945 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1947 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1948 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1949 EXPECTED(ret, False);
1950 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1952 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1953 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1954 EXPECTED(ret, True);
1955 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1957 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1958 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1959 EXPECTED(ret, True);
1960 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1962 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1963 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1964 EXPECTED(ret, False);
1965 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1967 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1968 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1969 EXPECTED(ret, False);
1970 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1972 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1973 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1974 EXPECTED(ret, True);
1975 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1977 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1978 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1979 EXPECTED(ret, False);
1980 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1982 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1983 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1984 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1985 EXPECTED(ret, False);
1986 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1989 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1990 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1991 EXPECTED(ret, False);
1992 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1994 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1996 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1998 ret = NT_STATUS_IS_OK(status);
2000 EXPECTED(ret, False);
2001 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2004 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
2005 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
2006 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2007 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2008 EXPECTED(ret, True);
2009 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2012 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
2013 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
2014 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2015 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
2016 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2018 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2019 EXPECTED(ret, True);
2020 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2022 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
2023 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2024 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2026 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
2027 EXPECTED(ret, True);
2028 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2030 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
2031 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2032 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2034 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
2035 EXPECTED(ret, True);
2036 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2038 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
2039 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
2040 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2041 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2043 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
2044 EXPECTED(ret, True);
2045 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2047 cli_close(cli1, fnum1);
2048 cli_close(cli2, fnum2);
2049 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2050 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2051 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2052 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
2053 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2054 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2055 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2057 cli_close(cli1, fnum1);
2058 EXPECTED(ret, True);
2059 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2062 cli_close(cli1, fnum1);
2063 cli_close(cli2, fnum2);
2064 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2065 torture_close_connection(cli1);
2066 torture_close_connection(cli2);
2068 printf("finished locktest4\n");
2073 looks at lock upgrade/downgrade.
2075 static bool run_locktest5(int dummy)
2077 static struct cli_state *cli1, *cli2;
2078 const char *fname = "\\lockt5.lck";
2079 uint16_t fnum1, fnum2, fnum3;
2082 bool correct = True;
2085 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2089 cli_sockopt(cli1, sockops);
2090 cli_sockopt(cli2, sockops);
2092 printf("starting locktest5\n");
2094 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2096 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2097 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2098 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2100 memset(buf, 0, sizeof(buf));
2102 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2104 if (!NT_STATUS_IS_OK(status)) {
2105 printf("Failed to create file: %s\n", nt_errstr(status));
2110 /* Check for NT bug... */
2111 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2112 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2113 cli_close(cli1, fnum1);
2114 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2115 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2116 EXPECTED(ret, True);
2117 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2118 cli_close(cli1, fnum1);
2119 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2120 cli_unlock(cli1, fnum3, 0, 1);
2122 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2123 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2124 EXPECTED(ret, True);
2125 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2127 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2128 EXPECTED(ret, False);
2130 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2132 /* Unlock the process 2 lock. */
2133 cli_unlock(cli2, fnum2, 0, 4);
2135 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2136 EXPECTED(ret, False);
2138 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2140 /* Unlock the process 1 fnum3 lock. */
2141 cli_unlock(cli1, fnum3, 0, 4);
2143 /* Stack 2 more locks here. */
2144 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2145 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2147 EXPECTED(ret, True);
2148 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2150 /* Unlock the first process lock, then check this was the WRITE lock that was
2153 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2154 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2156 EXPECTED(ret, True);
2157 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2159 /* Unlock the process 2 lock. */
2160 cli_unlock(cli2, fnum2, 0, 4);
2162 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2164 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2165 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2166 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2168 EXPECTED(ret, True);
2169 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2171 /* Ensure the next unlock fails. */
2172 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2173 EXPECTED(ret, False);
2174 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2176 /* Ensure connection 2 can get a write lock. */
2177 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2178 EXPECTED(ret, True);
2180 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2184 cli_close(cli1, fnum1);
2185 cli_close(cli2, fnum2);
2186 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2187 if (!torture_close_connection(cli1)) {
2190 if (!torture_close_connection(cli2)) {
2194 printf("finished locktest5\n");
2200 tries the unusual lockingX locktype bits
2202 static bool run_locktest6(int dummy)
2204 static struct cli_state *cli;
2205 const char *fname[1] = { "\\lock6.txt" };
2210 if (!torture_open_connection(&cli, 0)) {
2214 cli_sockopt(cli, sockops);
2216 printf("starting locktest6\n");
2219 printf("Testing %s\n", fname[i]);
2221 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2223 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2224 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2225 cli_close(cli, fnum);
2226 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2228 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2229 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2230 cli_close(cli, fnum);
2231 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2233 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2236 torture_close_connection(cli);
2238 printf("finished locktest6\n");
2242 static bool run_locktest7(int dummy)
2244 struct cli_state *cli1;
2245 const char *fname = "\\lockt7.lck";
2248 bool correct = False;
2251 if (!torture_open_connection(&cli1, 0)) {
2255 cli_sockopt(cli1, sockops);
2257 printf("starting locktest7\n");
2259 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2261 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2263 memset(buf, 0, sizeof(buf));
2265 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2267 if (!NT_STATUS_IS_OK(status)) {
2268 printf("Failed to create file: %s\n", nt_errstr(status));
2272 cli_setpid(cli1, 1);
2274 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2275 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2278 printf("pid1 successfully locked range 130:4 for READ\n");
2281 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2282 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2285 printf("pid1 successfully read the range 130:4\n");
2288 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2289 if (!NT_STATUS_IS_OK(status)) {
2290 printf("pid1 unable to write to the range 130:4, error was "
2291 "%s\n", nt_errstr(status));
2292 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2293 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2297 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2301 cli_setpid(cli1, 2);
2303 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2304 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2306 printf("pid2 successfully read the range 130:4\n");
2309 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 printf("pid2 unable to write to the range 130:4, error was "
2312 "%s\n", nt_errstr(status));
2313 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2314 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2318 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2322 cli_setpid(cli1, 1);
2323 cli_unlock(cli1, fnum1, 130, 4);
2325 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2326 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2329 printf("pid1 successfully locked range 130:4 for WRITE\n");
2332 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2333 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2336 printf("pid1 successfully read the range 130:4\n");
2339 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2340 if (!NT_STATUS_IS_OK(status)) {
2341 printf("pid1 unable to write to the range 130:4, error was "
2342 "%s\n", nt_errstr(status));
2345 printf("pid1 successfully wrote to the range 130:4\n");
2348 cli_setpid(cli1, 2);
2350 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2351 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2352 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2353 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2357 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2361 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 printf("pid2 unable to write to the range 130:4, error was "
2364 "%s\n", nt_errstr(status));
2365 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2366 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2370 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2374 cli_unlock(cli1, fnum1, 130, 0);
2378 cli_close(cli1, fnum1);
2379 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2380 torture_close_connection(cli1);
2382 printf("finished locktest7\n");
2387 * This demonstrates a problem with our use of GPFS share modes: A file
2388 * descriptor sitting in the pending close queue holding a GPFS share mode
2389 * blocks opening a file another time. Happens with Word 2007 temp files.
2390 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2391 * open is denied with NT_STATUS_SHARING_VIOLATION.
2394 static bool run_locktest8(int dummy)
2396 struct cli_state *cli1;
2397 const char *fname = "\\lockt8.lck";
2398 uint16_t fnum1, fnum2;
2400 bool correct = False;
2403 if (!torture_open_connection(&cli1, 0)) {
2407 cli_sockopt(cli1, sockops);
2409 printf("starting locktest8\n");
2411 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2413 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2415 if (!NT_STATUS_IS_OK(status)) {
2416 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2420 memset(buf, 0, sizeof(buf));
2422 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2423 if (!NT_STATUS_IS_OK(status)) {
2424 d_fprintf(stderr, "cli_open second time returned %s\n",
2429 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2430 printf("Unable to apply read lock on range 1:1, error was "
2431 "%s\n", cli_errstr(cli1));
2435 status = cli_close(cli1, fnum1);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2441 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2442 if (!NT_STATUS_IS_OK(status)) {
2443 d_fprintf(stderr, "cli_open third time returned %s\n",
2451 cli_close(cli1, fnum1);
2452 cli_close(cli1, fnum2);
2453 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2454 torture_close_connection(cli1);
2456 printf("finished locktest8\n");
2461 * This test is designed to be run in conjunction with
2462 * external NFS or POSIX locks taken in the filesystem.
2463 * It checks that the smbd server will block until the
2464 * lock is released and then acquire it. JRA.
2467 static bool got_alarm;
2468 static int alarm_fd;
2470 static void alarm_handler(int dummy)
2475 static void alarm_handler_parent(int dummy)
2480 static void do_local_lock(int read_fd, int write_fd)
2485 const char *local_pathname = NULL;
2488 local_pathname = talloc_asprintf(talloc_tos(),
2489 "%s/lockt9.lck", local_path);
2490 if (!local_pathname) {
2491 printf("child: alloc fail\n");
2495 unlink(local_pathname);
2496 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2498 printf("child: open of %s failed %s.\n",
2499 local_pathname, strerror(errno));
2503 /* Now take a fcntl lock. */
2504 lock.l_type = F_WRLCK;
2505 lock.l_whence = SEEK_SET;
2508 lock.l_pid = getpid();
2510 ret = fcntl(fd,F_SETLK,&lock);
2512 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2513 local_pathname, strerror(errno));
2516 printf("child: got lock 0:4 on file %s.\n",
2521 CatchSignal(SIGALRM, alarm_handler);
2523 /* Signal the parent. */
2524 if (write(write_fd, &c, 1) != 1) {
2525 printf("child: start signal fail %s.\n",
2532 /* Wait for the parent to be ready. */
2533 if (read(read_fd, &c, 1) != 1) {
2534 printf("child: reply signal fail %s.\n",
2542 printf("child: released lock 0:4 on file %s.\n",
2548 static bool run_locktest9(int dummy)
2550 struct cli_state *cli1;
2551 const char *fname = "\\lockt9.lck";
2553 bool correct = False;
2554 int pipe_in[2], pipe_out[2];
2558 struct timeval start;
2562 printf("starting locktest9\n");
2564 if (local_path == NULL) {
2565 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2569 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2574 if (child_pid == -1) {
2578 if (child_pid == 0) {
2580 do_local_lock(pipe_out[0], pipe_in[1]);
2590 ret = read(pipe_in[0], &c, 1);
2592 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2597 if (!torture_open_connection(&cli1, 0)) {
2601 cli_sockopt(cli1, sockops);
2603 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2605 if (!NT_STATUS_IS_OK(status)) {
2606 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2610 /* Ensure the child has the lock. */
2611 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2612 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2615 d_printf("Child has the lock.\n");
2618 /* Tell the child to wait 5 seconds then exit. */
2619 ret = write(pipe_out[1], &c, 1);
2621 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2626 /* Wait 20 seconds for the lock. */
2627 alarm_fd = cli1->fd;
2628 CatchSignal(SIGALRM, alarm_handler_parent);
2631 start = timeval_current();
2633 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2634 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2635 "%s\n", cli_errstr(cli1));
2640 seconds = timeval_elapsed(&start);
2642 printf("Parent got the lock after %.2f seconds.\n",
2645 status = cli_close(cli1, fnum);
2646 if (!NT_STATUS_IS_OK(status)) {
2647 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2654 cli_close(cli1, fnum);
2655 torture_close_connection(cli1);
2659 printf("finished locktest9\n");
2664 test whether fnums and tids open on one VC are available on another (a major
2667 static bool run_fdpasstest(int dummy)
2669 struct cli_state *cli1, *cli2;
2670 const char *fname = "\\fdpass.tst";
2675 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2678 cli_sockopt(cli1, sockops);
2679 cli_sockopt(cli2, sockops);
2681 printf("starting fdpasstest\n");
2683 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2685 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2687 if (!NT_STATUS_IS_OK(status)) {
2688 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2692 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2694 if (!NT_STATUS_IS_OK(status)) {
2695 printf("write failed (%s)\n", nt_errstr(status));
2699 cli2->vuid = cli1->vuid;
2700 cli2->cnum = cli1->cnum;
2701 cli2->pid = cli1->pid;
2703 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2704 printf("read succeeded! nasty security hole [%s]\n",
2709 cli_close(cli1, fnum1);
2710 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2712 torture_close_connection(cli1);
2713 torture_close_connection(cli2);
2715 printf("finished fdpasstest\n");
2719 static bool run_fdsesstest(int dummy)
2721 struct cli_state *cli;
2726 const char *fname = "\\fdsess.tst";
2727 const char *fname1 = "\\fdsess1.tst";
2734 if (!torture_open_connection(&cli, 0))
2736 cli_sockopt(cli, sockops);
2738 if (!torture_cli_session_setup2(cli, &new_vuid))
2741 saved_cnum = cli->cnum;
2742 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2744 new_cnum = cli->cnum;
2745 cli->cnum = saved_cnum;
2747 printf("starting fdsesstest\n");
2749 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2750 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2752 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2753 if (!NT_STATUS_IS_OK(status)) {
2754 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2758 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2760 if (!NT_STATUS_IS_OK(status)) {
2761 printf("write failed (%s)\n", nt_errstr(status));
2765 saved_vuid = cli->vuid;
2766 cli->vuid = new_vuid;
2768 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2769 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2773 /* Try to open a file with different vuid, samba cnum. */
2774 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2775 printf("create with different vuid, same cnum succeeded.\n");
2776 cli_close(cli, fnum2);
2777 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2779 printf("create with different vuid, same cnum failed.\n");
2780 printf("This will cause problems with service clients.\n");
2784 cli->vuid = saved_vuid;
2786 /* Try with same vuid, different cnum. */
2787 cli->cnum = new_cnum;
2789 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2790 printf("read succeeded with different cnum![%s]\n",
2795 cli->cnum = saved_cnum;
2796 cli_close(cli, fnum1);
2797 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2799 torture_close_connection(cli);
2801 printf("finished fdsesstest\n");
2806 This test checks that
2808 1) the server does not allow an unlink on a file that is open
2810 static bool run_unlinktest(int dummy)
2812 struct cli_state *cli;
2813 const char *fname = "\\unlink.tst";
2815 bool correct = True;
2818 if (!torture_open_connection(&cli, 0)) {
2822 cli_sockopt(cli, sockops);
2824 printf("starting unlink test\n");
2826 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2830 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2836 status = cli_unlink(cli, fname,
2837 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2838 if (NT_STATUS_IS_OK(status)) {
2839 printf("error: server allowed unlink on an open file\n");
2842 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2843 NT_STATUS_SHARING_VIOLATION);
2846 cli_close(cli, fnum);
2847 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2849 if (!torture_close_connection(cli)) {
2853 printf("unlink test finished\n");
2860 test how many open files this server supports on the one socket
2862 static bool run_maxfidtest(int dummy)
2864 struct cli_state *cli;
2866 uint16_t fnums[0x11000];
2869 bool correct = True;
2875 printf("failed to connect\n");
2879 cli_sockopt(cli, sockops);
2881 for (i=0; i<0x11000; i++) {
2882 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2883 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2885 if (!NT_STATUS_IS_OK(status)) {
2886 printf("open of %s failed (%s)\n",
2887 fname, nt_errstr(status));
2888 printf("maximum fnum is %d\n", i);
2896 printf("cleaning up\n");
2898 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2899 cli_close(cli, fnums[i]);
2901 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2902 if (!NT_STATUS_IS_OK(status)) {
2903 printf("unlink of %s failed (%s)\n",
2904 fname, nt_errstr(status));
2911 printf("maxfid test finished\n");
2912 if (!torture_close_connection(cli)) {
2918 /* generate a random buffer */
2919 static void rand_buf(char *buf, int len)
2922 *buf = (char)sys_random();
2927 /* send smb negprot commands, not reading the response */
2928 static bool run_negprot_nowait(int dummy)
2930 struct tevent_context *ev;
2932 struct cli_state *cli;
2933 bool correct = True;
2935 printf("starting negprot nowait test\n");
2937 ev = tevent_context_init(talloc_tos());
2942 if (!(cli = open_nbt_connection())) {
2947 for (i=0;i<50000;i++) {
2948 struct tevent_req *req;
2950 req = cli_negprot_send(ev, ev, cli);
2955 if (!tevent_req_poll(req, ev)) {
2956 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2964 if (torture_close_connection(cli)) {
2968 printf("finished negprot nowait test\n");
2973 /* send smb negprot commands, not reading the response */
2974 static bool run_bad_nbt_session(int dummy)
2976 struct nmb_name called, calling;
2977 struct sockaddr_storage ss;
2982 printf("starting bad nbt session test\n");
2984 make_nmb_name(&calling, myname, 0x0);
2985 make_nmb_name(&called , host, 0x20);
2987 if (!resolve_name(host, &ss, 0x20, true)) {
2988 d_fprintf(stderr, "Could not resolve name %s\n", host);
2992 status = open_socket_out(&ss, 139, 10000, &fd);
2993 if (!NT_STATUS_IS_OK(status)) {
2994 d_fprintf(stderr, "open_socket_out failed: %s\n",
2999 ret = cli_bad_session_request(fd, &calling, &called);
3002 d_fprintf(stderr, "open_socket_out failed: %s\n",
3007 printf("finished bad nbt session test\n");
3011 /* send random IPC commands */
3012 static bool run_randomipc(int dummy)
3014 char *rparam = NULL;
3016 unsigned int rdrcnt,rprcnt;
3018 int api, param_len, i;
3019 struct cli_state *cli;
3020 bool correct = True;
3023 printf("starting random ipc test\n");
3025 if (!torture_open_connection(&cli, 0)) {
3029 for (i=0;i<count;i++) {
3030 api = sys_random() % 500;
3031 param_len = (sys_random() % 64);
3033 rand_buf(param, param_len);
3038 param, param_len, 8,
3039 NULL, 0, BUFFER_SIZE,
3043 printf("%d/%d\r", i,count);
3046 printf("%d/%d\n", i, count);
3048 if (!torture_close_connection(cli)) {
3052 printf("finished random ipc test\n");
3059 static void browse_callback(const char *sname, uint32 stype,
3060 const char *comment, void *state)
3062 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3068 This test checks the browse list code
3071 static bool run_browsetest(int dummy)
3073 static struct cli_state *cli;
3074 bool correct = True;
3076 printf("starting browse test\n");
3078 if (!torture_open_connection(&cli, 0)) {
3082 printf("domain list:\n");
3083 cli_NetServerEnum(cli, cli->server_domain,
3084 SV_TYPE_DOMAIN_ENUM,
3085 browse_callback, NULL);
3087 printf("machine list:\n");
3088 cli_NetServerEnum(cli, cli->server_domain,
3090 browse_callback, NULL);
3092 if (!torture_close_connection(cli)) {
3096 printf("browse test finished\n");
3104 This checks how the getatr calls works
3106 static bool run_attrtest(int dummy)
3108 struct cli_state *cli;
3111 const char *fname = "\\attrib123456789.tst";
3112 bool correct = True;
3115 printf("starting attrib test\n");
3117 if (!torture_open_connection(&cli, 0)) {
3121 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3122 cli_open(cli, fname,
3123 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3124 cli_close(cli, fnum);
3126 status = cli_getatr(cli, fname, NULL, NULL, &t);
3127 if (!NT_STATUS_IS_OK(status)) {
3128 printf("getatr failed (%s)\n", nt_errstr(status));
3132 if (abs(t - time(NULL)) > 60*60*24*10) {
3133 printf("ERROR: SMBgetatr bug. time is %s",
3139 t2 = t-60*60*24; /* 1 day ago */
3141 status = cli_setatr(cli, fname, 0, t2);
3142 if (!NT_STATUS_IS_OK(status)) {
3143 printf("setatr failed (%s)\n", nt_errstr(status));
3147 status = cli_getatr(cli, fname, NULL, NULL, &t);
3148 if (!NT_STATUS_IS_OK(status)) {
3149 printf("getatr failed (%s)\n", nt_errstr(status));
3154 printf("ERROR: getatr/setatr bug. times are\n%s",
3156 printf("%s", ctime(&t2));
3160 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3162 if (!torture_close_connection(cli)) {
3166 printf("attrib test finished\n");
3173 This checks a couple of trans2 calls
3175 static bool run_trans2test(int dummy)
3177 struct cli_state *cli;
3180 time_t c_time, a_time, m_time;
3181 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3182 const char *fname = "\\trans2.tst";
3183 const char *dname = "\\trans2";
3184 const char *fname2 = "\\trans2\\trans2.tst";
3186 bool correct = True;
3190 printf("starting trans2 test\n");
3192 if (!torture_open_connection(&cli, 0)) {
3196 status = cli_get_fs_attr_info(cli, &fs_attr);
3197 if (!NT_STATUS_IS_OK(status)) {
3198 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3203 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3204 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3205 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3206 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3207 if (!NT_STATUS_IS_OK(status)) {
3208 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3212 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3218 if (strcmp(pname, fname)) {
3219 printf("qfilename gave different name? [%s] [%s]\n",
3224 cli_close(cli, fnum);
3228 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3229 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3231 if (!NT_STATUS_IS_OK(status)) {
3232 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3235 cli_close(cli, fnum);
3237 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3239 if (!NT_STATUS_IS_OK(status)) {
3240 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3243 if (c_time != m_time) {
3244 printf("create time=%s", ctime(&c_time));
3245 printf("modify time=%s", ctime(&m_time));
3246 printf("This system appears to have sticky create times\n");
3248 if (a_time % (60*60) == 0) {
3249 printf("access time=%s", ctime(&a_time));
3250 printf("This system appears to set a midnight access time\n");
3254 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3255 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3261 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3262 cli_open(cli, fname,
3263 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3264 cli_close(cli, fnum);
3265 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3266 &m_time_ts, &size, NULL, NULL);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3271 if (w_time_ts.tv_sec < 60*60*24*2) {
3272 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3273 printf("This system appears to set a initial 0 write time\n");
3278 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3281 /* check if the server updates the directory modification time
3282 when creating a new file */
3283 status = cli_mkdir(cli, dname);
3284 if (!NT_STATUS_IS_OK(status)) {
3285 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3289 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3290 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3291 if (!NT_STATUS_IS_OK(status)) {
3292 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3296 cli_open(cli, fname2,
3297 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3298 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3299 cli_close(cli, fnum);
3300 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3301 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3302 if (!NT_STATUS_IS_OK(status)) {
3303 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3306 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3308 printf("This system does not update directory modification times\n");
3312 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3313 cli_rmdir(cli, dname);
3315 if (!torture_close_connection(cli)) {
3319 printf("trans2 test finished\n");
3325 This checks new W2K calls.
3328 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3330 uint8_t *buf = NULL;
3334 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3335 pcli->max_xmit, NULL, &buf, &len);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3340 printf("qfileinfo: level %d, len = %u\n", level, len);
3341 dump_data(0, (uint8 *)buf, len);
3348 static bool run_w2ktest(int dummy)
3350 struct cli_state *cli;
3352 const char *fname = "\\w2ktest\\w2k.tst";
3354 bool correct = True;
3356 printf("starting w2k test\n");
3358 if (!torture_open_connection(&cli, 0)) {
3362 cli_open(cli, fname,
3363 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3365 for (level = 1004; level < 1040; level++) {
3366 new_trans(cli, fnum, level);
3369 cli_close(cli, fnum);
3371 if (!torture_close_connection(cli)) {
3375 printf("w2k test finished\n");
3382 this is a harness for some oplock tests
3384 static bool run_oplock1(int dummy)
3386 struct cli_state *cli1;
3387 const char *fname = "\\lockt1.lck";
3389 bool correct = True;
3392 printf("starting oplock test 1\n");
3394 if (!torture_open_connection(&cli1, 0)) {
3398 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3400 cli_sockopt(cli1, sockops);
3402 cli1->use_oplocks = True;
3404 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3406 if (!NT_STATUS_IS_OK(status)) {
3407 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3411 cli1->use_oplocks = False;
3413 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3414 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3416 status = cli_close(cli1, fnum1);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 printf("close2 failed (%s)\n", nt_errstr(status));
3422 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3423 if (!NT_STATUS_IS_OK(status)) {
3424 printf("unlink failed (%s)\n", nt_errstr(status));
3428 if (!torture_close_connection(cli1)) {
3432 printf("finished oplock test 1\n");
3437 static bool run_oplock2(int dummy)
3439 struct cli_state *cli1, *cli2;
3440 const char *fname = "\\lockt2.lck";
3441 uint16_t fnum1, fnum2;
3442 int saved_use_oplocks = use_oplocks;
3444 bool correct = True;
3445 volatile bool *shared_correct;
3448 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3449 *shared_correct = True;
3451 use_level_II_oplocks = True;
3454 printf("starting oplock test 2\n");
3456 if (!torture_open_connection(&cli1, 0)) {
3457 use_level_II_oplocks = False;
3458 use_oplocks = saved_use_oplocks;
3462 cli1->use_oplocks = True;
3463 cli1->use_level_II_oplocks = True;
3465 if (!torture_open_connection(&cli2, 1)) {
3466 use_level_II_oplocks = False;
3467 use_oplocks = saved_use_oplocks;
3471 cli2->use_oplocks = True;
3472 cli2->use_level_II_oplocks = True;
3474 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3476 cli_sockopt(cli1, sockops);
3477 cli_sockopt(cli2, sockops);
3479 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3481 if (!NT_STATUS_IS_OK(status)) {
3482 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3486 /* Don't need the globals any more. */
3487 use_level_II_oplocks = False;
3488 use_oplocks = saved_use_oplocks;
3492 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3493 if (!NT_STATUS_IS_OK(status)) {
3494 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3495 *shared_correct = False;
3501 status = cli_close(cli2, fnum2);
3502 if (!NT_STATUS_IS_OK(status)) {
3503 printf("close2 failed (%s)\n", nt_errstr(status));
3504 *shared_correct = False;
3512 /* Ensure cli1 processes the break. Empty file should always return 0
3515 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3516 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3520 /* Should now be at level II. */
3521 /* Test if sending a write locks causes a break to none. */
3523 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3524 printf("lock failed (%s)\n", cli_errstr(cli1));
3528 cli_unlock(cli1, fnum1, 0, 4);
3532 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3533 printf("lock failed (%s)\n", cli_errstr(cli1));
3537 cli_unlock(cli1, fnum1, 0, 4);
3541 cli_read(cli1, fnum1, buf, 0, 4);
3543 status = cli_close(cli1, fnum1);
3544 if (!NT_STATUS_IS_OK(status)) {
3545 printf("close1 failed (%s)\n", nt_errstr(status));
3551 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3552 if (!NT_STATUS_IS_OK(status)) {
3553 printf("unlink failed (%s)\n", nt_errstr(status));
3557 if (!torture_close_connection(cli1)) {
3561 if (!*shared_correct) {
3565 printf("finished oplock test 2\n");
3570 struct oplock4_state {
3571 struct tevent_context *ev;
3572 struct cli_state *cli;
3577 static void oplock4_got_break(struct tevent_req *req);
3578 static void oplock4_got_open(struct tevent_req *req);
3580 static bool run_oplock4(int dummy)
3582 struct tevent_context *ev;
3583 struct cli_state *cli1, *cli2;
3584 struct tevent_req *oplock_req, *open_req;
3585 const char *fname = "\\lockt4.lck";
3586 const char *fname_ln = "\\lockt4_ln.lck";
3587 uint16_t fnum1, fnum2;
3588 int saved_use_oplocks = use_oplocks;
3590 bool correct = true;
3594 struct oplock4_state *state;
3596 printf("starting oplock test 4\n");
3598 if (!torture_open_connection(&cli1, 0)) {
3599 use_level_II_oplocks = false;
3600 use_oplocks = saved_use_oplocks;
3604 if (!torture_open_connection(&cli2, 1)) {
3605 use_level_II_oplocks = false;
3606 use_oplocks = saved_use_oplocks;
3610 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3611 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3613 cli_sockopt(cli1, sockops);
3614 cli_sockopt(cli2, sockops);
3616 /* Create the file. */
3617 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3619 if (!NT_STATUS_IS_OK(status)) {
3620 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3624 status = cli_close(cli1, fnum1);
3625 if (!NT_STATUS_IS_OK(status)) {
3626 printf("close1 failed (%s)\n", nt_errstr(status));
3630 /* Now create a hardlink. */
3631 status = cli_nt_hardlink(cli1, fname, fname_ln);
3632 if (!NT_STATUS_IS_OK(status)) {
3633 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3637 /* Prove that opening hardlinks cause deny modes to conflict. */
3638 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3639 if (!NT_STATUS_IS_OK(status)) {
3640 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3644 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3645 if (NT_STATUS_IS_OK(status)) {
3646 printf("open of %s succeeded - should fail with sharing violation.\n",
3651 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3652 printf("open of %s should fail with sharing violation. Got %s\n",
3653 fname_ln, nt_errstr(status));
3657 status = cli_close(cli1, fnum1);
3658 if (!NT_STATUS_IS_OK(status)) {
3659 printf("close1 failed (%s)\n", nt_errstr(status));
3663 cli1->use_oplocks = true;
3664 cli1->use_level_II_oplocks = true;
3666 cli2->use_oplocks = true;
3667 cli2->use_level_II_oplocks = true;
3669 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3670 if (!NT_STATUS_IS_OK(status)) {
3671 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3675 ev = tevent_context_init(talloc_tos());
3677 printf("tevent_req_create failed\n");
3681 state = talloc(ev, struct oplock4_state);
3682 if (state == NULL) {
3683 printf("talloc failed\n");
3688 state->got_break = &got_break;
3689 state->fnum2 = &fnum2;
3691 oplock_req = cli_smb_oplock_break_waiter_send(
3692 talloc_tos(), ev, cli1);
3693 if (oplock_req == NULL) {
3694 printf("cli_smb_oplock_break_waiter_send failed\n");
3697 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3699 open_req = cli_open_send(
3700 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3701 if (oplock_req == NULL) {
3702 printf("cli_open_send failed\n");
3705 tevent_req_set_callback(open_req, oplock4_got_open, state);
3710 while (!got_break || fnum2 == 0xffff) {
3712 ret = tevent_loop_once(ev);
3714 printf("tevent_loop_once failed: %s\n",
3720 status = cli_close(cli2, fnum2);
3721 if (!NT_STATUS_IS_OK(status)) {
3722 printf("close2 failed (%s)\n", nt_errstr(status));
3726 status = cli_close(cli1, fnum1);
3727 if (!NT_STATUS_IS_OK(status)) {
3728 printf("close1 failed (%s)\n", nt_errstr(status));
3732 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3733 if (!NT_STATUS_IS_OK(status)) {
3734 printf("unlink failed (%s)\n", nt_errstr(status));
3738 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3739 if (!NT_STATUS_IS_OK(status)) {
3740 printf("unlink failed (%s)\n", nt_errstr(status));
3744 if (!torture_close_connection(cli1)) {
3752 printf("finished oplock test 4\n");
3757 static void oplock4_got_break(struct tevent_req *req)
3759 struct oplock4_state *state = tevent_req_callback_data(
3760 req, struct oplock4_state);
3765 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3772 *state->got_break = true;
3774 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3777 printf("cli_oplock_ack_send failed\n");
3782 static void oplock4_got_open(struct tevent_req *req)
3784 struct oplock4_state *state = tevent_req_callback_data(
3785 req, struct oplock4_state);
3788 status = cli_open_recv(req, state->fnum2);
3789 if (!NT_STATUS_IS_OK(status)) {
3790 printf("cli_open_recv returned %s\n", nt_errstr(status));
3791 *state->fnum2 = 0xffff;
3796 Test delete on close semantics.
3798 static bool run_deletetest(int dummy)
3800 struct cli_state *cli1 = NULL;
3801 struct cli_state *cli2 = NULL;
3802 const char *fname = "\\delete.file";
3803 uint16_t fnum1 = (uint16_t)-1;
3804 uint16_t fnum2 = (uint16_t)-1;
3805 bool correct = True;
3808 printf("starting delete test\n");
3810 if (!torture_open_connection(&cli1, 0)) {
3814 cli_sockopt(cli1, sockops);
3816 /* Test 1 - this should delete the file on close. */
3818 cli_setatr(cli1, fname, 0, 0);
3819 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3821 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3822 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3823 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3824 if (!NT_STATUS_IS_OK(status)) {
3825 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3830 status = cli_close(cli1, fnum1);
3831 if (!NT_STATUS_IS_OK(status)) {
3832 printf("[1] close failed (%s)\n", nt_errstr(status));
3837 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3838 printf("[1] open of %s succeeded (should fail)\n", fname);
3843 printf("first delete on close test succeeded.\n");
3845 /* Test 2 - this should delete the file on close. */
3847 cli_setatr(cli1, fname, 0, 0);
3848 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3850 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3851 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3852 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3859 status = cli_nt_delete_on_close(cli1, fnum1, true);
3860 if (!NT_STATUS_IS_OK(status)) {
3861 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3866 status = cli_close(cli1, fnum1);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 printf("[2] close failed (%s)\n", nt_errstr(status));
3873 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3874 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3875 status = cli_close(cli1, fnum1);
3876 if (!NT_STATUS_IS_OK(status)) {
3877 printf("[2] close failed (%s)\n", nt_errstr(status));
3881 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3883 printf("second delete on close test succeeded.\n");
3886 cli_setatr(cli1, fname, 0, 0);
3887 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3889 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3890 FILE_ATTRIBUTE_NORMAL,
3891 FILE_SHARE_READ|FILE_SHARE_WRITE,
3892 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3899 /* This should fail with a sharing violation - open for delete is only compatible
3900 with SHARE_DELETE. */
3902 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3903 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3904 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3909 /* This should succeed. */
3910 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3911 FILE_ATTRIBUTE_NORMAL,
3912 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3913 FILE_OPEN, 0, 0, &fnum2);
3914 if (!NT_STATUS_IS_OK(status)) {
3915 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3920 status = cli_nt_delete_on_close(cli1, fnum1, true);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3927 status = cli_close(cli1, fnum1);
3928 if (!NT_STATUS_IS_OK(status)) {
3929 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3934 status = cli_close(cli1, fnum2);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3941 /* This should fail - file should no longer be there. */
3943 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3944 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3945 status = cli_close(cli1, fnum1);
3946 if (!NT_STATUS_IS_OK(status)) {
3947 printf("[3] close failed (%s)\n", nt_errstr(status));
3949 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3953 printf("third delete on close test succeeded.\n");
3956 cli_setatr(cli1, fname, 0, 0);
3957 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3959 status = cli_ntcreate(cli1, fname, 0,
3960 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3961 FILE_ATTRIBUTE_NORMAL,
3962 FILE_SHARE_READ|FILE_SHARE_WRITE,
3963 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3970 /* This should succeed. */
3971 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3972 FILE_ATTRIBUTE_NORMAL,
3973 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3974 FILE_OPEN, 0, 0, &fnum2);
3975 if (!NT_STATUS_IS_OK(status)) {
3976 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3981 status = cli_close(cli1, fnum2);
3982 if (!NT_STATUS_IS_OK(status)) {
3983 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3988 status = cli_nt_delete_on_close(cli1, fnum1, true);
3989 if (!NT_STATUS_IS_OK(status)) {
3990 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3995 /* This should fail - no more opens once delete on close set. */
3996 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3997 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3998 FILE_OPEN, 0, 0, &fnum2))) {
3999 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4003 printf("fourth delete on close test succeeded.\n");
4005 status = cli_close(cli1, fnum1);
4006 if (!NT_STATUS_IS_OK(status)) {
4007 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4013 cli_setatr(cli1, fname, 0, 0);
4014 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4016 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4023 /* This should fail - only allowed on NT opens with DELETE access. */
4025 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4026 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4031 status = cli_close(cli1, fnum1);
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4038 printf("fifth delete on close test succeeded.\n");
4041 cli_setatr(cli1, fname, 0, 0);
4042 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4044 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4045 FILE_ATTRIBUTE_NORMAL,
4046 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4047 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 printf("[6] open of %s failed (%s)\n", fname,
4055 /* This should fail - only allowed on NT opens with DELETE access. */
4057 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4058 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4063 status = cli_close(cli1, fnum1);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4070 printf("sixth delete on close test succeeded.\n");
4073 cli_setatr(cli1, fname, 0, 0);
4074 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4076 status = cli_ntcreate(cli1, fname, 0,
4077 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4078 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4086 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4087 printf("[7] setting delete_on_close on file failed !\n");
4092 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4093 printf("[7] unsetting delete_on_close on file failed !\n");
4098 status = cli_close(cli1, fnum1);
4099 if (!NT_STATUS_IS_OK(status)) {
4100 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4105 /* This next open should succeed - we reset the flag. */
4106 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4107 if (!NT_STATUS_IS_OK(status)) {
4108 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4113 status = cli_close(cli1, fnum1);
4114 if (!NT_STATUS_IS_OK(status)) {
4115 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4120 printf("seventh delete on close test succeeded.\n");
4123 cli_setatr(cli1, fname, 0, 0);
4124 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4126 if (!torture_open_connection(&cli2, 1)) {
4127 printf("[8] failed to open second connection.\n");
4132 cli_sockopt(cli1, sockops);
4134 status = cli_ntcreate(cli1, fname, 0,
4135 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4136 FILE_ATTRIBUTE_NORMAL,
4137 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4138 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4139 if (!NT_STATUS_IS_OK(status)) {
4140 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4145 status = cli_ntcreate(cli2, fname, 0,
4146 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4147 FILE_ATTRIBUTE_NORMAL,
4148 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4149 FILE_OPEN, 0, 0, &fnum2);
4150 if (!NT_STATUS_IS_OK(status)) {
4151 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4156 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4157 printf("[8] setting delete_on_close on file failed !\n");
4162 status = cli_close(cli1, fnum1);
4163 if (!NT_STATUS_IS_OK(status)) {
4164 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4169 status = cli_close(cli2, fnum2);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4176 /* This should fail.. */
4177 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4178 if (NT_STATUS_IS_OK(status)) {
4179 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4183 printf("eighth delete on close test succeeded.\n");
4185 /* This should fail - we need to set DELETE_ACCESS. */
4186 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4187 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4188 printf("[9] open of %s succeeded should have failed!\n", fname);
4193 printf("ninth delete on close test succeeded.\n");
4195 status = cli_ntcreate(cli1, fname, 0,
4196 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4197 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4198 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4200 if (!NT_STATUS_IS_OK(status)) {
4201 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4206 /* This should delete the file. */
4207 status = cli_close(cli1, fnum1);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("[10] close failed (%s)\n", nt_errstr(status));
4214 /* This should fail.. */
4215 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4216 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4220 printf("tenth delete on close test succeeded.\n");
4222 cli_setatr(cli1, fname, 0, 0);
4223 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4225 /* What error do we get when attempting to open a read-only file with
4228 /* Create a readonly file. */
4229 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4230 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4231 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4232 if (!NT_STATUS_IS_OK(status)) {
4233 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4238 status = cli_close(cli1, fnum1);
4239 if (!NT_STATUS_IS_OK(status)) {
4240 printf("[11] close failed (%s)\n", nt_errstr(status));
4245 /* Now try open for delete access. */
4246 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4247 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4248 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4249 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4250 cli_close(cli1, fnum1);
4254 NTSTATUS nterr = cli_nt_error(cli1);
4255 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4256 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4260 printf("eleventh delete on close test succeeded.\n");
4264 printf("finished delete test\n");
4267 /* FIXME: This will crash if we aborted before cli2 got
4268 * intialized, because these functions don't handle
4269 * uninitialized connections. */
4271 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4272 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4273 cli_setatr(cli1, fname, 0, 0);
4274 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4276 if (cli1 && !torture_close_connection(cli1)) {
4279 if (cli2 && !torture_close_connection(cli2)) {
4285 static bool run_deletetest_ln(int dummy)
4287 struct cli_state *cli;
4288 const char *fname = "\\delete1";
4289 const char *fname_ln = "\\delete1_ln";
4293 bool correct = true;
4296 printf("starting deletetest-ln\n");
4298 if (!torture_open_connection(&cli, 0)) {
4302 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4303 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4305 cli_sockopt(cli, sockops);
4307 /* Create the file. */
4308 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4309 if (!NT_STATUS_IS_OK(status)) {
4310 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4314 status = cli_close(cli, fnum);
4315 if (!NT_STATUS_IS_OK(status)) {
4316 printf("close1 failed (%s)\n", nt_errstr(status));
4320 /* Now create a hardlink. */
4321 status = cli_nt_hardlink(cli, fname, fname_ln);
4322 if (!NT_STATUS_IS_OK(status)) {
4323 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4327 /* Open the original file. */
4328 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4329 FILE_ATTRIBUTE_NORMAL,
4330 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4331 FILE_OPEN_IF, 0, 0, &fnum);
4332 if (!NT_STATUS_IS_OK(status)) {
4333 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4337 /* Unlink the hard link path. */
4338 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4339 FILE_ATTRIBUTE_NORMAL,
4340 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4341 FILE_OPEN_IF, 0, 0, &fnum1);
4342 if (!NT_STATUS_IS_OK(status)) {
4343 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4346 status = cli_nt_delete_on_close(cli, fnum1, true);
4347 if (!NT_STATUS_IS_OK(status)) {
4348 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4349 __location__, fname_ln, nt_errstr(status));
4353 status = cli_close(cli, fnum1);
4354 if (!NT_STATUS_IS_OK(status)) {
4355 printf("close %s failed (%s)\n",
4356 fname_ln, nt_errstr(status));
4360 status = cli_close(cli, fnum);
4361 if (!NT_STATUS_IS_OK(status)) {
4362 printf("close %s failed (%s)\n",
4363 fname, nt_errstr(status));
4367 /* Ensure the original file is still there. */
4368 status = cli_getatr(cli, fname, NULL, NULL, &t);
4369 if (!NT_STATUS_IS_OK(status)) {
4370 printf("%s getatr on file %s failed (%s)\n",
4377 /* Ensure the link path is gone. */
4378 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4379 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4380 printf("%s, getatr for file %s returned wrong error code %s "
4381 "- should have been deleted\n",
4383 fname_ln, nt_errstr(status));
4387 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4388 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4390 if (!torture_close_connection(cli)) {
4394 printf("finished deletetest-ln\n");
4400 print out server properties
4402 static bool run_properties(int dummy)
4404 struct cli_state *cli;
4405 bool correct = True;
4407 printf("starting properties test\n");
4411 if (!torture_open_connection(&cli, 0)) {
4415 cli_sockopt(cli, sockops);
4417 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4419 if (!torture_close_connection(cli)) {
4428 /* FIRST_DESIRED_ACCESS 0xf019f */
4429 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4430 FILE_READ_EA| /* 0xf */ \
4431 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4432 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4433 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4434 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4435 /* SECOND_DESIRED_ACCESS 0xe0080 */
4436 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4437 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4438 WRITE_OWNER_ACCESS /* 0xe0000 */
4441 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4442 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4444 WRITE_OWNER_ACCESS /* */
4448 Test ntcreate calls made by xcopy
4450 static bool run_xcopy(int dummy)
4452 static struct cli_state *cli1;
4453 const char *fname = "\\test.txt";
4454 bool correct = True;
4455 uint16_t fnum1, fnum2;
4458 printf("starting xcopy test\n");
4460 if (!torture_open_connection(&cli1, 0)) {
4464 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4465 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4466 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4467 if (!NT_STATUS_IS_OK(status)) {
4468 printf("First open failed - %s\n", nt_errstr(status));
4472 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4473 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4474 FILE_OPEN, 0x200000, 0, &fnum2);
4475 if (!NT_STATUS_IS_OK(status)) {
4476 printf("second open failed - %s\n", nt_errstr(status));
4480 if (!torture_close_connection(cli1)) {
4488 Test rename on files open with share delete and no share delete.
4490 static bool run_rename(int dummy)
4492 static struct cli_state *cli1;
4493 const char *fname = "\\test.txt";
4494 const char *fname1 = "\\test1.txt";
4495 bool correct = True;
4500 printf("starting rename test\n");
4502 if (!torture_open_connection(&cli1, 0)) {
4506 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4507 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4509 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4510 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4511 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4512 if (!NT_STATUS_IS_OK(status)) {
4513 printf("First open failed - %s\n", nt_errstr(status));
4517 status = cli_rename(cli1, fname, fname1);
4518 if (!NT_STATUS_IS_OK(status)) {
4519 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4521 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4525 status = cli_close(cli1, fnum1);
4526 if (!NT_STATUS_IS_OK(status)) {
4527 printf("close - 1 failed (%s)\n", nt_errstr(status));
4531 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4532 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4533 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4535 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4537 FILE_SHARE_DELETE|FILE_SHARE_READ,
4539 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4540 if (!NT_STATUS_IS_OK(status)) {
4541 printf("Second open failed - %s\n", nt_errstr(status));
4545 status = cli_rename(cli1, fname, fname1);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4550 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4553 status = cli_close(cli1, fnum1);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("close - 2 failed (%s)\n", nt_errstr(status));
4559 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4560 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4562 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4563 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4564 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4565 if (!NT_STATUS_IS_OK(status)) {
4566 printf("Third open failed - %s\n", nt_errstr(status));
4575 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4576 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4577 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4580 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4581 printf("[8] setting delete_on_close on file failed !\n");
4585 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4586 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4592 status = cli_rename(cli1, fname, fname1);
4593 if (!NT_STATUS_IS_OK(status)) {
4594 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4597 printf("Third rename succeeded (SHARE_NONE)\n");
4600 status = cli_close(cli1, fnum1);
4601 if (!NT_STATUS_IS_OK(status)) {
4602 printf("close - 3 failed (%s)\n", nt_errstr(status));
4606 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4607 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4611 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4612 FILE_ATTRIBUTE_NORMAL,
4613 FILE_SHARE_READ | FILE_SHARE_WRITE,
4614 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4615 if (!NT_STATUS_IS_OK(status)) {
4616 printf("Fourth open failed - %s\n", nt_errstr(status));
4620 status = cli_rename(cli1, fname, fname1);
4621 if (!NT_STATUS_IS_OK(status)) {
4622 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4624 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4628 status = cli_close(cli1, fnum1);
4629 if (!NT_STATUS_IS_OK(status)) {
4630 printf("close - 4 failed (%s)\n", nt_errstr(status));
4634 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4635 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4639 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4640 FILE_ATTRIBUTE_NORMAL,
4641 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4642 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4643 if (!NT_STATUS_IS_OK(status)) {
4644 printf("Fifth open failed - %s\n", nt_errstr(status));
4648 status = cli_rename(cli1, fname, fname1);
4649 if (!NT_STATUS_IS_OK(status)) {
4650 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4653 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4657 * Now check if the first name still exists ...
4660 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4661 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4662 printf("Opening original file after rename of open file fails: %s\n",
4666 printf("Opening original file after rename of open file works ...\n");
4667 (void)cli_close(cli1, fnum2);
4671 status = cli_close(cli1, fnum1);
4672 if (!NT_STATUS_IS_OK(status)) {
4673 printf("close - 5 failed (%s)\n", nt_errstr(status));
4677 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4678 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4679 if (!NT_STATUS_IS_OK(status)) {
4680 printf("getatr on file %s failed - %s ! \n",
4681 fname1, nt_errstr(status));
4684 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4685 printf("Renamed file %s has wrong attr 0x%x "
4686 "(should be 0x%x)\n",
4689 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4692 printf("Renamed file %s has archive bit set\n", fname1);
4696 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4697 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4699 if (!torture_close_connection(cli1)) {
4706 static bool run_pipe_number(int dummy)
4708 struct cli_state *cli1;
4709 const char *pipe_name = "\\SPOOLSS";
4714 printf("starting pipenumber test\n");
4715 if (!torture_open_connection(&cli1, 0)) {
4719 cli_sockopt(cli1, sockops);
4721 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4722 FILE_ATTRIBUTE_NORMAL,
4723 FILE_SHARE_READ|FILE_SHARE_WRITE,
4724 FILE_OPEN_IF, 0, 0, &fnum);
4725 if (!NT_STATUS_IS_OK(status)) {
4726 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4730 printf("\r%6d", num_pipes);
4733 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4734 torture_close_connection(cli1);
4739 Test open mode returns on read-only files.
4741 static bool run_opentest(int dummy)
4743 static struct cli_state *cli1;
4744 static struct cli_state *cli2;
4745 const char *fname = "\\readonly.file";
4746 uint16_t fnum1, fnum2;
4749 bool correct = True;
4753 printf("starting open test\n");
4755 if (!torture_open_connection(&cli1, 0)) {
4759 cli_setatr(cli1, fname, 0, 0);
4760 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4762 cli_sockopt(cli1, sockops);
4764 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4765 if (!NT_STATUS_IS_OK(status)) {
4766 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4770 status = cli_close(cli1, fnum1);
4771 if (!NT_STATUS_IS_OK(status)) {
4772 printf("close2 failed (%s)\n", nt_errstr(status));
4776 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4777 if (!NT_STATUS_IS_OK(status)) {
4778 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4782 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4783 if (!NT_STATUS_IS_OK(status)) {
4784 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4788 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4789 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4791 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4792 NT_STATUS_ACCESS_DENIED)) {
4793 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4796 printf("finished open test 1\n");
4798 cli_close(cli1, fnum1);
4800 /* Now try not readonly and ensure ERRbadshare is returned. */
4802 cli_setatr(cli1, fname, 0, 0);
4804 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4805 if (!NT_STATUS_IS_OK(status)) {
4806 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4810 /* This will fail - but the error should be ERRshare. */
4811 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4813 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4814 NT_STATUS_SHARING_VIOLATION)) {
4815 printf("correct error code ERRDOS/ERRbadshare returned\n");
4818 status = cli_close(cli1, fnum1);
4819 if (!NT_STATUS_IS_OK(status)) {
4820 printf("close2 failed (%s)\n", nt_errstr(status));
4824 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4826 printf("finished open test 2\n");
4828 /* Test truncate open disposition on file opened for read. */
4829 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4830 if (!NT_STATUS_IS_OK(status)) {
4831 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4835 /* write 20 bytes. */
4837 memset(buf, '\0', 20);
4839 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4840 if (!NT_STATUS_IS_OK(status)) {
4841 printf("write failed (%s)\n", nt_errstr(status));
4845 status = cli_close(cli1, fnum1);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4851 /* Ensure size == 20. */
4852 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4853 if (!NT_STATUS_IS_OK(status)) {
4854 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4859 printf("(3) file size != 20\n");
4863 /* Now test if we can truncate a file opened for readonly. */
4864 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4870 status = cli_close(cli1, fnum1);
4871 if (!NT_STATUS_IS_OK(status)) {
4872 printf("close2 failed (%s)\n", nt_errstr(status));
4876 /* Ensure size == 0. */
4877 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4884 printf("(3) file size != 0\n");
4887 printf("finished open test 3\n");
4889 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4891 printf("Do ctemp tests\n");
4892 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4893 if (!NT_STATUS_IS_OK(status)) {
4894 printf("ctemp failed (%s)\n", nt_errstr(status));
4898 printf("ctemp gave path %s\n", tmp_path);
4899 status = cli_close(cli1, fnum1);
4900 if (!NT_STATUS_IS_OK(status)) {
4901 printf("close of temp failed (%s)\n", nt_errstr(status));
4904 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4905 if (!NT_STATUS_IS_OK(status)) {
4906 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4909 /* Test the non-io opens... */
4911 if (!torture_open_connection(&cli2, 1)) {
4915 cli_setatr(cli2, fname, 0, 0);
4916 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4918 cli_sockopt(cli2, sockops);
4920 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4921 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4922 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4923 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4924 if (!NT_STATUS_IS_OK(status)) {
4925 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4929 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4930 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4931 FILE_OPEN_IF, 0, 0, &fnum2);
4932 if (!NT_STATUS_IS_OK(status)) {
4933 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4937 status = cli_close(cli1, fnum1);
4938 if (!NT_STATUS_IS_OK(status)) {
4939 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4943 status = cli_close(cli2, fnum2);
4944 if (!NT_STATUS_IS_OK(status)) {
4945 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4949 printf("non-io open test #1 passed.\n");
4951 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4953 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4955 status = cli_ntcreate(cli1, fname, 0,
4956 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4957 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4958 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4959 if (!NT_STATUS_IS_OK(status)) {
4960 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4964 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4965 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4966 FILE_OPEN_IF, 0, 0, &fnum2);
4967 if (!NT_STATUS_IS_OK(status)) {
4968 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4972 status = cli_close(cli1, fnum1);
4973 if (!NT_STATUS_IS_OK(status)) {
4974 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4978 status = cli_close(cli2, fnum2);
4979 if (!NT_STATUS_IS_OK(status)) {
4980 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4984 printf("non-io open test #2 passed.\n");
4986 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4988 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4990 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4991 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4992 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4993 if (!NT_STATUS_IS_OK(status)) {
4994 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4998 status = cli_ntcreate(cli2, fname, 0,
4999 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5000 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5001 FILE_OPEN_IF, 0, 0, &fnum2);
5002 if (!NT_STATUS_IS_OK(status)) {
5003 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5007 status = cli_close(cli1, fnum1);
5008 if (!NT_STATUS_IS_OK(status)) {
5009 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5013 status = cli_close(cli2, fnum2);
5014 if (!NT_STATUS_IS_OK(status)) {
5015 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5019 printf("non-io open test #3 passed.\n");
5021 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5023 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5025 status = cli_ntcreate(cli1, fname, 0,
5026 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5027 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5028 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5029 if (!NT_STATUS_IS_OK(status)) {
5030 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5034 status = cli_ntcreate(cli2, fname, 0,
5035 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5036 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5037 FILE_OPEN_IF, 0, 0, &fnum2);
5038 if (NT_STATUS_IS_OK(status)) {
5039 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5043 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5045 status = cli_close(cli1, fnum1);
5046 if (!NT_STATUS_IS_OK(status)) {
5047 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5051 printf("non-io open test #4 passed.\n");
5053 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5055 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5057 status = cli_ntcreate(cli1, fname, 0,
5058 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5059 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5060 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5061 if (!NT_STATUS_IS_OK(status)) {
5062 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5066 status = cli_ntcreate(cli2, fname, 0,
5067 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5068 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5069 FILE_OPEN_IF, 0, 0, &fnum2);
5070 if (!NT_STATUS_IS_OK(status)) {
5071 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5075 status = cli_close(cli1, fnum1);
5076 if (!NT_STATUS_IS_OK(status)) {
5077 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5081 status = cli_close(cli2, fnum2);
5082 if (!NT_STATUS_IS_OK(status)) {
5083 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5087 printf("non-io open test #5 passed.\n");
5089 printf("TEST #6 testing 1 non-io open, one io open\n");
5091 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5093 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5094 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5095 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5096 if (!NT_STATUS_IS_OK(status)) {
5097 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5101 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5102 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5103 FILE_OPEN_IF, 0, 0, &fnum2);
5104 if (!NT_STATUS_IS_OK(status)) {
5105 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5109 status = cli_close(cli1, fnum1);
5110 if (!NT_STATUS_IS_OK(status)) {
5111 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5115 status = cli_close(cli2, fnum2);
5116 if (!NT_STATUS_IS_OK(status)) {
5117 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5121 printf("non-io open test #6 passed.\n");
5123 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5125 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5127 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5128 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5129 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5130 if (!NT_STATUS_IS_OK(status)) {
5131 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5135 status = cli_ntcreate(cli2, fname, 0,
5136 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5137 FILE_ATTRIBUTE_NORMAL,
5138 FILE_SHARE_READ|FILE_SHARE_DELETE,
5139 FILE_OPEN_IF, 0, 0, &fnum2);
5140 if (NT_STATUS_IS_OK(status)) {
5141 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5145 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5147 status = cli_close(cli1, fnum1);
5148 if (!NT_STATUS_IS_OK(status)) {
5149 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5153 printf("non-io open test #7 passed.\n");
5155 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5157 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5158 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5159 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5160 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5161 if (!NT_STATUS_IS_OK(status)) {
5162 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5167 /* Write to ensure we have to update the file time. */
5168 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5170 if (!NT_STATUS_IS_OK(status)) {
5171 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5176 status = cli_close(cli1, fnum1);
5177 if (!NT_STATUS_IS_OK(status)) {
5178 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5184 if (!torture_close_connection(cli1)) {
5187 if (!torture_close_connection(cli2)) {
5194 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5196 uint16 major, minor;
5197 uint32 caplow, caphigh;
5200 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5201 printf("Server doesn't support UNIX CIFS extensions.\n");
5202 return NT_STATUS_NOT_SUPPORTED;
5205 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("Server didn't return UNIX CIFS extensions: %s\n",
5213 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("Server doesn't support setting UNIX CIFS extensions: "
5217 "%s.\n", nt_errstr(status));
5221 return NT_STATUS_OK;
5225 Test POSIX open /mkdir calls.
5227 static bool run_simple_posix_open_test(int dummy)
5229 static struct cli_state *cli1;
5230 const char *fname = "posix:file";
5231 const char *hname = "posix:hlink";
5232 const char *sname = "posix:symlink";
5233 const char *dname = "posix:dir";
5236 uint16_t fnum1 = (uint16_t)-1;
5237 SMB_STRUCT_STAT sbuf;
5238 bool correct = false;
5241 printf("Starting simple POSIX open test\n");
5243 if (!torture_open_connection(&cli1, 0)) {
5247 cli_sockopt(cli1, sockops);
5249 status = torture_setup_unix_extensions(cli1);
5250 if (!NT_STATUS_IS_OK(status)) {
5254 cli_setatr(cli1, fname, 0, 0);
5255 cli_posix_unlink(cli1, fname);
5256 cli_setatr(cli1, dname, 0, 0);
5257 cli_posix_rmdir(cli1, dname);
5258 cli_setatr(cli1, hname, 0, 0);
5259 cli_posix_unlink(cli1, hname);
5260 cli_setatr(cli1, sname, 0, 0);
5261 cli_posix_unlink(cli1, sname);
5263 /* Create a directory. */
5264 status = cli_posix_mkdir(cli1, dname, 0777);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5270 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5272 if (!NT_STATUS_IS_OK(status)) {
5273 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5277 /* Test ftruncate - set file size. */
5278 status = cli_ftruncate(cli1, fnum1, 1000);
5279 if (!NT_STATUS_IS_OK(status)) {
5280 printf("ftruncate failed (%s)\n", nt_errstr(status));
5284 /* Ensure st_size == 1000 */
5285 status = cli_posix_stat(cli1, fname, &sbuf);
5286 if (!NT_STATUS_IS_OK(status)) {
5287 printf("stat failed (%s)\n", nt_errstr(status));
5291 if (sbuf.st_ex_size != 1000) {
5292 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5296 /* Test ftruncate - set file size back to zero. */
5297 status = cli_ftruncate(cli1, fnum1, 0);
5298 if (!NT_STATUS_IS_OK(status)) {
5299 printf("ftruncate failed (%s)\n", nt_errstr(status));
5303 status = cli_close(cli1, fnum1);
5304 if (!NT_STATUS_IS_OK(status)) {
5305 printf("close failed (%s)\n", nt_errstr(status));
5309 /* Now open the file again for read only. */
5310 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5311 if (!NT_STATUS_IS_OK(status)) {
5312 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5316 /* Now unlink while open. */
5317 status = cli_posix_unlink(cli1, fname);
5318 if (!NT_STATUS_IS_OK(status)) {
5319 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5323 status = cli_close(cli1, fnum1);
5324 if (!NT_STATUS_IS_OK(status)) {
5325 printf("close(2) failed (%s)\n", nt_errstr(status));
5329 /* Ensure the file has gone. */
5330 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5331 if (NT_STATUS_IS_OK(status)) {
5332 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5336 /* Create again to test open with O_TRUNC. */
5337 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5338 if (!NT_STATUS_IS_OK(status)) {
5339 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5343 /* Test ftruncate - set file size. */
5344 status = cli_ftruncate(cli1, fnum1, 1000);
5345 if (!NT_STATUS_IS_OK(status)) {
5346 printf("ftruncate failed (%s)\n", nt_errstr(status));
5350 /* Ensure st_size == 1000 */
5351 status = cli_posix_stat(cli1, fname, &sbuf);
5352 if (!NT_STATUS_IS_OK(status)) {
5353 printf("stat failed (%s)\n", nt_errstr(status));
5357 if (sbuf.st_ex_size != 1000) {
5358 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5362 status = cli_close(cli1, fnum1);
5363 if (!NT_STATUS_IS_OK(status)) {
5364 printf("close(2) failed (%s)\n", nt_errstr(status));
5368 /* Re-open with O_TRUNC. */
5369 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5375 /* Ensure st_size == 0 */
5376 status = cli_posix_stat(cli1, fname, &sbuf);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("stat failed (%s)\n", nt_errstr(status));
5382 if (sbuf.st_ex_size != 0) {
5383 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5387 status = cli_close(cli1, fnum1);
5388 if (!NT_STATUS_IS_OK(status)) {
5389 printf("close failed (%s)\n", nt_errstr(status));
5393 status = cli_posix_unlink(cli1, fname);
5394 if (!NT_STATUS_IS_OK(status)) {
5395 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5399 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5400 if (!NT_STATUS_IS_OK(status)) {
5401 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5402 dname, nt_errstr(status));
5406 cli_close(cli1, fnum1);
5408 /* What happens when we try and POSIX open a directory for write ? */
5409 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5410 if (NT_STATUS_IS_OK(status)) {
5411 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5414 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5415 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5420 /* Create the file. */
5421 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5423 if (!NT_STATUS_IS_OK(status)) {
5424 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5428 /* Write some data into it. */
5429 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5431 if (!NT_STATUS_IS_OK(status)) {
5432 printf("cli_write failed: %s\n", nt_errstr(status));
5436 cli_close(cli1, fnum1);
5438 /* Now create a hardlink. */
5439 status = cli_posix_hardlink(cli1, fname, hname);
5440 if (!NT_STATUS_IS_OK(status)) {
5441 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5445 /* Now create a symlink. */
5446 status = cli_posix_symlink(cli1, fname, sname);
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5452 /* Open the hardlink for read. */
5453 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5454 if (!NT_STATUS_IS_OK(status)) {
5455 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5459 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5460 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5464 if (memcmp(buf, "TEST DATA\n", 10)) {
5465 printf("invalid data read from hardlink\n");
5469 /* Do a POSIX lock/unlock. */
5470 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5471 if (!NT_STATUS_IS_OK(status)) {
5472 printf("POSIX lock failed %s\n", nt_errstr(status));
5476 /* Punch a hole in the locked area. */
5477 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5478 if (!NT_STATUS_IS_OK(status)) {
5479 printf("POSIX unlock failed %s\n", nt_errstr(status));
5483 cli_close(cli1, fnum1);
5485 /* Open the symlink for read - this should fail. A POSIX
5486 client should not be doing opens on a symlink. */
5487 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5488 if (NT_STATUS_IS_OK(status)) {
5489 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5492 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5493 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5494 printf("POSIX open of %s should have failed "
5495 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5496 "failed with %s instead.\n",
5497 sname, nt_errstr(status));
5502 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5503 if (!NT_STATUS_IS_OK(status)) {
5504 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5508 if (strcmp(namebuf, fname) != 0) {
5509 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5510 sname, fname, namebuf);
5514 status = cli_posix_rmdir(cli1, dname);
5515 if (!NT_STATUS_IS_OK(status)) {
5516 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5520 printf("Simple POSIX open test passed\n");
5525 if (fnum1 != (uint16_t)-1) {
5526 cli_close(cli1, fnum1);
5527 fnum1 = (uint16_t)-1;
5530 cli_setatr(cli1, sname, 0, 0);
5531 cli_posix_unlink(cli1, sname);
5532 cli_setatr(cli1, hname, 0, 0);
5533 cli_posix_unlink(cli1, hname);
5534 cli_setatr(cli1, fname, 0, 0);
5535 cli_posix_unlink(cli1, fname);
5536 cli_setatr(cli1, dname, 0, 0);
5537 cli_posix_rmdir(cli1, dname);
5539 if (!torture_close_connection(cli1)) {
5547 static uint32 open_attrs_table[] = {
5548 FILE_ATTRIBUTE_NORMAL,
5549 FILE_ATTRIBUTE_ARCHIVE,
5550 FILE_ATTRIBUTE_READONLY,
5551 FILE_ATTRIBUTE_HIDDEN,
5552 FILE_ATTRIBUTE_SYSTEM,
5554 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5555 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5556 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5557 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5558 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5559 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5561 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5562 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5563 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5564 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5567 struct trunc_open_results {
5574 static struct trunc_open_results attr_results[] = {
5575 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5576 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5577 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5578 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5579 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5580 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5581 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5582 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5583 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5584 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5585 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5586 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5587 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5588 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5589 { 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 },
5590 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5591 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5592 { 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 },
5593 { 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 },
5594 { 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 },
5595 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5596 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5597 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5598 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5599 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5600 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5603 static bool run_openattrtest(int dummy)
5605 static struct cli_state *cli1;
5606 const char *fname = "\\openattr.file";
5608 bool correct = True;
5610 unsigned int i, j, k, l;
5613 printf("starting open attr test\n");
5615 if (!torture_open_connection(&cli1, 0)) {
5619 cli_sockopt(cli1, sockops);
5621 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5622 cli_setatr(cli1, fname, 0, 0);
5623 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5625 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5626 open_attrs_table[i], FILE_SHARE_NONE,
5627 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5628 if (!NT_STATUS_IS_OK(status)) {
5629 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5633 status = cli_close(cli1, fnum1);
5634 if (!NT_STATUS_IS_OK(status)) {
5635 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5639 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5640 status = cli_ntcreate(cli1, fname, 0,
5641 FILE_READ_DATA|FILE_WRITE_DATA,
5642 open_attrs_table[j],
5643 FILE_SHARE_NONE, FILE_OVERWRITE,
5645 if (!NT_STATUS_IS_OK(status)) {
5646 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5647 if (attr_results[l].num == k) {
5648 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5649 k, open_attrs_table[i],
5650 open_attrs_table[j],
5651 fname, NT_STATUS_V(status), nt_errstr(status));
5656 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5657 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5658 k, open_attrs_table[i], open_attrs_table[j],
5663 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5669 status = cli_close(cli1, fnum1);
5670 if (!NT_STATUS_IS_OK(status)) {
5671 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5675 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5676 if (!NT_STATUS_IS_OK(status)) {
5677 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5682 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5683 k, open_attrs_table[i], open_attrs_table[j], attr );
5686 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5687 if (attr_results[l].num == k) {
5688 if (attr != attr_results[l].result_attr ||
5689 open_attrs_table[i] != attr_results[l].init_attr ||
5690 open_attrs_table[j] != attr_results[l].trunc_attr) {
5691 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5692 open_attrs_table[i],
5693 open_attrs_table[j],
5695 attr_results[l].result_attr);
5705 cli_setatr(cli1, fname, 0, 0);
5706 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5708 printf("open attr test %s.\n", correct ? "passed" : "failed");
5710 if (!torture_close_connection(cli1)) {
5716 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5717 const char *name, void *state)
5719 int *matched = (int *)state;
5720 if (matched != NULL) {
5723 return NT_STATUS_OK;
5727 test directory listing speed
5729 static bool run_dirtest(int dummy)
5732 static struct cli_state *cli;
5734 struct timeval core_start;
5735 bool correct = True;
5738 printf("starting directory test\n");
5740 if (!torture_open_connection(&cli, 0)) {
5744 cli_sockopt(cli, sockops);
5747 for (i=0;i<torture_numops;i++) {
5749 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5750 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5751 fprintf(stderr,"Failed to open %s\n", fname);
5754 cli_close(cli, fnum);
5757 core_start = timeval_current();
5760 cli_list(cli, "a*.*", 0, list_fn, &matched);
5761 printf("Matched %d\n", matched);
5764 cli_list(cli, "b*.*", 0, list_fn, &matched);
5765 printf("Matched %d\n", matched);
5768 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5769 printf("Matched %d\n", matched);
5771 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5774 for (i=0;i<torture_numops;i++) {
5776 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5777 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5780 if (!torture_close_connection(cli)) {
5784 printf("finished dirtest\n");
5789 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5792 struct cli_state *pcli = (struct cli_state *)state;
5794 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5796 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5797 return NT_STATUS_OK;
5799 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5800 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5801 printf("del_fn: failed to rmdir %s\n,", fname );
5803 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5804 printf("del_fn: failed to unlink %s\n,", fname );
5806 return NT_STATUS_OK;
5811 sees what IOCTLs are supported
5813 bool torture_ioctl_test(int dummy)
5815 static struct cli_state *cli;
5816 uint16_t device, function;
5818 const char *fname = "\\ioctl.dat";
5822 if (!torture_open_connection(&cli, 0)) {
5826 printf("starting ioctl test\n");
5828 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5830 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5831 if (!NT_STATUS_IS_OK(status)) {
5832 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5836 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5837 printf("ioctl device info: %s\n", nt_errstr(status));
5839 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5840 printf("ioctl job info: %s\n", nt_errstr(status));
5842 for (device=0;device<0x100;device++) {
5843 printf("ioctl test with device = 0x%x\n", device);
5844 for (function=0;function<0x100;function++) {
5845 uint32 code = (device<<16) | function;
5847 status = cli_raw_ioctl(cli, fnum, code, &blob);
5849 if (NT_STATUS_IS_OK(status)) {
5850 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5852 data_blob_free(&blob);
5857 if (!torture_close_connection(cli)) {
5866 tries varients of chkpath
5868 bool torture_chkpath_test(int dummy)
5870 static struct cli_state *cli;
5875 if (!torture_open_connection(&cli, 0)) {
5879 printf("starting chkpath test\n");
5881 /* cleanup from an old run */
5882 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5883 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5884 cli_rmdir(cli, "\\chkpath.dir");
5886 status = cli_mkdir(cli, "\\chkpath.dir");
5887 if (!NT_STATUS_IS_OK(status)) {
5888 printf("mkdir1 failed : %s\n", nt_errstr(status));
5892 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5893 if (!NT_STATUS_IS_OK(status)) {
5894 printf("mkdir2 failed : %s\n", nt_errstr(status));
5898 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5900 if (!NT_STATUS_IS_OK(status)) {
5901 printf("open1 failed (%s)\n", nt_errstr(status));
5904 cli_close(cli, fnum);
5906 status = cli_chkpath(cli, "\\chkpath.dir");
5907 if (!NT_STATUS_IS_OK(status)) {
5908 printf("chkpath1 failed: %s\n", nt_errstr(status));
5912 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5913 if (!NT_STATUS_IS_OK(status)) {
5914 printf("chkpath2 failed: %s\n", nt_errstr(status));
5918 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5919 if (!NT_STATUS_IS_OK(status)) {
5920 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5921 NT_STATUS_NOT_A_DIRECTORY);
5923 printf("* chkpath on a file should fail\n");
5927 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5928 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5929 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5931 printf("* chkpath on a non existant file should fail\n");
5935 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5936 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5937 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5939 printf("* chkpath on a non existent component should fail\n");
5943 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5944 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5945 cli_rmdir(cli, "\\chkpath.dir");
5947 if (!torture_close_connection(cli)) {
5954 static bool run_eatest(int dummy)
5956 static struct cli_state *cli;
5957 const char *fname = "\\eatest.txt";
5958 bool correct = True;
5962 struct ea_struct *ea_list = NULL;
5963 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5966 printf("starting eatest\n");
5968 if (!torture_open_connection(&cli, 0)) {
5969 talloc_destroy(mem_ctx);
5973 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5975 status = cli_ntcreate(cli, fname, 0,
5976 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5977 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5979 if (!NT_STATUS_IS_OK(status)) {
5980 printf("open failed - %s\n", nt_errstr(status));
5981 talloc_destroy(mem_ctx);
5985 for (i = 0; i < 10; i++) {
5986 fstring ea_name, ea_val;
5988 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5989 memset(ea_val, (char)i+1, i+1);
5990 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5991 if (!NT_STATUS_IS_OK(status)) {
5992 printf("ea_set of name %s failed - %s\n", ea_name,
5994 talloc_destroy(mem_ctx);
5999 cli_close(cli, fnum);
6000 for (i = 0; i < 10; i++) {
6001 fstring ea_name, ea_val;
6003 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6004 memset(ea_val, (char)i+1, i+1);
6005 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6006 if (!NT_STATUS_IS_OK(status)) {
6007 printf("ea_set of name %s failed - %s\n", ea_name,
6009 talloc_destroy(mem_ctx);
6014 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6015 if (!NT_STATUS_IS_OK(status)) {
6016 printf("ea_get list failed - %s\n", nt_errstr(status));
6020 printf("num_eas = %d\n", (int)num_eas);
6022 if (num_eas != 20) {
6023 printf("Should be 20 EA's stored... failing.\n");
6027 for (i = 0; i < num_eas; i++) {
6028 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6029 dump_data(0, ea_list[i].value.data,
6030 ea_list[i].value.length);
6033 /* Setting EA's to zero length deletes them. Test this */
6034 printf("Now deleting all EA's - case indepenent....\n");
6037 cli_set_ea_path(cli, fname, "", "", 0);
6039 for (i = 0; i < 20; i++) {
6041 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6042 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6043 if (!NT_STATUS_IS_OK(status)) {
6044 printf("ea_set of name %s failed - %s\n", ea_name,
6046 talloc_destroy(mem_ctx);
6052 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6053 if (!NT_STATUS_IS_OK(status)) {
6054 printf("ea_get list failed - %s\n", nt_errstr(status));
6058 printf("num_eas = %d\n", (int)num_eas);
6059 for (i = 0; i < num_eas; i++) {
6060 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6061 dump_data(0, ea_list[i].value.data,
6062 ea_list[i].value.length);
6066 printf("deleting EA's failed.\n");
6070 /* Try and delete a non existant EA. */
6071 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6072 if (!NT_STATUS_IS_OK(status)) {
6073 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6078 talloc_destroy(mem_ctx);
6079 if (!torture_close_connection(cli)) {
6086 static bool run_dirtest1(int dummy)
6089 static struct cli_state *cli;
6092 bool correct = True;
6094 printf("starting directory test\n");
6096 if (!torture_open_connection(&cli, 0)) {
6100 cli_sockopt(cli, sockops);
6102 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6103 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6104 cli_rmdir(cli, "\\LISTDIR");
6105 cli_mkdir(cli, "\\LISTDIR");
6107 /* Create 1000 files and 1000 directories. */
6108 for (i=0;i<1000;i++) {
6110 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6111 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6112 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6113 fprintf(stderr,"Failed to open %s\n", fname);
6116 cli_close(cli, fnum);
6118 for (i=0;i<1000;i++) {
6120 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6121 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6122 fprintf(stderr,"Failed to open %s\n", fname);
6127 /* Now ensure that doing an old list sees both files and directories. */
6129 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6130 printf("num_seen = %d\n", num_seen );
6131 /* We should see 100 files + 1000 directories + . and .. */
6132 if (num_seen != 2002)
6135 /* Ensure if we have the "must have" bits we only see the
6139 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6140 printf("num_seen = %d\n", num_seen );
6141 if (num_seen != 1002)
6145 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6146 printf("num_seen = %d\n", num_seen );
6147 if (num_seen != 1000)
6150 /* Delete everything. */
6151 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6152 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6153 cli_rmdir(cli, "\\LISTDIR");
6156 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6157 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6158 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6161 if (!torture_close_connection(cli)) {
6165 printf("finished dirtest1\n");
6170 static bool run_error_map_extract(int dummy) {
6172 static struct cli_state *c_dos;
6173 static struct cli_state *c_nt;
6185 /* NT-Error connection */
6187 if (!(c_nt = open_nbt_connection())) {
6191 c_nt->use_spnego = False;
6193 status = cli_negprot(c_nt);
6195 if (!NT_STATUS_IS_OK(status)) {
6196 printf("%s rejected the NT-error negprot (%s)\n", host,
6202 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6203 if (!NT_STATUS_IS_OK(status)) {
6204 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6208 /* DOS-Error connection */
6210 if (!(c_dos = open_nbt_connection())) {
6214 c_dos->use_spnego = False;
6215 c_dos->force_dos_errors = True;
6217 status = cli_negprot(c_dos);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 printf("%s rejected the DOS-error negprot (%s)\n", host,
6221 cli_shutdown(c_dos);
6225 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6226 if (!NT_STATUS_IS_OK(status)) {
6227 printf("%s rejected the DOS-error initial session setup (%s)\n",
6228 host, nt_errstr(status));
6232 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6233 fstr_sprintf(user, "%X", error);
6235 status = cli_session_setup(c_nt, user,
6236 password, strlen(password),
6237 password, strlen(password),
6239 if (NT_STATUS_IS_OK(status)) {
6240 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6243 /* Case #1: 32-bit NT errors */
6244 if (cli_is_nt_error(c_nt)) {
6245 nt_status = cli_nt_error(c_nt);
6247 printf("/** Dos error on NT connection! (%s) */\n",
6249 nt_status = NT_STATUS(0xc0000000);
6252 status = cli_session_setup(c_dos, user,
6253 password, strlen(password),
6254 password, strlen(password),
6256 if (NT_STATUS_IS_OK(status)) {
6257 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6260 /* Case #1: 32-bit NT errors */
6261 if (!cli_is_dos_error(c_dos)) {
6262 printf("/** NT error on DOS connection! (%s) */\n",
6264 errnum = errclass = 0;
6266 cli_dos_error(c_dos, &errclass, &errnum);
6269 if (NT_STATUS_V(nt_status) != error) {
6270 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6271 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6272 get_nt_error_c_code(talloc_tos(), nt_status));
6275 printf("\t{%s,\t%s,\t%s},\n",
6276 smb_dos_err_class(errclass),
6277 smb_dos_err_name(errclass, errnum),
6278 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6283 static bool run_sesssetup_bench(int dummy)
6285 static struct cli_state *c;
6286 const char *fname = "\\file.dat";
6291 if (!torture_open_connection(&c, 0)) {
6295 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6296 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6297 FILE_DELETE_ON_CLOSE, 0, &fnum);
6298 if (!NT_STATUS_IS_OK(status)) {
6299 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6303 for (i=0; i<torture_numops; i++) {
6304 status = cli_session_setup(
6306 password, strlen(password),
6307 password, strlen(password),
6309 if (!NT_STATUS_IS_OK(status)) {
6310 d_printf("(%s) cli_session_setup failed: %s\n",
6311 __location__, nt_errstr(status));
6315 d_printf("\r%d ", (int)c->vuid);
6317 status = cli_ulogoff(c);
6318 if (!NT_STATUS_IS_OK(status)) {
6319 d_printf("(%s) cli_ulogoff failed: %s\n",
6320 __location__, nt_errstr(status));
6329 static bool subst_test(const char *str, const char *user, const char *domain,
6330 uid_t uid, gid_t gid, const char *expected)
6335 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6337 if (strcmp(subst, expected) != 0) {
6338 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6339 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6348 static void chain1_open_completion(struct tevent_req *req)
6352 status = cli_open_recv(req, &fnum);
6355 d_printf("cli_open_recv returned %s: %d\n",
6357 NT_STATUS_IS_OK(status) ? fnum : -1);
6360 static void chain1_write_completion(struct tevent_req *req)
6364 status = cli_write_andx_recv(req, &written);
6367 d_printf("cli_write_andx_recv returned %s: %d\n",
6369 NT_STATUS_IS_OK(status) ? (int)written : -1);
6372 static void chain1_close_completion(struct tevent_req *req)
6375 bool *done = (bool *)tevent_req_callback_data_void(req);
6377 status = cli_close_recv(req);
6382 d_printf("cli_close returned %s\n", nt_errstr(status));
6385 static bool run_chain1(int dummy)
6387 struct cli_state *cli1;
6388 struct event_context *evt = event_context_init(NULL);
6389 struct tevent_req *reqs[3], *smbreqs[3];
6391 const char *str = "foobar";
6394 printf("starting chain1 test\n");
6395 if (!torture_open_connection(&cli1, 0)) {
6399 cli_sockopt(cli1, sockops);
6401 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6402 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6403 if (reqs[0] == NULL) return false;
6404 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6407 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6408 (const uint8_t *)str, 0, strlen(str)+1,
6409 smbreqs, 1, &smbreqs[1]);
6410 if (reqs[1] == NULL) return false;
6411 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6413 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6414 if (reqs[2] == NULL) return false;
6415 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6417 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6418 if (!NT_STATUS_IS_OK(status)) {
6423 event_loop_once(evt);
6426 torture_close_connection(cli1);
6430 static void chain2_sesssetup_completion(struct tevent_req *req)
6433 status = cli_session_setup_guest_recv(req);
6434 d_printf("sesssetup returned %s\n", nt_errstr(status));
6437 static void chain2_tcon_completion(struct tevent_req *req)
6439 bool *done = (bool *)tevent_req_callback_data_void(req);
6441 status = cli_tcon_andx_recv(req);
6442 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6446 static bool run_chain2(int dummy)
6448 struct cli_state *cli1;
6449 struct event_context *evt = event_context_init(NULL);
6450 struct tevent_req *reqs[2], *smbreqs[2];
6454 printf("starting chain2 test\n");
6455 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6456 port_to_use, Undefined, 0);
6457 if (!NT_STATUS_IS_OK(status)) {
6461 cli_sockopt(cli1, sockops);
6463 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6465 if (reqs[0] == NULL) return false;
6466 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6468 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6469 "?????", NULL, 0, &smbreqs[1]);
6470 if (reqs[1] == NULL) return false;
6471 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6473 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6474 if (!NT_STATUS_IS_OK(status)) {
6479 event_loop_once(evt);
6482 torture_close_connection(cli1);
6487 struct torture_createdel_state {
6488 struct tevent_context *ev;
6489 struct cli_state *cli;
6492 static void torture_createdel_created(struct tevent_req *subreq);
6493 static void torture_createdel_closed(struct tevent_req *subreq);
6495 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6496 struct tevent_context *ev,
6497 struct cli_state *cli,
6500 struct tevent_req *req, *subreq;
6501 struct torture_createdel_state *state;
6503 req = tevent_req_create(mem_ctx, &state,
6504 struct torture_createdel_state);
6511 subreq = cli_ntcreate_send(
6512 state, ev, cli, name, 0,
6513 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6514 FILE_ATTRIBUTE_NORMAL,
6515 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6516 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6518 if (tevent_req_nomem(subreq, req)) {
6519 return tevent_req_post(req, ev);
6521 tevent_req_set_callback(subreq, torture_createdel_created, req);
6525 static void torture_createdel_created(struct tevent_req *subreq)
6527 struct tevent_req *req = tevent_req_callback_data(
6528 subreq, struct tevent_req);
6529 struct torture_createdel_state *state = tevent_req_data(
6530 req, struct torture_createdel_state);
6534 status = cli_ntcreate_recv(subreq, &fnum);
6535 TALLOC_FREE(subreq);
6536 if (!NT_STATUS_IS_OK(status)) {
6537 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6538 nt_errstr(status)));
6539 tevent_req_nterror(req, status);
6543 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6544 if (tevent_req_nomem(subreq, req)) {
6547 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6550 static void torture_createdel_closed(struct tevent_req *subreq)
6552 struct tevent_req *req = tevent_req_callback_data(
6553 subreq, struct tevent_req);
6556 status = cli_close_recv(subreq);
6557 if (!NT_STATUS_IS_OK(status)) {
6558 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6559 tevent_req_nterror(req, status);
6562 tevent_req_done(req);
6565 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6567 return tevent_req_simple_recv_ntstatus(req);
6570 struct torture_createdels_state {
6571 struct tevent_context *ev;
6572 struct cli_state *cli;
6573 const char *base_name;
6577 struct tevent_req **reqs;
6580 static void torture_createdels_done(struct tevent_req *subreq);
6582 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6583 struct tevent_context *ev,
6584 struct cli_state *cli,
6585 const char *base_name,
6589 struct tevent_req *req;
6590 struct torture_createdels_state *state;
6593 req = tevent_req_create(mem_ctx, &state,
6594 struct torture_createdels_state);
6600 state->base_name = talloc_strdup(state, base_name);
6601 if (tevent_req_nomem(state->base_name, req)) {
6602 return tevent_req_post(req, ev);
6604 state->num_files = MAX(num_parallel, num_files);
6606 state->received = 0;
6608 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6609 if (tevent_req_nomem(state->reqs, req)) {
6610 return tevent_req_post(req, ev);
6613 for (i=0; i<num_parallel; i++) {
6616 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6618 if (tevent_req_nomem(name, req)) {
6619 return tevent_req_post(req, ev);
6621 state->reqs[i] = torture_createdel_send(
6622 state->reqs, state->ev, state->cli, name);
6623 if (tevent_req_nomem(state->reqs[i], req)) {
6624 return tevent_req_post(req, ev);
6626 name = talloc_move(state->reqs[i], &name);
6627 tevent_req_set_callback(state->reqs[i],
6628 torture_createdels_done, req);
6634 static void torture_createdels_done(struct tevent_req *subreq)
6636 struct tevent_req *req = tevent_req_callback_data(
6637 subreq, struct tevent_req);
6638 struct torture_createdels_state *state = tevent_req_data(
6639 req, struct torture_createdels_state);
6640 size_t num_parallel = talloc_array_length(state->reqs);
6645 status = torture_createdel_recv(subreq);
6646 if (!NT_STATUS_IS_OK(status)){
6647 DEBUG(10, ("torture_createdel_recv returned %s\n",
6648 nt_errstr(status)));
6649 TALLOC_FREE(subreq);
6650 tevent_req_nterror(req, status);
6654 for (i=0; i<num_parallel; i++) {
6655 if (subreq == state->reqs[i]) {
6659 if (i == num_parallel) {
6660 DEBUG(10, ("received something we did not send\n"));
6661 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6664 TALLOC_FREE(state->reqs[i]);
6666 if (state->sent >= state->num_files) {
6667 tevent_req_done(req);
6671 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6673 if (tevent_req_nomem(name, req)) {
6676 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6678 if (tevent_req_nomem(state->reqs[i], req)) {
6681 name = talloc_move(state->reqs[i], &name);
6682 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6686 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6688 return tevent_req_simple_recv_ntstatus(req);
6691 struct swallow_notify_state {
6692 struct tevent_context *ev;
6693 struct cli_state *cli;
6695 uint32_t completion_filter;
6697 bool (*fn)(uint32_t action, const char *name, void *priv);
6701 static void swallow_notify_done(struct tevent_req *subreq);
6703 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6704 struct tevent_context *ev,
6705 struct cli_state *cli,
6707 uint32_t completion_filter,
6709 bool (*fn)(uint32_t action,
6714 struct tevent_req *req, *subreq;
6715 struct swallow_notify_state *state;
6717 req = tevent_req_create(mem_ctx, &state,
6718 struct swallow_notify_state);
6725 state->completion_filter = completion_filter;
6726 state->recursive = recursive;
6730 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6731 0xffff, state->completion_filter,
6733 if (tevent_req_nomem(subreq, req)) {
6734 return tevent_req_post(req, ev);
6736 tevent_req_set_callback(subreq, swallow_notify_done, req);
6740 static void swallow_notify_done(struct tevent_req *subreq)
6742 struct tevent_req *req = tevent_req_callback_data(
6743 subreq, struct tevent_req);
6744 struct swallow_notify_state *state = tevent_req_data(
6745 req, struct swallow_notify_state);
6747 uint32_t i, num_changes;
6748 struct notify_change *changes;
6750 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6751 TALLOC_FREE(subreq);
6752 if (!NT_STATUS_IS_OK(status)) {
6753 DEBUG(10, ("cli_notify_recv returned %s\n",
6754 nt_errstr(status)));
6755 tevent_req_nterror(req, status);
6759 for (i=0; i<num_changes; i++) {
6760 state->fn(changes[i].action, changes[i].name, state->priv);
6762 TALLOC_FREE(changes);
6764 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6765 0xffff, state->completion_filter,
6767 if (tevent_req_nomem(subreq, req)) {
6770 tevent_req_set_callback(subreq, swallow_notify_done, req);
6773 static bool print_notifies(uint32_t action, const char *name, void *priv)
6775 if (DEBUGLEVEL > 5) {
6776 d_printf("%d %s\n", (int)action, name);
6781 static void notify_bench_done(struct tevent_req *req)
6783 int *num_finished = (int *)tevent_req_callback_data_void(req);
6787 static bool run_notify_bench(int dummy)
6789 const char *dname = "\\notify-bench";
6790 struct tevent_context *ev;
6793 struct tevent_req *req1;
6794 struct tevent_req *req2 = NULL;
6795 int i, num_unc_names;
6796 int num_finished = 0;
6798 printf("starting notify-bench test\n");
6800 if (use_multishare_conn) {
6802 unc_list = file_lines_load(multishare_conn_fname,
6803 &num_unc_names, 0, NULL);
6804 if (!unc_list || num_unc_names <= 0) {
6805 d_printf("Failed to load unc names list from '%s'\n",
6806 multishare_conn_fname);
6809 TALLOC_FREE(unc_list);
6814 ev = tevent_context_init(talloc_tos());
6816 d_printf("tevent_context_init failed\n");
6820 for (i=0; i<num_unc_names; i++) {
6821 struct cli_state *cli;
6824 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6826 if (base_fname == NULL) {
6830 if (!torture_open_connection(&cli, i)) {
6834 status = cli_ntcreate(cli, dname, 0,
6835 MAXIMUM_ALLOWED_ACCESS,
6836 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6838 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6841 if (!NT_STATUS_IS_OK(status)) {
6842 d_printf("Could not create %s: %s\n", dname,
6847 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6848 FILE_NOTIFY_CHANGE_FILE_NAME |
6849 FILE_NOTIFY_CHANGE_DIR_NAME |
6850 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6851 FILE_NOTIFY_CHANGE_LAST_WRITE,
6852 false, print_notifies, NULL);
6854 d_printf("Could not create notify request\n");
6858 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6859 base_fname, 10, torture_numops);
6861 d_printf("Could not create createdels request\n");
6864 TALLOC_FREE(base_fname);
6866 tevent_req_set_callback(req2, notify_bench_done,
6870 while (num_finished < num_unc_names) {
6872 ret = tevent_loop_once(ev);
6874 d_printf("tevent_loop_once failed\n");
6879 if (!tevent_req_poll(req2, ev)) {
6880 d_printf("tevent_req_poll failed\n");
6883 status = torture_createdels_recv(req2);
6884 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6889 static bool run_mangle1(int dummy)
6891 struct cli_state *cli;
6892 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6896 time_t change_time, access_time, write_time;
6900 printf("starting mangle1 test\n");
6901 if (!torture_open_connection(&cli, 0)) {
6905 cli_sockopt(cli, sockops);
6907 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6908 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6910 if (!NT_STATUS_IS_OK(status)) {
6911 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6914 cli_close(cli, fnum);
6916 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6917 if (!NT_STATUS_IS_OK(status)) {
6918 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6922 d_printf("alt_name: %s\n", alt_name);
6924 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6925 if (!NT_STATUS_IS_OK(status)) {
6926 d_printf("cli_open(%s) failed: %s\n", alt_name,
6930 cli_close(cli, fnum);
6932 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6933 &write_time, &size, &mode);
6934 if (!NT_STATUS_IS_OK(status)) {
6935 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6943 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6945 size_t *to_pull = (size_t *)priv;
6946 size_t thistime = *to_pull;
6948 thistime = MIN(thistime, n);
6949 if (thistime == 0) {
6953 memset(buf, 0, thistime);
6954 *to_pull -= thistime;
6958 static bool run_windows_write(int dummy)
6960 struct cli_state *cli1;
6964 const char *fname = "\\writetest.txt";
6965 struct timeval start_time;
6970 printf("starting windows_write test\n");
6971 if (!torture_open_connection(&cli1, 0)) {
6975 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6976 if (!NT_STATUS_IS_OK(status)) {
6977 printf("open failed (%s)\n", nt_errstr(status));
6981 cli_sockopt(cli1, sockops);
6983 start_time = timeval_current();
6985 for (i=0; i<torture_numops; i++) {
6987 off_t start = i * torture_blocksize;
6988 size_t to_pull = torture_blocksize - 1;
6990 status = cli_writeall(cli1, fnum, 0, &c,
6991 start + torture_blocksize - 1, 1, NULL);
6992 if (!NT_STATUS_IS_OK(status)) {
6993 printf("cli_write failed: %s\n", nt_errstr(status));
6997 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6998 null_source, &to_pull);
6999 if (!NT_STATUS_IS_OK(status)) {
7000 printf("cli_push returned: %s\n", nt_errstr(status));
7005 seconds = timeval_elapsed(&start_time);
7006 kbytes = (double)torture_blocksize * torture_numops;
7009 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7010 (double)seconds, (int)(kbytes/seconds));
7014 cli_close(cli1, fnum);
7015 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7016 torture_close_connection(cli1);
7020 static bool run_cli_echo(int dummy)
7022 struct cli_state *cli;
7025 printf("starting cli_echo test\n");
7026 if (!torture_open_connection(&cli, 0)) {
7029 cli_sockopt(cli, sockops);
7031 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7033 d_printf("cli_echo returned %s\n", nt_errstr(status));
7035 torture_close_connection(cli);
7036 return NT_STATUS_IS_OK(status);
7039 static bool run_uid_regression_test(int dummy)
7041 static struct cli_state *cli;
7044 bool correct = True;
7047 printf("starting uid regression test\n");
7049 if (!torture_open_connection(&cli, 0)) {
7053 cli_sockopt(cli, sockops);
7055 /* Ok - now save then logoff our current user. */
7056 old_vuid = cli->vuid;
7058 status = cli_ulogoff(cli);
7059 if (!NT_STATUS_IS_OK(status)) {
7060 d_printf("(%s) cli_ulogoff failed: %s\n",
7061 __location__, nt_errstr(status));
7066 cli->vuid = old_vuid;
7068 /* Try an operation. */
7069 status = cli_mkdir(cli, "\\uid_reg_test");
7070 if (NT_STATUS_IS_OK(status)) {
7071 d_printf("(%s) cli_mkdir succeeded\n",
7076 /* Should be bad uid. */
7077 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7078 NT_STATUS_USER_SESSION_DELETED)) {
7084 old_cnum = cli->cnum;
7086 /* Now try a SMBtdis with the invald vuid set to zero. */
7089 /* This should succeed. */
7090 status = cli_tdis(cli);
7092 if (NT_STATUS_IS_OK(status)) {
7093 d_printf("First tdis with invalid vuid should succeed.\n");
7095 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7100 cli->vuid = old_vuid;
7101 cli->cnum = old_cnum;
7103 /* This should fail. */
7104 status = cli_tdis(cli);
7105 if (NT_STATUS_IS_OK(status)) {
7106 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7110 /* Should be bad tid. */
7111 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7112 NT_STATUS_NETWORK_NAME_DELETED)) {
7118 cli_rmdir(cli, "\\uid_reg_test");
7127 static const char *illegal_chars = "*\\/?<>|\":";
7128 static char force_shortname_chars[] = " +,.[];=\177";
7130 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7131 const char *mask, void *state)
7133 struct cli_state *pcli = (struct cli_state *)state;
7135 NTSTATUS status = NT_STATUS_OK;
7137 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7139 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7140 return NT_STATUS_OK;
7142 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7143 status = cli_rmdir(pcli, fname);
7144 if (!NT_STATUS_IS_OK(status)) {
7145 printf("del_fn: failed to rmdir %s\n,", fname );
7148 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7149 if (!NT_STATUS_IS_OK(status)) {
7150 printf("del_fn: failed to unlink %s\n,", fname );
7162 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7163 const char *name, void *state)
7165 struct sn_state *s = (struct sn_state *)state;
7169 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7170 i, finfo->name, finfo->short_name);
7173 if (strchr(force_shortname_chars, i)) {
7174 if (!finfo->short_name) {
7175 /* Shortname not created when it should be. */
7176 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7177 __location__, finfo->name, i);
7180 } else if (finfo->short_name){
7181 /* Shortname created when it should not be. */
7182 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7183 __location__, finfo->short_name, finfo->name);
7187 return NT_STATUS_OK;
7190 static bool run_shortname_test(int dummy)
7192 static struct cli_state *cli;
7193 bool correct = True;
7199 printf("starting shortname test\n");
7201 if (!torture_open_connection(&cli, 0)) {
7205 cli_sockopt(cli, sockops);
7207 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7208 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7209 cli_rmdir(cli, "\\shortname");
7211 status = cli_mkdir(cli, "\\shortname");
7212 if (!NT_STATUS_IS_OK(status)) {
7213 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7214 __location__, nt_errstr(status));
7219 strlcpy(fname, "\\shortname\\", sizeof(fname));
7220 strlcat(fname, "test .txt", sizeof(fname));
7224 for (i = 32; i < 128; i++) {
7225 uint16_t fnum = (uint16_t)-1;
7229 if (strchr(illegal_chars, i)) {
7234 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7235 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7236 if (!NT_STATUS_IS_OK(status)) {
7237 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7238 __location__, fname, nt_errstr(status));
7242 cli_close(cli, fnum);
7245 status = cli_list(cli, "\\shortname\\test*.*", 0,
7246 shortname_list_fn, &s);
7247 if (s.matched != 1) {
7248 d_printf("(%s) failed to list %s: %s\n",
7249 __location__, fname, nt_errstr(status));
7254 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7255 if (!NT_STATUS_IS_OK(status)) {
7256 d_printf("(%s) failed to delete %s: %s\n",
7257 __location__, fname, nt_errstr(status));
7270 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7271 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7272 cli_rmdir(cli, "\\shortname");
7273 torture_close_connection(cli);
7277 static void pagedsearch_cb(struct tevent_req *req)
7280 struct tldap_message *msg;
7283 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7284 if (rc != TLDAP_SUCCESS) {
7285 d_printf("tldap_search_paged_recv failed: %s\n",
7286 tldap_err2string(rc));
7289 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7293 if (!tldap_entry_dn(msg, &dn)) {
7294 d_printf("tldap_entry_dn failed\n");
7297 d_printf("%s\n", dn);
7301 static bool run_tldap(int dummy)
7303 struct tldap_context *ld;
7306 struct sockaddr_storage addr;
7307 struct tevent_context *ev;
7308 struct tevent_req *req;
7312 if (!resolve_name(host, &addr, 0, false)) {
7313 d_printf("could not find host %s\n", host);
7316 status = open_socket_out(&addr, 389, 9999, &fd);
7317 if (!NT_STATUS_IS_OK(status)) {
7318 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7322 ld = tldap_context_create(talloc_tos(), fd);
7325 d_printf("tldap_context_create failed\n");
7329 rc = tldap_fetch_rootdse(ld);
7330 if (rc != TLDAP_SUCCESS) {
7331 d_printf("tldap_fetch_rootdse failed: %s\n",
7332 tldap_errstr(talloc_tos(), ld, rc));
7336 basedn = tldap_talloc_single_attribute(
7337 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7338 if (basedn == NULL) {
7339 d_printf("no defaultNamingContext\n");
7342 d_printf("defaultNamingContext: %s\n", basedn);
7344 ev = tevent_context_init(talloc_tos());
7346 d_printf("tevent_context_init failed\n");
7350 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7351 TLDAP_SCOPE_SUB, "(objectclass=*)",
7353 NULL, 0, NULL, 0, 0, 0, 0, 5);
7355 d_printf("tldap_search_paged_send failed\n");
7358 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7360 tevent_req_poll(req, ev);
7364 /* test search filters against rootDSE */
7365 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7366 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7368 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7369 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7370 talloc_tos(), NULL, NULL);
7371 if (rc != TLDAP_SUCCESS) {
7372 d_printf("tldap_search with complex filter failed: %s\n",
7373 tldap_errstr(talloc_tos(), ld, rc));
7381 /* Torture test to ensure no regression of :
7382 https://bugzilla.samba.org/show_bug.cgi?id=7084
7385 static bool run_dir_createtime(int dummy)
7387 struct cli_state *cli;
7388 const char *dname = "\\testdir";
7389 const char *fname = "\\testdir\\testfile";
7391 struct timespec create_time;
7392 struct timespec create_time1;
7396 if (!torture_open_connection(&cli, 0)) {
7400 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7401 cli_rmdir(cli, dname);
7403 status = cli_mkdir(cli, dname);
7404 if (!NT_STATUS_IS_OK(status)) {
7405 printf("mkdir failed: %s\n", nt_errstr(status));
7409 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7411 if (!NT_STATUS_IS_OK(status)) {
7412 printf("cli_qpathinfo2 returned %s\n",
7417 /* Sleep 3 seconds, then create a file. */
7420 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7422 if (!NT_STATUS_IS_OK(status)) {
7423 printf("cli_open failed: %s\n", nt_errstr(status));
7427 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7429 if (!NT_STATUS_IS_OK(status)) {
7430 printf("cli_qpathinfo2 (2) returned %s\n",
7435 if (timespec_compare(&create_time1, &create_time)) {
7436 printf("run_dir_createtime: create time was updated (error)\n");
7438 printf("run_dir_createtime: create time was not updated (correct)\n");
7444 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7445 cli_rmdir(cli, dname);
7446 if (!torture_close_connection(cli)) {
7453 static bool run_streamerror(int dummy)
7455 struct cli_state *cli;
7456 const char *dname = "\\testdir";
7457 const char *streamname =
7458 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7460 time_t change_time, access_time, write_time;
7462 uint16_t mode, fnum;
7465 if (!torture_open_connection(&cli, 0)) {
7469 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7470 cli_rmdir(cli, dname);
7472 status = cli_mkdir(cli, dname);
7473 if (!NT_STATUS_IS_OK(status)) {
7474 printf("mkdir failed: %s\n", nt_errstr(status));
7478 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7480 status = cli_nt_error(cli);
7482 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7483 printf("pathinfo returned %s, expected "
7484 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7489 status = cli_ntcreate(cli, streamname, 0x16,
7490 FILE_READ_DATA|FILE_READ_EA|
7491 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7492 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7493 FILE_OPEN, 0, 0, &fnum);
7495 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7496 printf("ntcreate returned %s, expected "
7497 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7503 cli_rmdir(cli, dname);
7507 static bool run_local_substitute(int dummy)
7511 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7512 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7513 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7514 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7515 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7516 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7517 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7518 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7520 /* Different captialization rules in sub_basic... */
7522 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7528 static bool run_local_base64(int dummy)
7533 for (i=1; i<2000; i++) {
7534 DATA_BLOB blob1, blob2;
7537 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7539 generate_random_buffer(blob1.data, blob1.length);
7541 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7543 d_fprintf(stderr, "base64_encode_data_blob failed "
7544 "for %d bytes\n", i);
7547 blob2 = base64_decode_data_blob(b64);
7550 if (data_blob_cmp(&blob1, &blob2)) {
7551 d_fprintf(stderr, "data_blob_cmp failed for %d "
7555 TALLOC_FREE(blob1.data);
7556 data_blob_free(&blob2);
7561 static bool run_local_gencache(int dummy)
7567 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7568 d_printf("%s: gencache_set() failed\n", __location__);
7572 if (!gencache_get("foo", NULL, NULL)) {
7573 d_printf("%s: gencache_get() failed\n", __location__);
7577 if (!gencache_get("foo", &val, &tm)) {
7578 d_printf("%s: gencache_get() failed\n", __location__);
7582 if (strcmp(val, "bar") != 0) {
7583 d_printf("%s: gencache_get() returned %s, expected %s\n",
7584 __location__, val, "bar");
7591 if (!gencache_del("foo")) {
7592 d_printf("%s: gencache_del() failed\n", __location__);
7595 if (gencache_del("foo")) {
7596 d_printf("%s: second gencache_del() succeeded\n",
7601 if (gencache_get("foo", &val, &tm)) {
7602 d_printf("%s: gencache_get() on deleted entry "
7603 "succeeded\n", __location__);
7607 blob = data_blob_string_const_null("bar");
7608 tm = time(NULL) + 60;
7610 if (!gencache_set_data_blob("foo", &blob, tm)) {
7611 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7615 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7616 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7620 if (strcmp((const char *)blob.data, "bar") != 0) {
7621 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7622 __location__, (const char *)blob.data, "bar");
7623 data_blob_free(&blob);
7627 data_blob_free(&blob);
7629 if (!gencache_del("foo")) {
7630 d_printf("%s: gencache_del() failed\n", __location__);
7633 if (gencache_del("foo")) {
7634 d_printf("%s: second gencache_del() succeeded\n",
7639 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7640 d_printf("%s: gencache_get_data_blob() on deleted entry "
7641 "succeeded\n", __location__);
7648 static bool rbt_testval(struct db_context *db, const char *key,
7651 struct db_record *rec;
7652 TDB_DATA data = string_tdb_data(value);
7656 rec = db->fetch_locked(db, db, string_tdb_data(key));
7658 d_fprintf(stderr, "fetch_locked failed\n");
7661 status = rec->store(rec, data, 0);
7662 if (!NT_STATUS_IS_OK(status)) {
7663 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7668 rec = db->fetch_locked(db, db, string_tdb_data(key));
7670 d_fprintf(stderr, "second fetch_locked failed\n");
7673 if ((rec->value.dsize != data.dsize)
7674 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7675 d_fprintf(stderr, "Got wrong data back\n");
7685 static bool run_local_rbtree(int dummy)
7687 struct db_context *db;
7691 db = db_open_rbt(NULL);
7694 d_fprintf(stderr, "db_open_rbt failed\n");
7698 for (i=0; i<1000; i++) {
7701 if (asprintf(&key, "key%ld", random()) == -1) {
7704 if (asprintf(&value, "value%ld", random()) == -1) {
7709 if (!rbt_testval(db, key, value)) {
7716 if (asprintf(&value, "value%ld", random()) == -1) {
7721 if (!rbt_testval(db, key, value)) {
7740 local test for character set functions
7742 This is a very simple test for the functionality in convert_string_error()
7744 static bool run_local_convert_string(int dummy)
7746 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7747 const char *test_strings[2] = { "March", "M\303\244rz" };
7751 for (i=0; i<2; i++) {
7752 const char *str = test_strings[i];
7753 int len = strlen(str);
7754 size_t converted_size;
7757 memset(dst, 'X', sizeof(dst));
7759 /* first try with real source length */
7760 ret = convert_string_error(CH_UNIX, CH_UTF8,
7765 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7769 if (converted_size != len) {
7770 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7771 str, len, (int)converted_size);
7775 if (strncmp(str, dst, converted_size) != 0) {
7776 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7780 if (strlen(str) != converted_size) {
7781 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7782 (int)strlen(str), (int)converted_size);
7786 if (dst[converted_size] != 'X') {
7787 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7791 /* now with srclen==-1, this causes the nul to be
7793 ret = convert_string_error(CH_UNIX, CH_UTF8,
7798 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7802 if (converted_size != len+1) {
7803 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7804 str, len, (int)converted_size);
7808 if (strncmp(str, dst, converted_size) != 0) {
7809 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7813 if (len+1 != converted_size) {
7814 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7815 len+1, (int)converted_size);
7819 if (dst[converted_size] != 'X') {
7820 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7827 TALLOC_FREE(tmp_ctx);
7830 TALLOC_FREE(tmp_ctx);
7835 struct talloc_dict_test {
7839 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7841 int *count = (int *)priv;
7846 static bool run_local_talloc_dict(int dummy)
7848 struct talloc_dict *dict;
7849 struct talloc_dict_test *t;
7852 dict = talloc_dict_init(talloc_tos());
7857 t = talloc(talloc_tos(), struct talloc_dict_test);
7864 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7869 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7882 static bool run_local_string_to_sid(int dummy) {
7885 if (string_to_sid(&sid, "S--1-5-32-545")) {
7886 printf("allowing S--1-5-32-545\n");
7889 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7890 printf("allowing S-1-5-32-+545\n");
7893 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")) {
7894 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7897 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7898 printf("allowing S-1-5-32-545-abc\n");
7901 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7902 printf("could not parse S-1-5-32-545\n");
7905 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7906 printf("mis-parsed S-1-5-32-545 as %s\n",
7907 sid_string_tos(&sid));
7913 static bool run_local_binary_to_sid(int dummy) {
7914 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7915 static const char good_binary_sid[] = {
7916 0x1, /* revision number */
7918 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7919 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7920 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7936 static const char long_binary_sid[] = {
7937 0x1, /* revision number */
7939 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7940 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7941 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7942 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7943 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7944 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7945 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7946 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7947 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7948 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7949 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7950 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7951 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7952 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7953 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7954 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7955 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7956 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7957 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7960 static const char long_binary_sid2[] = {
7961 0x1, /* revision number */
7963 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7964 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7965 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7966 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7967 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7968 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7969 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7970 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7971 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7972 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7973 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7974 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7975 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7976 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7977 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7978 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7979 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7980 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7981 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7982 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7983 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7984 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7985 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7986 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7987 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7988 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7989 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7990 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7991 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7992 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7993 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7994 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7995 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7998 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8001 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8004 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8010 /* Split a path name into filename and stream name components. Canonicalise
8011 * such that an implicit $DATA token is always explicit.
8013 * The "specification" of this function can be found in the
8014 * run_local_stream_name() function in torture.c, I've tried those
8015 * combinations against a W2k3 server.
8018 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8019 char **pbase, char **pstream)
8022 char *stream = NULL;
8023 char *sname; /* stream name */
8024 const char *stype; /* stream type */
8026 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8028 sname = strchr_m(fname, ':');
8030 if (lp_posix_pathnames() || (sname == NULL)) {
8031 if (pbase != NULL) {
8032 base = talloc_strdup(mem_ctx, fname);
8033 NT_STATUS_HAVE_NO_MEMORY(base);
8038 if (pbase != NULL) {
8039 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8040 NT_STATUS_HAVE_NO_MEMORY(base);
8045 stype = strchr_m(sname, ':');
8047 if (stype == NULL) {
8048 sname = talloc_strdup(mem_ctx, sname);
8052 if (strcasecmp_m(stype, ":$DATA") != 0) {
8054 * If there is an explicit stream type, so far we only
8055 * allow $DATA. Is there anything else allowed? -- vl
8057 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8059 return NT_STATUS_OBJECT_NAME_INVALID;
8061 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8065 if (sname == NULL) {
8067 return NT_STATUS_NO_MEMORY;
8070 if (sname[0] == '\0') {
8072 * no stream name, so no stream
8077 if (pstream != NULL) {
8078 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8079 if (stream == NULL) {
8082 return NT_STATUS_NO_MEMORY;
8085 * upper-case the type field
8087 strupper_m(strchr_m(stream, ':')+1);
8091 if (pbase != NULL) {
8094 if (pstream != NULL) {
8097 return NT_STATUS_OK;
8100 static bool test_stream_name(const char *fname, const char *expected_base,
8101 const char *expected_stream,
8102 NTSTATUS expected_status)
8106 char *stream = NULL;
8108 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8109 if (!NT_STATUS_EQUAL(status, expected_status)) {
8113 if (!NT_STATUS_IS_OK(status)) {
8117 if (base == NULL) goto error;
8119 if (strcmp(expected_base, base) != 0) goto error;
8121 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8122 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8124 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8128 TALLOC_FREE(stream);
8132 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8133 fname, expected_base ? expected_base : "<NULL>",
8134 expected_stream ? expected_stream : "<NULL>",
8135 nt_errstr(expected_status));
8136 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8137 base ? base : "<NULL>", stream ? stream : "<NULL>",
8140 TALLOC_FREE(stream);
8144 static bool run_local_stream_name(int dummy)
8148 ret &= test_stream_name(
8149 "bla", "bla", NULL, NT_STATUS_OK);
8150 ret &= test_stream_name(
8151 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8152 ret &= test_stream_name(
8153 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8154 ret &= test_stream_name(
8155 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8156 ret &= test_stream_name(
8157 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8158 ret &= test_stream_name(
8159 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8160 ret &= test_stream_name(
8161 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8162 ret &= test_stream_name(
8163 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8168 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8170 if (a.length != b.length) {
8171 printf("a.length=%d != b.length=%d\n",
8172 (int)a.length, (int)b.length);
8175 if (memcmp(a.data, b.data, a.length) != 0) {
8176 printf("a.data and b.data differ\n");
8182 static bool run_local_memcache(int dummy)
8184 struct memcache *cache;
8186 DATA_BLOB d1, d2, d3;
8187 DATA_BLOB v1, v2, v3;
8189 TALLOC_CTX *mem_ctx;
8191 size_t size1, size2;
8194 cache = memcache_init(NULL, 100);
8196 if (cache == NULL) {
8197 printf("memcache_init failed\n");
8201 d1 = data_blob_const("d1", 2);
8202 d2 = data_blob_const("d2", 2);
8203 d3 = data_blob_const("d3", 2);
8205 k1 = data_blob_const("d1", 2);
8206 k2 = data_blob_const("d2", 2);
8208 memcache_add(cache, STAT_CACHE, k1, d1);
8209 memcache_add(cache, GETWD_CACHE, k2, d2);
8211 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8212 printf("could not find k1\n");
8215 if (!data_blob_equal(d1, v1)) {
8219 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8220 printf("could not find k2\n");
8223 if (!data_blob_equal(d2, v2)) {
8227 memcache_add(cache, STAT_CACHE, k1, d3);
8229 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8230 printf("could not find replaced k1\n");
8233 if (!data_blob_equal(d3, v3)) {
8237 memcache_add(cache, GETWD_CACHE, k1, d1);
8239 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8240 printf("Did find k2, should have been purged\n");
8246 cache = memcache_init(NULL, 0);
8248 mem_ctx = talloc_init("foo");
8250 str1 = talloc_strdup(mem_ctx, "string1");
8251 str2 = talloc_strdup(mem_ctx, "string2");
8253 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8254 data_blob_string_const("torture"), &str1);
8255 size1 = talloc_total_size(cache);
8257 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8258 data_blob_string_const("torture"), &str2);
8259 size2 = talloc_total_size(cache);
8261 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8263 if (size2 > size1) {
8264 printf("memcache leaks memory!\n");
8274 static void wbclient_done(struct tevent_req *req)
8277 struct winbindd_response *wb_resp;
8278 int *i = (int *)tevent_req_callback_data_void(req);
8280 wbc_err = wb_trans_recv(req, req, &wb_resp);
8283 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8286 static bool run_local_wbclient(int dummy)
8288 struct event_context *ev;
8289 struct wb_context **wb_ctx;
8290 struct winbindd_request wb_req;
8291 bool result = false;
8294 BlockSignals(True, SIGPIPE);
8296 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8301 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8302 if (wb_ctx == NULL) {
8306 ZERO_STRUCT(wb_req);
8307 wb_req.cmd = WINBINDD_PING;
8309 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8311 for (i=0; i<nprocs; i++) {
8312 wb_ctx[i] = wb_context_init(ev, NULL);
8313 if (wb_ctx[i] == NULL) {
8316 for (j=0; j<torture_numops; j++) {
8317 struct tevent_req *req;
8318 req = wb_trans_send(ev, ev, wb_ctx[i],
8319 (j % 2) == 0, &wb_req);
8323 tevent_req_set_callback(req, wbclient_done, &i);
8329 while (i < nprocs * torture_numops) {
8330 event_loop_once(ev);
8339 static void getaddrinfo_finished(struct tevent_req *req)
8341 char *name = (char *)tevent_req_callback_data_void(req);
8342 struct addrinfo *ainfo;
8345 res = getaddrinfo_recv(req, &ainfo);
8347 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8350 d_printf("gai(%s) succeeded\n", name);
8351 freeaddrinfo(ainfo);
8354 static bool run_getaddrinfo_send(int dummy)
8356 TALLOC_CTX *frame = talloc_stackframe();
8357 struct fncall_context *ctx;
8358 struct tevent_context *ev;
8359 bool result = false;
8360 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8361 "www.slashdot.org", "heise.de" };
8362 struct tevent_req *reqs[4];
8365 ev = event_context_init(frame);
8370 ctx = fncall_context_init(frame, 4);
8372 for (i=0; i<ARRAY_SIZE(names); i++) {
8373 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8375 if (reqs[i] == NULL) {
8378 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8379 discard_const_p(void, names[i]));
8382 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8383 tevent_loop_once(ev);
8392 static bool dbtrans_inc(struct db_context *db)
8394 struct db_record *rec;
8399 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8401 printf(__location__ "fetch_lock failed\n");
8405 if (rec->value.dsize != sizeof(uint32_t)) {
8406 printf(__location__ "value.dsize = %d\n",
8407 (int)rec->value.dsize);
8411 val = (uint32_t *)rec->value.dptr;
8414 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8417 if (!NT_STATUS_IS_OK(status)) {
8418 printf(__location__ "store failed: %s\n",
8429 static bool run_local_dbtrans(int dummy)
8431 struct db_context *db;
8432 struct db_record *rec;
8437 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8438 O_RDWR|O_CREAT, 0600);
8440 printf("Could not open transtest.db\n");
8444 res = db->transaction_start(db);
8446 printf(__location__ "transaction_start failed\n");
8450 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8452 printf(__location__ "fetch_lock failed\n");
8456 if (rec->value.dptr == NULL) {
8458 status = rec->store(
8459 rec, make_tdb_data((uint8_t *)&initial,
8462 if (!NT_STATUS_IS_OK(status)) {
8463 printf(__location__ "store returned %s\n",
8471 res = db->transaction_commit(db);
8473 printf(__location__ "transaction_commit failed\n");
8481 res = db->transaction_start(db);
8483 printf(__location__ "transaction_start failed\n");
8487 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8488 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8492 for (i=0; i<10; i++) {
8493 if (!dbtrans_inc(db)) {
8498 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8499 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8503 if (val2 != val + 10) {
8504 printf(__location__ "val=%d, val2=%d\n",
8505 (int)val, (int)val2);
8509 printf("val2=%d\r", val2);
8511 res = db->transaction_commit(db);
8513 printf(__location__ "transaction_commit failed\n");
8523 * Just a dummy test to be run under a debugger. There's no real way
8524 * to inspect the tevent_select specific function from outside of
8528 static bool run_local_tevent_select(int dummy)
8530 struct tevent_context *ev;
8531 struct tevent_fd *fd1, *fd2;
8532 bool result = false;
8534 ev = tevent_context_init_byname(NULL, "select");
8536 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8540 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8542 d_fprintf(stderr, "tevent_add_fd failed\n");
8545 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8547 d_fprintf(stderr, "tevent_add_fd failed\n");
8552 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8554 d_fprintf(stderr, "tevent_add_fd failed\n");
8564 static double create_procs(bool (*fn)(int), bool *result)
8567 volatile pid_t *child_status;
8568 volatile bool *child_status_out;
8571 struct timeval start;
8575 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8576 if (!child_status) {
8577 printf("Failed to setup shared memory\n");
8581 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8582 if (!child_status_out) {
8583 printf("Failed to setup result status shared memory\n");
8587 for (i = 0; i < nprocs; i++) {
8588 child_status[i] = 0;
8589 child_status_out[i] = True;
8592 start = timeval_current();
8594 for (i=0;i<nprocs;i++) {
8597 pid_t mypid = getpid();
8598 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8600 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8603 if (torture_open_connection(¤t_cli, i)) break;
8605 printf("pid %d failed to start\n", (int)getpid());
8611 child_status[i] = getpid();
8613 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8615 child_status_out[i] = fn(i);
8622 for (i=0;i<nprocs;i++) {
8623 if (child_status[i]) synccount++;
8625 if (synccount == nprocs) break;
8627 } while (timeval_elapsed(&start) < 30);
8629 if (synccount != nprocs) {
8630 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8632 return timeval_elapsed(&start);
8635 /* start the client load */
8636 start = timeval_current();
8638 for (i=0;i<nprocs;i++) {
8639 child_status[i] = 0;
8642 printf("%d clients started\n", nprocs);
8644 for (i=0;i<nprocs;i++) {
8645 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8650 for (i=0;i<nprocs;i++) {
8651 if (!child_status_out[i]) {
8655 return timeval_elapsed(&start);
8658 #define FLAG_MULTIPROC 1
8665 {"FDPASS", run_fdpasstest, 0},
8666 {"LOCK1", run_locktest1, 0},
8667 {"LOCK2", run_locktest2, 0},
8668 {"LOCK3", run_locktest3, 0},
8669 {"LOCK4", run_locktest4, 0},
8670 {"LOCK5", run_locktest5, 0},
8671 {"LOCK6", run_locktest6, 0},
8672 {"LOCK7", run_locktest7, 0},
8673 {"LOCK8", run_locktest8, 0},
8674 {"LOCK9", run_locktest9, 0},
8675 {"UNLINK", run_unlinktest, 0},
8676 {"BROWSE", run_browsetest, 0},
8677 {"ATTR", run_attrtest, 0},
8678 {"TRANS2", run_trans2test, 0},
8679 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8680 {"TORTURE",run_torture, FLAG_MULTIPROC},
8681 {"RANDOMIPC", run_randomipc, 0},
8682 {"NEGNOWAIT", run_negprot_nowait, 0},
8683 {"NBENCH", run_nbench, 0},
8684 {"NBENCH2", run_nbench2, 0},
8685 {"OPLOCK1", run_oplock1, 0},
8686 {"OPLOCK2", run_oplock2, 0},
8687 {"OPLOCK4", run_oplock4, 0},
8688 {"DIR", run_dirtest, 0},
8689 {"DIR1", run_dirtest1, 0},
8690 {"DIR-CREATETIME", run_dir_createtime, 0},
8691 {"DENY1", torture_denytest1, 0},
8692 {"DENY2", torture_denytest2, 0},
8693 {"TCON", run_tcon_test, 0},
8694 {"TCONDEV", run_tcon_devtype_test, 0},
8695 {"RW1", run_readwritetest, 0},
8696 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8697 {"RW3", run_readwritelarge, 0},
8698 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8699 {"OPEN", run_opentest, 0},
8700 {"POSIX", run_simple_posix_open_test, 0},
8701 {"POSIX-APPEND", run_posix_append, 0},
8702 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8703 {"ASYNC-ECHO", run_async_echo, 0},
8704 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8705 { "SHORTNAME-TEST", run_shortname_test, 0},
8706 { "ADDRCHANGE", run_addrchange, 0},
8708 {"OPENATTR", run_openattrtest, 0},
8710 {"XCOPY", run_xcopy, 0},
8711 {"RENAME", run_rename, 0},
8712 {"DELETE", run_deletetest, 0},
8713 {"DELETE-LN", run_deletetest_ln, 0},
8714 {"PROPERTIES", run_properties, 0},
8715 {"MANGLE", torture_mangle, 0},
8716 {"MANGLE1", run_mangle1, 0},
8717 {"W2K", run_w2ktest, 0},
8718 {"TRANS2SCAN", torture_trans2_scan, 0},
8719 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8720 {"UTABLE", torture_utable, 0},
8721 {"CASETABLE", torture_casetable, 0},
8722 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8723 {"PIPE_NUMBER", run_pipe_number, 0},
8724 {"TCON2", run_tcon2_test, 0},
8725 {"IOCTL", torture_ioctl_test, 0},
8726 {"CHKPATH", torture_chkpath_test, 0},
8727 {"FDSESS", run_fdsesstest, 0},
8728 { "EATEST", run_eatest, 0},
8729 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8730 { "CHAIN1", run_chain1, 0},
8731 { "CHAIN2", run_chain2, 0},
8732 { "WINDOWS-WRITE", run_windows_write, 0},
8733 { "NTTRANS-CREATE", run_nttrans_create, 0},
8734 { "CLI_ECHO", run_cli_echo, 0},
8735 { "GETADDRINFO", run_getaddrinfo_send, 0},
8736 { "TLDAP", run_tldap },
8737 { "STREAMERROR", run_streamerror },
8738 { "NOTIFY-BENCH", run_notify_bench },
8739 { "BAD-NBT-SESSION", run_bad_nbt_session },
8740 { "SMB-ANY-CONNECT", run_smb_any_connect },
8741 { "NOTIFY-ONLINE", run_notify_online },
8742 { "SMB2-BASIC", run_smb2_basic },
8743 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8744 { "LOCAL-GENCACHE", run_local_gencache, 0},
8745 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8746 { "LOCAL-BASE64", run_local_base64, 0},
8747 { "LOCAL-RBTREE", run_local_rbtree, 0},
8748 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8749 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8750 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8751 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8752 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8753 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8754 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8755 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8760 /****************************************************************************
8761 run a specified test or "ALL"
8762 ****************************************************************************/
8763 static bool run_test(const char *name)
8770 if (strequal(name,"ALL")) {
8771 for (i=0;torture_ops[i].name;i++) {
8772 run_test(torture_ops[i].name);
8777 for (i=0;torture_ops[i].name;i++) {
8778 fstr_sprintf(randomfname, "\\XX%x",
8779 (unsigned)random());
8781 if (strequal(name, torture_ops[i].name)) {
8783 printf("Running %s\n", name);
8784 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8785 t = create_procs(torture_ops[i].fn, &result);
8788 printf("TEST %s FAILED!\n", name);
8791 struct timeval start;
8792 start = timeval_current();
8793 if (!torture_ops[i].fn(0)) {
8795 printf("TEST %s FAILED!\n", name);
8797 t = timeval_elapsed(&start);
8799 printf("%s took %g secs\n\n", name, t);
8804 printf("Did not find a test named %s\n", name);
8812 static void usage(void)
8816 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8817 printf("Please use samba4 torture.\n\n");
8819 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8821 printf("\t-d debuglevel\n");
8822 printf("\t-U user%%pass\n");
8823 printf("\t-k use kerberos\n");
8824 printf("\t-N numprocs\n");
8825 printf("\t-n my_netbios_name\n");
8826 printf("\t-W workgroup\n");
8827 printf("\t-o num_operations\n");
8828 printf("\t-O socket_options\n");
8829 printf("\t-m maximum protocol\n");
8830 printf("\t-L use oplocks\n");
8831 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8832 printf("\t-A showall\n");
8833 printf("\t-p port\n");
8834 printf("\t-s seed\n");
8835 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8836 printf("\t-f filename filename to test\n");
8839 printf("tests are:");
8840 for (i=0;torture_ops[i].name;i++) {
8841 printf(" %s", torture_ops[i].name);
8845 printf("default test is ALL\n");
8850 /****************************************************************************
8852 ****************************************************************************/
8853 int main(int argc,char *argv[])
8859 bool correct = True;
8860 TALLOC_CTX *frame = talloc_stackframe();
8861 int seed = time(NULL);
8863 #ifdef HAVE_SETBUFFER
8864 setbuffer(stdout, NULL, 0);
8867 setup_logging("smbtorture", DEBUG_STDOUT);
8871 if (is_default_dyn_CONFIGFILE()) {
8872 if(getenv("SMB_CONF_PATH")) {
8873 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8876 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8883 for(p = argv[1]; *p; p++)
8887 if (strncmp(argv[1], "//", 2)) {
8891 fstrcpy(host, &argv[1][2]);
8892 p = strchr_m(&host[2],'/');
8897 fstrcpy(share, p+1);
8899 fstrcpy(myname, get_myname(talloc_tos()));
8901 fprintf(stderr, "Failed to get my hostname.\n");
8905 if (*username == 0 && getenv("LOGNAME")) {
8906 fstrcpy(username,getenv("LOGNAME"));
8912 fstrcpy(workgroup, lp_workgroup());
8914 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8918 port_to_use = atoi(optarg);
8921 seed = atoi(optarg);
8924 fstrcpy(workgroup,optarg);
8927 max_protocol = interpret_protocol(optarg, max_protocol);
8930 nprocs = atoi(optarg);
8933 torture_numops = atoi(optarg);
8936 lp_set_cmdline("log level", optarg);
8945 local_path = optarg;
8948 torture_showall = True;
8951 fstrcpy(myname, optarg);
8954 client_txt = optarg;
8961 use_kerberos = True;
8963 d_printf("No kerberos support compiled in\n");
8969 fstrcpy(username,optarg);
8970 p = strchr_m(username,'%');
8973 fstrcpy(password, p+1);
8978 fstrcpy(multishare_conn_fname, optarg);
8979 use_multishare_conn = True;
8982 torture_blocksize = atoi(optarg);
8985 test_filename = SMB_STRDUP(optarg);
8988 printf("Unknown option %c (%d)\n", (char)opt, opt);
8993 d_printf("using seed %d\n", seed);
8997 if(use_kerberos && !gotuser) gotpass = True;
9000 p = getpass("Password:");
9002 fstrcpy(password, p);
9007 printf("host=%s share=%s user=%s myname=%s\n",
9008 host, share, username, myname);
9010 if (argc == optind) {
9011 correct = run_test("ALL");
9013 for (i=optind;i<argc;i++) {
9014 if (!run_test(argv[i])) {