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 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1647 printf("lock1 failed (%s)\n", cli_errstr(cli));
1651 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1652 printf("WRITE lock1 succeeded! This is a locking bug\n");
1655 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1656 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1659 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1660 printf("WRITE lock2 succeeded! This is a locking bug\n");
1663 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1664 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1667 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1668 printf("READ lock2 succeeded! This is a locking bug\n");
1671 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1672 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1675 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1676 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1679 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1680 printf("unlock at 100 succeeded! This is a locking bug\n");
1684 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1685 printf("unlock1 succeeded! This is a locking bug\n");
1688 if (!check_error(__LINE__, cli,
1690 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1693 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1694 printf("unlock2 succeeded! This is a locking bug\n");
1697 if (!check_error(__LINE__, cli,
1699 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1702 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1703 printf("lock3 succeeded! This is a locking bug\n");
1706 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1711 status = cli_close(cli, fnum1);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 printf("close1 failed (%s)\n", nt_errstr(status));
1717 status = cli_close(cli, fnum2);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 printf("close2 failed (%s)\n", nt_errstr(status));
1723 status = cli_close(cli, fnum3);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 printf("close3 failed (%s)\n", nt_errstr(status));
1729 if (!torture_close_connection(cli)) {
1733 printf("locktest2 finished\n");
1740 This test checks that
1742 1) the server supports the full offset range in lock requests
1744 static bool run_locktest3(int dummy)
1746 static struct cli_state *cli1, *cli2;
1747 const char *fname = "\\lockt3.lck";
1748 uint16_t fnum1, fnum2;
1751 bool correct = True;
1754 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1756 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1759 cli_sockopt(cli1, sockops);
1760 cli_sockopt(cli2, sockops);
1762 printf("starting locktest3\n");
1764 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1766 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1768 if (!NT_STATUS_IS_OK(status)) {
1769 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1773 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1774 if (!NT_STATUS_IS_OK(status)) {
1775 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1779 for (offset=i=0;i<torture_numops;i++) {
1781 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1782 printf("lock1 %d failed (%s)\n",
1788 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1789 printf("lock2 %d failed (%s)\n",
1796 for (offset=i=0;i<torture_numops;i++) {
1799 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1800 printf("error: lock1 %d succeeded!\n", i);
1804 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1805 printf("error: lock2 %d succeeded!\n", i);
1809 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1810 printf("error: lock3 %d succeeded!\n", i);
1814 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1815 printf("error: lock4 %d succeeded!\n", i);
1820 for (offset=i=0;i<torture_numops;i++) {
1823 status = cli_unlock(cli1, fnum1, offset-1, 1);
1824 if (!NT_STATUS_IS_OK(status)) {
1825 printf("unlock1 %d failed (%s)\n",
1831 status = cli_unlock(cli2, fnum2, offset-2, 1);
1832 if (!NT_STATUS_IS_OK(status)) {
1833 printf("unlock2 %d failed (%s)\n",
1840 status = cli_close(cli1, fnum1);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 printf("close1 failed (%s)\n", nt_errstr(status));
1846 status = cli_close(cli2, fnum2);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 printf("close2 failed (%s)\n", nt_errstr(status));
1852 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 printf("unlink failed (%s)\n", nt_errstr(status));
1858 if (!torture_close_connection(cli1)) {
1862 if (!torture_close_connection(cli2)) {
1866 printf("finished locktest3\n");
1871 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1872 printf("** "); correct = False; \
1876 looks at overlapping locks
1878 static bool run_locktest4(int dummy)
1880 static struct cli_state *cli1, *cli2;
1881 const char *fname = "\\lockt4.lck";
1882 uint16_t fnum1, fnum2, f;
1885 bool correct = True;
1888 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1892 cli_sockopt(cli1, sockops);
1893 cli_sockopt(cli2, sockops);
1895 printf("starting locktest4\n");
1897 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1899 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1900 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1902 memset(buf, 0, sizeof(buf));
1904 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1906 if (!NT_STATUS_IS_OK(status)) {
1907 printf("Failed to create file: %s\n", nt_errstr(status));
1912 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1913 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1914 EXPECTED(ret, False);
1915 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1917 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1918 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1919 EXPECTED(ret, True);
1920 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1922 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1923 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1924 EXPECTED(ret, False);
1925 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1927 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1928 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1929 EXPECTED(ret, True);
1930 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1932 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1933 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1934 EXPECTED(ret, False);
1935 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1937 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1938 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1939 EXPECTED(ret, True);
1940 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1942 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1943 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1944 EXPECTED(ret, True);
1945 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1947 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1948 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1949 EXPECTED(ret, False);
1950 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1952 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1953 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1954 EXPECTED(ret, False);
1955 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1957 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1958 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1959 EXPECTED(ret, True);
1960 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1962 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1963 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1964 EXPECTED(ret, False);
1965 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1967 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1968 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1969 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1970 EXPECTED(ret, False);
1971 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1974 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1975 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1976 EXPECTED(ret, False);
1977 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1979 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1981 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1983 ret = NT_STATUS_IS_OK(status);
1985 EXPECTED(ret, False);
1986 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1989 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1990 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1991 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1992 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1993 EXPECTED(ret, True);
1994 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1997 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1998 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1999 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2000 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
2001 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2003 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2004 EXPECTED(ret, True);
2005 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2007 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
2008 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2009 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2011 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
2012 EXPECTED(ret, True);
2013 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2015 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
2016 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2017 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2019 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
2020 EXPECTED(ret, True);
2021 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2023 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
2024 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
2025 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2026 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2028 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
2029 EXPECTED(ret, True);
2030 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2032 cli_close(cli1, fnum1);
2033 cli_close(cli2, fnum2);
2034 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2035 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2036 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2037 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
2038 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2039 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2040 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2042 cli_close(cli1, fnum1);
2043 EXPECTED(ret, True);
2044 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2047 cli_close(cli1, fnum1);
2048 cli_close(cli2, fnum2);
2049 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2050 torture_close_connection(cli1);
2051 torture_close_connection(cli2);
2053 printf("finished locktest4\n");
2058 looks at lock upgrade/downgrade.
2060 static bool run_locktest5(int dummy)
2062 static struct cli_state *cli1, *cli2;
2063 const char *fname = "\\lockt5.lck";
2064 uint16_t fnum1, fnum2, fnum3;
2067 bool correct = True;
2070 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2074 cli_sockopt(cli1, sockops);
2075 cli_sockopt(cli2, sockops);
2077 printf("starting locktest5\n");
2079 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2081 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2082 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2083 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2085 memset(buf, 0, sizeof(buf));
2087 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2089 if (!NT_STATUS_IS_OK(status)) {
2090 printf("Failed to create file: %s\n", nt_errstr(status));
2095 /* Check for NT bug... */
2096 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2097 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2098 cli_close(cli1, fnum1);
2099 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2100 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2101 EXPECTED(ret, True);
2102 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2103 cli_close(cli1, fnum1);
2104 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2105 cli_unlock(cli1, fnum3, 0, 1);
2107 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2108 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2109 EXPECTED(ret, True);
2110 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2112 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2113 EXPECTED(ret, False);
2115 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2117 /* Unlock the process 2 lock. */
2118 cli_unlock(cli2, fnum2, 0, 4);
2120 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2121 EXPECTED(ret, False);
2123 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2125 /* Unlock the process 1 fnum3 lock. */
2126 cli_unlock(cli1, fnum3, 0, 4);
2128 /* Stack 2 more locks here. */
2129 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2130 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2132 EXPECTED(ret, True);
2133 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2135 /* Unlock the first process lock, then check this was the WRITE lock that was
2138 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2139 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2141 EXPECTED(ret, True);
2142 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2144 /* Unlock the process 2 lock. */
2145 cli_unlock(cli2, fnum2, 0, 4);
2147 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2149 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2150 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2151 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2153 EXPECTED(ret, True);
2154 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2156 /* Ensure the next unlock fails. */
2157 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2158 EXPECTED(ret, False);
2159 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2161 /* Ensure connection 2 can get a write lock. */
2162 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2163 EXPECTED(ret, True);
2165 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2169 cli_close(cli1, fnum1);
2170 cli_close(cli2, fnum2);
2171 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2172 if (!torture_close_connection(cli1)) {
2175 if (!torture_close_connection(cli2)) {
2179 printf("finished locktest5\n");
2185 tries the unusual lockingX locktype bits
2187 static bool run_locktest6(int dummy)
2189 static struct cli_state *cli;
2190 const char *fname[1] = { "\\lock6.txt" };
2195 if (!torture_open_connection(&cli, 0)) {
2199 cli_sockopt(cli, sockops);
2201 printf("starting locktest6\n");
2204 printf("Testing %s\n", fname[i]);
2206 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2208 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2209 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2210 cli_close(cli, fnum);
2211 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2213 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2214 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2215 cli_close(cli, fnum);
2216 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2218 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2221 torture_close_connection(cli);
2223 printf("finished locktest6\n");
2227 static bool run_locktest7(int dummy)
2229 struct cli_state *cli1;
2230 const char *fname = "\\lockt7.lck";
2233 bool correct = False;
2236 if (!torture_open_connection(&cli1, 0)) {
2240 cli_sockopt(cli1, sockops);
2242 printf("starting locktest7\n");
2244 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2246 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2248 memset(buf, 0, sizeof(buf));
2250 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2252 if (!NT_STATUS_IS_OK(status)) {
2253 printf("Failed to create file: %s\n", nt_errstr(status));
2257 cli_setpid(cli1, 1);
2259 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2260 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2263 printf("pid1 successfully locked range 130:4 for READ\n");
2266 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2267 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2270 printf("pid1 successfully read the range 130:4\n");
2273 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2274 if (!NT_STATUS_IS_OK(status)) {
2275 printf("pid1 unable to write to the range 130:4, error was "
2276 "%s\n", nt_errstr(status));
2277 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2278 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2282 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2286 cli_setpid(cli1, 2);
2288 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2289 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2291 printf("pid2 successfully read the range 130:4\n");
2294 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2295 if (!NT_STATUS_IS_OK(status)) {
2296 printf("pid2 unable to write to the range 130:4, error was "
2297 "%s\n", nt_errstr(status));
2298 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2299 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2303 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2307 cli_setpid(cli1, 1);
2308 cli_unlock(cli1, fnum1, 130, 4);
2310 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2311 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2314 printf("pid1 successfully locked range 130:4 for WRITE\n");
2317 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2318 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2321 printf("pid1 successfully read the range 130:4\n");
2324 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2325 if (!NT_STATUS_IS_OK(status)) {
2326 printf("pid1 unable to write to the range 130:4, error was "
2327 "%s\n", nt_errstr(status));
2330 printf("pid1 successfully wrote to the range 130:4\n");
2333 cli_setpid(cli1, 2);
2335 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2336 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2337 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2338 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2342 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2346 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("pid2 unable to write to the range 130:4, error was "
2349 "%s\n", nt_errstr(status));
2350 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2351 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2355 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2359 cli_unlock(cli1, fnum1, 130, 0);
2363 cli_close(cli1, fnum1);
2364 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2365 torture_close_connection(cli1);
2367 printf("finished locktest7\n");
2372 * This demonstrates a problem with our use of GPFS share modes: A file
2373 * descriptor sitting in the pending close queue holding a GPFS share mode
2374 * blocks opening a file another time. Happens with Word 2007 temp files.
2375 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2376 * open is denied with NT_STATUS_SHARING_VIOLATION.
2379 static bool run_locktest8(int dummy)
2381 struct cli_state *cli1;
2382 const char *fname = "\\lockt8.lck";
2383 uint16_t fnum1, fnum2;
2385 bool correct = False;
2388 if (!torture_open_connection(&cli1, 0)) {
2392 cli_sockopt(cli1, sockops);
2394 printf("starting locktest8\n");
2396 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2398 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2400 if (!NT_STATUS_IS_OK(status)) {
2401 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2405 memset(buf, 0, sizeof(buf));
2407 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2408 if (!NT_STATUS_IS_OK(status)) {
2409 d_fprintf(stderr, "cli_open second time returned %s\n",
2414 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2415 printf("Unable to apply read lock on range 1:1, error was "
2416 "%s\n", cli_errstr(cli1));
2420 status = cli_close(cli1, fnum1);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2426 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2427 if (!NT_STATUS_IS_OK(status)) {
2428 d_fprintf(stderr, "cli_open third time returned %s\n",
2436 cli_close(cli1, fnum1);
2437 cli_close(cli1, fnum2);
2438 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2439 torture_close_connection(cli1);
2441 printf("finished locktest8\n");
2446 * This test is designed to be run in conjunction with
2447 * external NFS or POSIX locks taken in the filesystem.
2448 * It checks that the smbd server will block until the
2449 * lock is released and then acquire it. JRA.
2452 static bool got_alarm;
2453 static int alarm_fd;
2455 static void alarm_handler(int dummy)
2460 static void alarm_handler_parent(int dummy)
2465 static void do_local_lock(int read_fd, int write_fd)
2470 const char *local_pathname = NULL;
2473 local_pathname = talloc_asprintf(talloc_tos(),
2474 "%s/lockt9.lck", local_path);
2475 if (!local_pathname) {
2476 printf("child: alloc fail\n");
2480 unlink(local_pathname);
2481 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2483 printf("child: open of %s failed %s.\n",
2484 local_pathname, strerror(errno));
2488 /* Now take a fcntl lock. */
2489 lock.l_type = F_WRLCK;
2490 lock.l_whence = SEEK_SET;
2493 lock.l_pid = getpid();
2495 ret = fcntl(fd,F_SETLK,&lock);
2497 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2498 local_pathname, strerror(errno));
2501 printf("child: got lock 0:4 on file %s.\n",
2506 CatchSignal(SIGALRM, alarm_handler);
2508 /* Signal the parent. */
2509 if (write(write_fd, &c, 1) != 1) {
2510 printf("child: start signal fail %s.\n",
2517 /* Wait for the parent to be ready. */
2518 if (read(read_fd, &c, 1) != 1) {
2519 printf("child: reply signal fail %s.\n",
2527 printf("child: released lock 0:4 on file %s.\n",
2533 static bool run_locktest9(int dummy)
2535 struct cli_state *cli1;
2536 const char *fname = "\\lockt9.lck";
2538 bool correct = False;
2539 int pipe_in[2], pipe_out[2];
2543 struct timeval start;
2547 printf("starting locktest9\n");
2549 if (local_path == NULL) {
2550 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2554 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2559 if (child_pid == -1) {
2563 if (child_pid == 0) {
2565 do_local_lock(pipe_out[0], pipe_in[1]);
2575 ret = read(pipe_in[0], &c, 1);
2577 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2582 if (!torture_open_connection(&cli1, 0)) {
2586 cli_sockopt(cli1, sockops);
2588 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2590 if (!NT_STATUS_IS_OK(status)) {
2591 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2595 /* Ensure the child has the lock. */
2596 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2597 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2600 d_printf("Child has the lock.\n");
2603 /* Tell the child to wait 5 seconds then exit. */
2604 ret = write(pipe_out[1], &c, 1);
2606 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2611 /* Wait 20 seconds for the lock. */
2612 alarm_fd = cli1->fd;
2613 CatchSignal(SIGALRM, alarm_handler_parent);
2616 start = timeval_current();
2618 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2619 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2620 "%s\n", cli_errstr(cli1));
2625 seconds = timeval_elapsed(&start);
2627 printf("Parent got the lock after %.2f seconds.\n",
2630 status = cli_close(cli1, fnum);
2631 if (!NT_STATUS_IS_OK(status)) {
2632 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2639 cli_close(cli1, fnum);
2640 torture_close_connection(cli1);
2644 printf("finished locktest9\n");
2649 test whether fnums and tids open on one VC are available on another (a major
2652 static bool run_fdpasstest(int dummy)
2654 struct cli_state *cli1, *cli2;
2655 const char *fname = "\\fdpass.tst";
2660 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2663 cli_sockopt(cli1, sockops);
2664 cli_sockopt(cli2, sockops);
2666 printf("starting fdpasstest\n");
2668 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2670 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2672 if (!NT_STATUS_IS_OK(status)) {
2673 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2677 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2679 if (!NT_STATUS_IS_OK(status)) {
2680 printf("write failed (%s)\n", nt_errstr(status));
2684 cli2->vuid = cli1->vuid;
2685 cli2->cnum = cli1->cnum;
2686 cli2->pid = cli1->pid;
2688 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2689 printf("read succeeded! nasty security hole [%s]\n",
2694 cli_close(cli1, fnum1);
2695 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2697 torture_close_connection(cli1);
2698 torture_close_connection(cli2);
2700 printf("finished fdpasstest\n");
2704 static bool run_fdsesstest(int dummy)
2706 struct cli_state *cli;
2711 const char *fname = "\\fdsess.tst";
2712 const char *fname1 = "\\fdsess1.tst";
2719 if (!torture_open_connection(&cli, 0))
2721 cli_sockopt(cli, sockops);
2723 if (!torture_cli_session_setup2(cli, &new_vuid))
2726 saved_cnum = cli->cnum;
2727 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2729 new_cnum = cli->cnum;
2730 cli->cnum = saved_cnum;
2732 printf("starting fdsesstest\n");
2734 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2735 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2737 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2743 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2745 if (!NT_STATUS_IS_OK(status)) {
2746 printf("write failed (%s)\n", nt_errstr(status));
2750 saved_vuid = cli->vuid;
2751 cli->vuid = new_vuid;
2753 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2754 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2758 /* Try to open a file with different vuid, samba cnum. */
2759 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2760 printf("create with different vuid, same cnum succeeded.\n");
2761 cli_close(cli, fnum2);
2762 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2764 printf("create with different vuid, same cnum failed.\n");
2765 printf("This will cause problems with service clients.\n");
2769 cli->vuid = saved_vuid;
2771 /* Try with same vuid, different cnum. */
2772 cli->cnum = new_cnum;
2774 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2775 printf("read succeeded with different cnum![%s]\n",
2780 cli->cnum = saved_cnum;
2781 cli_close(cli, fnum1);
2782 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2784 torture_close_connection(cli);
2786 printf("finished fdsesstest\n");
2791 This test checks that
2793 1) the server does not allow an unlink on a file that is open
2795 static bool run_unlinktest(int dummy)
2797 struct cli_state *cli;
2798 const char *fname = "\\unlink.tst";
2800 bool correct = True;
2803 if (!torture_open_connection(&cli, 0)) {
2807 cli_sockopt(cli, sockops);
2809 printf("starting unlink test\n");
2811 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2815 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2821 status = cli_unlink(cli, fname,
2822 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2823 if (NT_STATUS_IS_OK(status)) {
2824 printf("error: server allowed unlink on an open file\n");
2827 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2828 NT_STATUS_SHARING_VIOLATION);
2831 cli_close(cli, fnum);
2832 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2834 if (!torture_close_connection(cli)) {
2838 printf("unlink test finished\n");
2845 test how many open files this server supports on the one socket
2847 static bool run_maxfidtest(int dummy)
2849 struct cli_state *cli;
2851 uint16_t fnums[0x11000];
2854 bool correct = True;
2860 printf("failed to connect\n");
2864 cli_sockopt(cli, sockops);
2866 for (i=0; i<0x11000; i++) {
2867 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2868 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2870 if (!NT_STATUS_IS_OK(status)) {
2871 printf("open of %s failed (%s)\n",
2872 fname, nt_errstr(status));
2873 printf("maximum fnum is %d\n", i);
2881 printf("cleaning up\n");
2883 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2884 cli_close(cli, fnums[i]);
2886 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 printf("unlink of %s failed (%s)\n",
2889 fname, nt_errstr(status));
2896 printf("maxfid test finished\n");
2897 if (!torture_close_connection(cli)) {
2903 /* generate a random buffer */
2904 static void rand_buf(char *buf, int len)
2907 *buf = (char)sys_random();
2912 /* send smb negprot commands, not reading the response */
2913 static bool run_negprot_nowait(int dummy)
2915 struct tevent_context *ev;
2917 struct cli_state *cli;
2918 bool correct = True;
2920 printf("starting negprot nowait test\n");
2922 ev = tevent_context_init(talloc_tos());
2927 if (!(cli = open_nbt_connection())) {
2932 for (i=0;i<50000;i++) {
2933 struct tevent_req *req;
2935 req = cli_negprot_send(ev, ev, cli);
2940 if (!tevent_req_poll(req, ev)) {
2941 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2949 if (torture_close_connection(cli)) {
2953 printf("finished negprot nowait test\n");
2958 /* send smb negprot commands, not reading the response */
2959 static bool run_bad_nbt_session(int dummy)
2961 struct nmb_name called, calling;
2962 struct sockaddr_storage ss;
2967 printf("starting bad nbt session test\n");
2969 make_nmb_name(&calling, myname, 0x0);
2970 make_nmb_name(&called , host, 0x20);
2972 if (!resolve_name(host, &ss, 0x20, true)) {
2973 d_fprintf(stderr, "Could not resolve name %s\n", host);
2977 status = open_socket_out(&ss, 139, 10000, &fd);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 d_fprintf(stderr, "open_socket_out failed: %s\n",
2984 ret = cli_bad_session_request(fd, &calling, &called);
2987 d_fprintf(stderr, "open_socket_out failed: %s\n",
2992 printf("finished bad nbt session test\n");
2996 /* send random IPC commands */
2997 static bool run_randomipc(int dummy)
2999 char *rparam = NULL;
3001 unsigned int rdrcnt,rprcnt;
3003 int api, param_len, i;
3004 struct cli_state *cli;
3005 bool correct = True;
3008 printf("starting random ipc test\n");
3010 if (!torture_open_connection(&cli, 0)) {
3014 for (i=0;i<count;i++) {
3015 api = sys_random() % 500;
3016 param_len = (sys_random() % 64);
3018 rand_buf(param, param_len);
3023 param, param_len, 8,
3024 NULL, 0, BUFFER_SIZE,
3028 printf("%d/%d\r", i,count);
3031 printf("%d/%d\n", i, count);
3033 if (!torture_close_connection(cli)) {
3037 printf("finished random ipc test\n");
3044 static void browse_callback(const char *sname, uint32 stype,
3045 const char *comment, void *state)
3047 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3053 This test checks the browse list code
3056 static bool run_browsetest(int dummy)
3058 static struct cli_state *cli;
3059 bool correct = True;
3061 printf("starting browse test\n");
3063 if (!torture_open_connection(&cli, 0)) {
3067 printf("domain list:\n");
3068 cli_NetServerEnum(cli, cli->server_domain,
3069 SV_TYPE_DOMAIN_ENUM,
3070 browse_callback, NULL);
3072 printf("machine list:\n");
3073 cli_NetServerEnum(cli, cli->server_domain,
3075 browse_callback, NULL);
3077 if (!torture_close_connection(cli)) {
3081 printf("browse test finished\n");
3089 This checks how the getatr calls works
3091 static bool run_attrtest(int dummy)
3093 struct cli_state *cli;
3096 const char *fname = "\\attrib123456789.tst";
3097 bool correct = True;
3100 printf("starting attrib test\n");
3102 if (!torture_open_connection(&cli, 0)) {
3106 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3107 cli_open(cli, fname,
3108 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3109 cli_close(cli, fnum);
3111 status = cli_getatr(cli, fname, NULL, NULL, &t);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("getatr failed (%s)\n", nt_errstr(status));
3117 if (abs(t - time(NULL)) > 60*60*24*10) {
3118 printf("ERROR: SMBgetatr bug. time is %s",
3124 t2 = t-60*60*24; /* 1 day ago */
3126 status = cli_setatr(cli, fname, 0, t2);
3127 if (!NT_STATUS_IS_OK(status)) {
3128 printf("setatr failed (%s)\n", nt_errstr(status));
3132 status = cli_getatr(cli, fname, NULL, NULL, &t);
3133 if (!NT_STATUS_IS_OK(status)) {
3134 printf("getatr failed (%s)\n", nt_errstr(status));
3139 printf("ERROR: getatr/setatr bug. times are\n%s",
3141 printf("%s", ctime(&t2));
3145 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3147 if (!torture_close_connection(cli)) {
3151 printf("attrib test finished\n");
3158 This checks a couple of trans2 calls
3160 static bool run_trans2test(int dummy)
3162 struct cli_state *cli;
3165 time_t c_time, a_time, m_time;
3166 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3167 const char *fname = "\\trans2.tst";
3168 const char *dname = "\\trans2";
3169 const char *fname2 = "\\trans2\\trans2.tst";
3171 bool correct = True;
3175 printf("starting trans2 test\n");
3177 if (!torture_open_connection(&cli, 0)) {
3181 status = cli_get_fs_attr_info(cli, &fs_attr);
3182 if (!NT_STATUS_IS_OK(status)) {
3183 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3188 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3189 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3190 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3191 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3197 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3198 if (!NT_STATUS_IS_OK(status)) {
3199 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3203 if (strcmp(pname, fname)) {
3204 printf("qfilename gave different name? [%s] [%s]\n",
3209 cli_close(cli, fnum);
3213 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3214 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3216 if (!NT_STATUS_IS_OK(status)) {
3217 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3220 cli_close(cli, fnum);
3222 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3224 if (!NT_STATUS_IS_OK(status)) {
3225 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3228 if (c_time != m_time) {
3229 printf("create time=%s", ctime(&c_time));
3230 printf("modify time=%s", ctime(&m_time));
3231 printf("This system appears to have sticky create times\n");
3233 if (a_time % (60*60) == 0) {
3234 printf("access time=%s", ctime(&a_time));
3235 printf("This system appears to set a midnight access time\n");
3239 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3240 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3246 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3247 cli_open(cli, fname,
3248 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3249 cli_close(cli, fnum);
3250 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3251 &m_time_ts, &size, NULL, NULL);
3252 if (!NT_STATUS_IS_OK(status)) {
3253 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3256 if (w_time_ts.tv_sec < 60*60*24*2) {
3257 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3258 printf("This system appears to set a initial 0 write time\n");
3263 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3266 /* check if the server updates the directory modification time
3267 when creating a new file */
3268 status = cli_mkdir(cli, dname);
3269 if (!NT_STATUS_IS_OK(status)) {
3270 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3274 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3275 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3276 if (!NT_STATUS_IS_OK(status)) {
3277 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3281 cli_open(cli, fname2,
3282 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3283 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3284 cli_close(cli, fnum);
3285 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3286 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3287 if (!NT_STATUS_IS_OK(status)) {
3288 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3291 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3293 printf("This system does not update directory modification times\n");
3297 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3298 cli_rmdir(cli, dname);
3300 if (!torture_close_connection(cli)) {
3304 printf("trans2 test finished\n");
3310 This checks new W2K calls.
3313 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3315 uint8_t *buf = NULL;
3319 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3320 pcli->max_xmit, NULL, &buf, &len);
3321 if (!NT_STATUS_IS_OK(status)) {
3322 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3325 printf("qfileinfo: level %d, len = %u\n", level, len);
3326 dump_data(0, (uint8 *)buf, len);
3333 static bool run_w2ktest(int dummy)
3335 struct cli_state *cli;
3337 const char *fname = "\\w2ktest\\w2k.tst";
3339 bool correct = True;
3341 printf("starting w2k test\n");
3343 if (!torture_open_connection(&cli, 0)) {
3347 cli_open(cli, fname,
3348 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3350 for (level = 1004; level < 1040; level++) {
3351 new_trans(cli, fnum, level);
3354 cli_close(cli, fnum);
3356 if (!torture_close_connection(cli)) {
3360 printf("w2k test finished\n");
3367 this is a harness for some oplock tests
3369 static bool run_oplock1(int dummy)
3371 struct cli_state *cli1;
3372 const char *fname = "\\lockt1.lck";
3374 bool correct = True;
3377 printf("starting oplock test 1\n");
3379 if (!torture_open_connection(&cli1, 0)) {
3383 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3385 cli_sockopt(cli1, sockops);
3387 cli1->use_oplocks = True;
3389 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3391 if (!NT_STATUS_IS_OK(status)) {
3392 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3396 cli1->use_oplocks = False;
3398 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3399 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3401 status = cli_close(cli1, fnum1);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 printf("close2 failed (%s)\n", nt_errstr(status));
3407 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3408 if (!NT_STATUS_IS_OK(status)) {
3409 printf("unlink failed (%s)\n", nt_errstr(status));
3413 if (!torture_close_connection(cli1)) {
3417 printf("finished oplock test 1\n");
3422 static bool run_oplock2(int dummy)
3424 struct cli_state *cli1, *cli2;
3425 const char *fname = "\\lockt2.lck";
3426 uint16_t fnum1, fnum2;
3427 int saved_use_oplocks = use_oplocks;
3429 bool correct = True;
3430 volatile bool *shared_correct;
3433 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3434 *shared_correct = True;
3436 use_level_II_oplocks = True;
3439 printf("starting oplock test 2\n");
3441 if (!torture_open_connection(&cli1, 0)) {
3442 use_level_II_oplocks = False;
3443 use_oplocks = saved_use_oplocks;
3447 cli1->use_oplocks = True;
3448 cli1->use_level_II_oplocks = True;
3450 if (!torture_open_connection(&cli2, 1)) {
3451 use_level_II_oplocks = False;
3452 use_oplocks = saved_use_oplocks;
3456 cli2->use_oplocks = True;
3457 cli2->use_level_II_oplocks = True;
3459 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3461 cli_sockopt(cli1, sockops);
3462 cli_sockopt(cli2, sockops);
3464 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3466 if (!NT_STATUS_IS_OK(status)) {
3467 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3471 /* Don't need the globals any more. */
3472 use_level_II_oplocks = False;
3473 use_oplocks = saved_use_oplocks;
3477 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3478 if (!NT_STATUS_IS_OK(status)) {
3479 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3480 *shared_correct = False;
3486 status = cli_close(cli2, fnum2);
3487 if (!NT_STATUS_IS_OK(status)) {
3488 printf("close2 failed (%s)\n", nt_errstr(status));
3489 *shared_correct = False;
3497 /* Ensure cli1 processes the break. Empty file should always return 0
3500 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3501 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3505 /* Should now be at level II. */
3506 /* Test if sending a write locks causes a break to none. */
3508 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3509 printf("lock failed (%s)\n", cli_errstr(cli1));
3513 cli_unlock(cli1, fnum1, 0, 4);
3517 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3518 printf("lock failed (%s)\n", cli_errstr(cli1));
3522 cli_unlock(cli1, fnum1, 0, 4);
3526 cli_read(cli1, fnum1, buf, 0, 4);
3528 status = cli_close(cli1, fnum1);
3529 if (!NT_STATUS_IS_OK(status)) {
3530 printf("close1 failed (%s)\n", nt_errstr(status));
3536 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("unlink failed (%s)\n", nt_errstr(status));
3542 if (!torture_close_connection(cli1)) {
3546 if (!*shared_correct) {
3550 printf("finished oplock test 2\n");
3555 struct oplock4_state {
3556 struct tevent_context *ev;
3557 struct cli_state *cli;
3562 static void oplock4_got_break(struct tevent_req *req);
3563 static void oplock4_got_open(struct tevent_req *req);
3565 static bool run_oplock4(int dummy)
3567 struct tevent_context *ev;
3568 struct cli_state *cli1, *cli2;
3569 struct tevent_req *oplock_req, *open_req;
3570 const char *fname = "\\lockt4.lck";
3571 const char *fname_ln = "\\lockt4_ln.lck";
3572 uint16_t fnum1, fnum2;
3573 int saved_use_oplocks = use_oplocks;
3575 bool correct = true;
3579 struct oplock4_state *state;
3581 printf("starting oplock test 4\n");
3583 if (!torture_open_connection(&cli1, 0)) {
3584 use_level_II_oplocks = false;
3585 use_oplocks = saved_use_oplocks;
3589 if (!torture_open_connection(&cli2, 1)) {
3590 use_level_II_oplocks = false;
3591 use_oplocks = saved_use_oplocks;
3595 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3596 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3598 cli_sockopt(cli1, sockops);
3599 cli_sockopt(cli2, sockops);
3601 /* Create the file. */
3602 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3604 if (!NT_STATUS_IS_OK(status)) {
3605 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3609 status = cli_close(cli1, fnum1);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("close1 failed (%s)\n", nt_errstr(status));
3615 /* Now create a hardlink. */
3616 status = cli_nt_hardlink(cli1, fname, fname_ln);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3622 /* Prove that opening hardlinks cause deny modes to conflict. */
3623 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3629 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3630 if (NT_STATUS_IS_OK(status)) {
3631 printf("open of %s succeeded - should fail with sharing violation.\n",
3636 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3637 printf("open of %s should fail with sharing violation. Got %s\n",
3638 fname_ln, nt_errstr(status));
3642 status = cli_close(cli1, fnum1);
3643 if (!NT_STATUS_IS_OK(status)) {
3644 printf("close1 failed (%s)\n", nt_errstr(status));
3648 cli1->use_oplocks = true;
3649 cli1->use_level_II_oplocks = true;
3651 cli2->use_oplocks = true;
3652 cli2->use_level_II_oplocks = true;
3654 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3655 if (!NT_STATUS_IS_OK(status)) {
3656 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3660 ev = tevent_context_init(talloc_tos());
3662 printf("tevent_req_create failed\n");
3666 state = talloc(ev, struct oplock4_state);
3667 if (state == NULL) {
3668 printf("talloc failed\n");
3673 state->got_break = &got_break;
3674 state->fnum2 = &fnum2;
3676 oplock_req = cli_smb_oplock_break_waiter_send(
3677 talloc_tos(), ev, cli1);
3678 if (oplock_req == NULL) {
3679 printf("cli_smb_oplock_break_waiter_send failed\n");
3682 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3684 open_req = cli_open_send(
3685 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3686 if (oplock_req == NULL) {
3687 printf("cli_open_send failed\n");
3690 tevent_req_set_callback(open_req, oplock4_got_open, state);
3695 while (!got_break || fnum2 == 0xffff) {
3697 ret = tevent_loop_once(ev);
3699 printf("tevent_loop_once failed: %s\n",
3705 status = cli_close(cli2, fnum2);
3706 if (!NT_STATUS_IS_OK(status)) {
3707 printf("close2 failed (%s)\n", nt_errstr(status));
3711 status = cli_close(cli1, fnum1);
3712 if (!NT_STATUS_IS_OK(status)) {
3713 printf("close1 failed (%s)\n", nt_errstr(status));
3717 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3718 if (!NT_STATUS_IS_OK(status)) {
3719 printf("unlink failed (%s)\n", nt_errstr(status));
3723 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3724 if (!NT_STATUS_IS_OK(status)) {
3725 printf("unlink failed (%s)\n", nt_errstr(status));
3729 if (!torture_close_connection(cli1)) {
3737 printf("finished oplock test 4\n");
3742 static void oplock4_got_break(struct tevent_req *req)
3744 struct oplock4_state *state = tevent_req_callback_data(
3745 req, struct oplock4_state);
3750 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3752 if (!NT_STATUS_IS_OK(status)) {
3753 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3757 *state->got_break = true;
3759 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3762 printf("cli_oplock_ack_send failed\n");
3767 static void oplock4_got_open(struct tevent_req *req)
3769 struct oplock4_state *state = tevent_req_callback_data(
3770 req, struct oplock4_state);
3773 status = cli_open_recv(req, state->fnum2);
3774 if (!NT_STATUS_IS_OK(status)) {
3775 printf("cli_open_recv returned %s\n", nt_errstr(status));
3776 *state->fnum2 = 0xffff;
3781 Test delete on close semantics.
3783 static bool run_deletetest(int dummy)
3785 struct cli_state *cli1 = NULL;
3786 struct cli_state *cli2 = NULL;
3787 const char *fname = "\\delete.file";
3788 uint16_t fnum1 = (uint16_t)-1;
3789 uint16_t fnum2 = (uint16_t)-1;
3790 bool correct = True;
3793 printf("starting delete test\n");
3795 if (!torture_open_connection(&cli1, 0)) {
3799 cli_sockopt(cli1, sockops);
3801 /* Test 1 - this should delete the file on close. */
3803 cli_setatr(cli1, fname, 0, 0);
3804 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3806 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3807 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3808 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3809 if (!NT_STATUS_IS_OK(status)) {
3810 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3815 status = cli_close(cli1, fnum1);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 printf("[1] close failed (%s)\n", nt_errstr(status));
3822 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3823 printf("[1] open of %s succeeded (should fail)\n", fname);
3828 printf("first delete on close test succeeded.\n");
3830 /* Test 2 - this should delete the file on close. */
3832 cli_setatr(cli1, fname, 0, 0);
3833 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3835 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3836 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3837 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3844 status = cli_nt_delete_on_close(cli1, fnum1, true);
3845 if (!NT_STATUS_IS_OK(status)) {
3846 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3851 status = cli_close(cli1, fnum1);
3852 if (!NT_STATUS_IS_OK(status)) {
3853 printf("[2] close failed (%s)\n", nt_errstr(status));
3858 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3859 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3860 status = cli_close(cli1, fnum1);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 printf("[2] close failed (%s)\n", nt_errstr(status));
3866 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3868 printf("second delete on close test succeeded.\n");
3871 cli_setatr(cli1, fname, 0, 0);
3872 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3874 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3875 FILE_ATTRIBUTE_NORMAL,
3876 FILE_SHARE_READ|FILE_SHARE_WRITE,
3877 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3878 if (!NT_STATUS_IS_OK(status)) {
3879 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3884 /* This should fail with a sharing violation - open for delete is only compatible
3885 with SHARE_DELETE. */
3887 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3888 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3889 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3894 /* This should succeed. */
3895 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3896 FILE_ATTRIBUTE_NORMAL,
3897 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3898 FILE_OPEN, 0, 0, &fnum2);
3899 if (!NT_STATUS_IS_OK(status)) {
3900 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3905 status = cli_nt_delete_on_close(cli1, fnum1, true);
3906 if (!NT_STATUS_IS_OK(status)) {
3907 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3912 status = cli_close(cli1, fnum1);
3913 if (!NT_STATUS_IS_OK(status)) {
3914 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3919 status = cli_close(cli1, fnum2);
3920 if (!NT_STATUS_IS_OK(status)) {
3921 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3926 /* This should fail - file should no longer be there. */
3928 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3929 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3930 status = cli_close(cli1, fnum1);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 printf("[3] close failed (%s)\n", nt_errstr(status));
3934 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3938 printf("third delete on close test succeeded.\n");
3941 cli_setatr(cli1, fname, 0, 0);
3942 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3944 status = cli_ntcreate(cli1, fname, 0,
3945 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3946 FILE_ATTRIBUTE_NORMAL,
3947 FILE_SHARE_READ|FILE_SHARE_WRITE,
3948 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3949 if (!NT_STATUS_IS_OK(status)) {
3950 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3955 /* This should succeed. */
3956 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3957 FILE_ATTRIBUTE_NORMAL,
3958 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3959 FILE_OPEN, 0, 0, &fnum2);
3960 if (!NT_STATUS_IS_OK(status)) {
3961 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3966 status = cli_close(cli1, fnum2);
3967 if (!NT_STATUS_IS_OK(status)) {
3968 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3973 status = cli_nt_delete_on_close(cli1, fnum1, true);
3974 if (!NT_STATUS_IS_OK(status)) {
3975 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3980 /* This should fail - no more opens once delete on close set. */
3981 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3982 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3983 FILE_OPEN, 0, 0, &fnum2))) {
3984 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3988 printf("fourth delete on close test succeeded.\n");
3990 status = cli_close(cli1, fnum1);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3998 cli_setatr(cli1, fname, 0, 0);
3999 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4001 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4008 /* This should fail - only allowed on NT opens with DELETE access. */
4010 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4011 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4016 status = cli_close(cli1, fnum1);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4023 printf("fifth delete on close test succeeded.\n");
4026 cli_setatr(cli1, fname, 0, 0);
4027 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4029 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4030 FILE_ATTRIBUTE_NORMAL,
4031 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4032 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4033 if (!NT_STATUS_IS_OK(status)) {
4034 printf("[6] open of %s failed (%s)\n", fname,
4040 /* This should fail - only allowed on NT opens with DELETE access. */
4042 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4043 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4048 status = cli_close(cli1, fnum1);
4049 if (!NT_STATUS_IS_OK(status)) {
4050 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4055 printf("sixth delete on close test succeeded.\n");
4058 cli_setatr(cli1, fname, 0, 0);
4059 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4061 status = cli_ntcreate(cli1, fname, 0,
4062 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4063 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4065 if (!NT_STATUS_IS_OK(status)) {
4066 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4071 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4072 printf("[7] setting delete_on_close on file failed !\n");
4077 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4078 printf("[7] unsetting delete_on_close on file failed !\n");
4083 status = cli_close(cli1, fnum1);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4090 /* This next open should succeed - we reset the flag. */
4091 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
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 printf("seventh delete on close test succeeded.\n");
4108 cli_setatr(cli1, fname, 0, 0);
4109 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4111 if (!torture_open_connection(&cli2, 1)) {
4112 printf("[8] failed to open second connection.\n");
4117 cli_sockopt(cli1, sockops);
4119 status = cli_ntcreate(cli1, fname, 0,
4120 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4121 FILE_ATTRIBUTE_NORMAL,
4122 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4123 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4124 if (!NT_STATUS_IS_OK(status)) {
4125 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4130 status = cli_ntcreate(cli2, fname, 0,
4131 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4132 FILE_ATTRIBUTE_NORMAL,
4133 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4134 FILE_OPEN, 0, 0, &fnum2);
4135 if (!NT_STATUS_IS_OK(status)) {
4136 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4141 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4142 printf("[8] setting delete_on_close on file failed !\n");
4147 status = cli_close(cli1, fnum1);
4148 if (!NT_STATUS_IS_OK(status)) {
4149 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4154 status = cli_close(cli2, fnum2);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4161 /* This should fail.. */
4162 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4163 if (NT_STATUS_IS_OK(status)) {
4164 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4168 printf("eighth delete on close test succeeded.\n");
4170 /* This should fail - we need to set DELETE_ACCESS. */
4171 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4172 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4173 printf("[9] open of %s succeeded should have failed!\n", fname);
4178 printf("ninth delete on close test succeeded.\n");
4180 status = cli_ntcreate(cli1, fname, 0,
4181 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4182 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4183 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4191 /* This should delete the file. */
4192 status = cli_close(cli1, fnum1);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 printf("[10] close failed (%s)\n", nt_errstr(status));
4199 /* This should fail.. */
4200 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4201 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4205 printf("tenth delete on close test succeeded.\n");
4207 cli_setatr(cli1, fname, 0, 0);
4208 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4210 /* What error do we get when attempting to open a read-only file with
4213 /* Create a readonly file. */
4214 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4215 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4216 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4223 status = cli_close(cli1, fnum1);
4224 if (!NT_STATUS_IS_OK(status)) {
4225 printf("[11] close failed (%s)\n", nt_errstr(status));
4230 /* Now try open for delete access. */
4231 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4232 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4233 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4234 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4235 cli_close(cli1, fnum1);
4239 NTSTATUS nterr = cli_nt_error(cli1);
4240 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4241 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4245 printf("eleventh delete on close test succeeded.\n");
4249 printf("finished delete test\n");
4252 /* FIXME: This will crash if we aborted before cli2 got
4253 * intialized, because these functions don't handle
4254 * uninitialized connections. */
4256 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4257 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4258 cli_setatr(cli1, fname, 0, 0);
4259 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4261 if (cli1 && !torture_close_connection(cli1)) {
4264 if (cli2 && !torture_close_connection(cli2)) {
4270 static bool run_deletetest_ln(int dummy)
4272 struct cli_state *cli;
4273 const char *fname = "\\delete1";
4274 const char *fname_ln = "\\delete1_ln";
4278 bool correct = true;
4281 printf("starting deletetest-ln\n");
4283 if (!torture_open_connection(&cli, 0)) {
4287 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4288 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4290 cli_sockopt(cli, sockops);
4292 /* Create the file. */
4293 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4299 status = cli_close(cli, fnum);
4300 if (!NT_STATUS_IS_OK(status)) {
4301 printf("close1 failed (%s)\n", nt_errstr(status));
4305 /* Now create a hardlink. */
4306 status = cli_nt_hardlink(cli, fname, fname_ln);
4307 if (!NT_STATUS_IS_OK(status)) {
4308 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4312 /* Open the original file. */
4313 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4314 FILE_ATTRIBUTE_NORMAL,
4315 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4316 FILE_OPEN_IF, 0, 0, &fnum);
4317 if (!NT_STATUS_IS_OK(status)) {
4318 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4322 /* Unlink the hard link path. */
4323 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4324 FILE_ATTRIBUTE_NORMAL,
4325 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4326 FILE_OPEN_IF, 0, 0, &fnum1);
4327 if (!NT_STATUS_IS_OK(status)) {
4328 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4331 status = cli_nt_delete_on_close(cli, fnum1, true);
4332 if (!NT_STATUS_IS_OK(status)) {
4333 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4334 __location__, fname_ln, nt_errstr(status));
4338 status = cli_close(cli, fnum1);
4339 if (!NT_STATUS_IS_OK(status)) {
4340 printf("close %s failed (%s)\n",
4341 fname_ln, nt_errstr(status));
4345 status = cli_close(cli, fnum);
4346 if (!NT_STATUS_IS_OK(status)) {
4347 printf("close %s failed (%s)\n",
4348 fname, nt_errstr(status));
4352 /* Ensure the original file is still there. */
4353 status = cli_getatr(cli, fname, NULL, NULL, &t);
4354 if (!NT_STATUS_IS_OK(status)) {
4355 printf("%s getatr on file %s failed (%s)\n",
4362 /* Ensure the link path is gone. */
4363 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4364 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4365 printf("%s, getatr for file %s returned wrong error code %s "
4366 "- should have been deleted\n",
4368 fname_ln, nt_errstr(status));
4372 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4373 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4375 if (!torture_close_connection(cli)) {
4379 printf("finished deletetest-ln\n");
4385 print out server properties
4387 static bool run_properties(int dummy)
4389 struct cli_state *cli;
4390 bool correct = True;
4392 printf("starting properties test\n");
4396 if (!torture_open_connection(&cli, 0)) {
4400 cli_sockopt(cli, sockops);
4402 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4404 if (!torture_close_connection(cli)) {
4413 /* FIRST_DESIRED_ACCESS 0xf019f */
4414 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4415 FILE_READ_EA| /* 0xf */ \
4416 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4417 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4418 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4419 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4420 /* SECOND_DESIRED_ACCESS 0xe0080 */
4421 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4422 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4423 WRITE_OWNER_ACCESS /* 0xe0000 */
4426 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4427 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4429 WRITE_OWNER_ACCESS /* */
4433 Test ntcreate calls made by xcopy
4435 static bool run_xcopy(int dummy)
4437 static struct cli_state *cli1;
4438 const char *fname = "\\test.txt";
4439 bool correct = True;
4440 uint16_t fnum1, fnum2;
4443 printf("starting xcopy test\n");
4445 if (!torture_open_connection(&cli1, 0)) {
4449 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4450 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4451 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 printf("First open failed - %s\n", nt_errstr(status));
4457 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4458 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4459 FILE_OPEN, 0x200000, 0, &fnum2);
4460 if (!NT_STATUS_IS_OK(status)) {
4461 printf("second open failed - %s\n", nt_errstr(status));
4465 if (!torture_close_connection(cli1)) {
4473 Test rename on files open with share delete and no share delete.
4475 static bool run_rename(int dummy)
4477 static struct cli_state *cli1;
4478 const char *fname = "\\test.txt";
4479 const char *fname1 = "\\test1.txt";
4480 bool correct = True;
4485 printf("starting rename test\n");
4487 if (!torture_open_connection(&cli1, 0)) {
4491 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4492 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4494 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4495 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4496 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4497 if (!NT_STATUS_IS_OK(status)) {
4498 printf("First open failed - %s\n", nt_errstr(status));
4502 status = cli_rename(cli1, fname, fname1);
4503 if (!NT_STATUS_IS_OK(status)) {
4504 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4506 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4510 status = cli_close(cli1, fnum1);
4511 if (!NT_STATUS_IS_OK(status)) {
4512 printf("close - 1 failed (%s)\n", nt_errstr(status));
4516 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4517 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4518 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4520 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4522 FILE_SHARE_DELETE|FILE_SHARE_READ,
4524 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4525 if (!NT_STATUS_IS_OK(status)) {
4526 printf("Second open failed - %s\n", nt_errstr(status));
4530 status = cli_rename(cli1, fname, fname1);
4531 if (!NT_STATUS_IS_OK(status)) {
4532 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4535 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4538 status = cli_close(cli1, fnum1);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 printf("close - 2 failed (%s)\n", nt_errstr(status));
4544 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4545 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4547 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4548 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4549 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4550 if (!NT_STATUS_IS_OK(status)) {
4551 printf("Third open failed - %s\n", nt_errstr(status));
4560 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4561 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4562 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4565 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4566 printf("[8] setting delete_on_close on file failed !\n");
4570 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4571 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4577 status = cli_rename(cli1, fname, fname1);
4578 if (!NT_STATUS_IS_OK(status)) {
4579 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4582 printf("Third rename succeeded (SHARE_NONE)\n");
4585 status = cli_close(cli1, fnum1);
4586 if (!NT_STATUS_IS_OK(status)) {
4587 printf("close - 3 failed (%s)\n", nt_errstr(status));
4591 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4592 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4596 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4597 FILE_ATTRIBUTE_NORMAL,
4598 FILE_SHARE_READ | FILE_SHARE_WRITE,
4599 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4600 if (!NT_STATUS_IS_OK(status)) {
4601 printf("Fourth open failed - %s\n", nt_errstr(status));
4605 status = cli_rename(cli1, fname, fname1);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4609 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4613 status = cli_close(cli1, fnum1);
4614 if (!NT_STATUS_IS_OK(status)) {
4615 printf("close - 4 failed (%s)\n", nt_errstr(status));
4619 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4620 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4624 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4625 FILE_ATTRIBUTE_NORMAL,
4626 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4627 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4628 if (!NT_STATUS_IS_OK(status)) {
4629 printf("Fifth open failed - %s\n", nt_errstr(status));
4633 status = cli_rename(cli1, fname, fname1);
4634 if (!NT_STATUS_IS_OK(status)) {
4635 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4638 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4642 * Now check if the first name still exists ...
4645 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4646 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4647 printf("Opening original file after rename of open file fails: %s\n",
4651 printf("Opening original file after rename of open file works ...\n");
4652 (void)cli_close(cli1, fnum2);
4656 status = cli_close(cli1, fnum1);
4657 if (!NT_STATUS_IS_OK(status)) {
4658 printf("close - 5 failed (%s)\n", nt_errstr(status));
4662 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4663 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 printf("getatr on file %s failed - %s ! \n",
4666 fname1, nt_errstr(status));
4669 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4670 printf("Renamed file %s has wrong attr 0x%x "
4671 "(should be 0x%x)\n",
4674 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4677 printf("Renamed file %s has archive bit set\n", fname1);
4681 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4682 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4684 if (!torture_close_connection(cli1)) {
4691 static bool run_pipe_number(int dummy)
4693 struct cli_state *cli1;
4694 const char *pipe_name = "\\SPOOLSS";
4699 printf("starting pipenumber test\n");
4700 if (!torture_open_connection(&cli1, 0)) {
4704 cli_sockopt(cli1, sockops);
4706 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4707 FILE_ATTRIBUTE_NORMAL,
4708 FILE_SHARE_READ|FILE_SHARE_WRITE,
4709 FILE_OPEN_IF, 0, 0, &fnum);
4710 if (!NT_STATUS_IS_OK(status)) {
4711 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4715 printf("\r%6d", num_pipes);
4718 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4719 torture_close_connection(cli1);
4724 Test open mode returns on read-only files.
4726 static bool run_opentest(int dummy)
4728 static struct cli_state *cli1;
4729 static struct cli_state *cli2;
4730 const char *fname = "\\readonly.file";
4731 uint16_t fnum1, fnum2;
4734 bool correct = True;
4738 printf("starting open test\n");
4740 if (!torture_open_connection(&cli1, 0)) {
4744 cli_setatr(cli1, fname, 0, 0);
4745 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4747 cli_sockopt(cli1, sockops);
4749 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4750 if (!NT_STATUS_IS_OK(status)) {
4751 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4755 status = cli_close(cli1, fnum1);
4756 if (!NT_STATUS_IS_OK(status)) {
4757 printf("close2 failed (%s)\n", nt_errstr(status));
4761 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4762 if (!NT_STATUS_IS_OK(status)) {
4763 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4767 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4768 if (!NT_STATUS_IS_OK(status)) {
4769 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4773 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4774 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4776 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4777 NT_STATUS_ACCESS_DENIED)) {
4778 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4781 printf("finished open test 1\n");
4783 cli_close(cli1, fnum1);
4785 /* Now try not readonly and ensure ERRbadshare is returned. */
4787 cli_setatr(cli1, fname, 0, 0);
4789 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4790 if (!NT_STATUS_IS_OK(status)) {
4791 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4795 /* This will fail - but the error should be ERRshare. */
4796 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4798 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4799 NT_STATUS_SHARING_VIOLATION)) {
4800 printf("correct error code ERRDOS/ERRbadshare returned\n");
4803 status = cli_close(cli1, fnum1);
4804 if (!NT_STATUS_IS_OK(status)) {
4805 printf("close2 failed (%s)\n", nt_errstr(status));
4809 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4811 printf("finished open test 2\n");
4813 /* Test truncate open disposition on file opened for read. */
4814 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4815 if (!NT_STATUS_IS_OK(status)) {
4816 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4820 /* write 20 bytes. */
4822 memset(buf, '\0', 20);
4824 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4825 if (!NT_STATUS_IS_OK(status)) {
4826 printf("write failed (%s)\n", nt_errstr(status));
4830 status = cli_close(cli1, fnum1);
4831 if (!NT_STATUS_IS_OK(status)) {
4832 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4836 /* Ensure size == 20. */
4837 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4838 if (!NT_STATUS_IS_OK(status)) {
4839 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4844 printf("(3) file size != 20\n");
4848 /* Now test if we can truncate a file opened for readonly. */
4849 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4850 if (!NT_STATUS_IS_OK(status)) {
4851 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4855 status = cli_close(cli1, fnum1);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("close2 failed (%s)\n", nt_errstr(status));
4861 /* Ensure size == 0. */
4862 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4863 if (!NT_STATUS_IS_OK(status)) {
4864 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4869 printf("(3) file size != 0\n");
4872 printf("finished open test 3\n");
4874 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4876 printf("Do ctemp tests\n");
4877 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("ctemp failed (%s)\n", nt_errstr(status));
4883 printf("ctemp gave path %s\n", tmp_path);
4884 status = cli_close(cli1, fnum1);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 printf("close of temp failed (%s)\n", nt_errstr(status));
4889 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4890 if (!NT_STATUS_IS_OK(status)) {
4891 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4894 /* Test the non-io opens... */
4896 if (!torture_open_connection(&cli2, 1)) {
4900 cli_setatr(cli2, fname, 0, 0);
4901 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4903 cli_sockopt(cli2, sockops);
4905 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4906 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4907 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4908 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4909 if (!NT_STATUS_IS_OK(status)) {
4910 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4914 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4915 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4916 FILE_OPEN_IF, 0, 0, &fnum2);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4922 status = cli_close(cli1, fnum1);
4923 if (!NT_STATUS_IS_OK(status)) {
4924 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4928 status = cli_close(cli2, fnum2);
4929 if (!NT_STATUS_IS_OK(status)) {
4930 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4934 printf("non-io open test #1 passed.\n");
4936 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4938 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4940 status = cli_ntcreate(cli1, fname, 0,
4941 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4942 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4943 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4944 if (!NT_STATUS_IS_OK(status)) {
4945 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4949 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4950 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4951 FILE_OPEN_IF, 0, 0, &fnum2);
4952 if (!NT_STATUS_IS_OK(status)) {
4953 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4957 status = cli_close(cli1, fnum1);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4963 status = cli_close(cli2, fnum2);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4969 printf("non-io open test #2 passed.\n");
4971 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4973 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4975 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4976 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4977 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4978 if (!NT_STATUS_IS_OK(status)) {
4979 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4983 status = cli_ntcreate(cli2, fname, 0,
4984 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4985 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4986 FILE_OPEN_IF, 0, 0, &fnum2);
4987 if (!NT_STATUS_IS_OK(status)) {
4988 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4992 status = cli_close(cli1, fnum1);
4993 if (!NT_STATUS_IS_OK(status)) {
4994 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4998 status = cli_close(cli2, fnum2);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5004 printf("non-io open test #3 passed.\n");
5006 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5008 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5010 status = cli_ntcreate(cli1, fname, 0,
5011 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5012 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5013 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5014 if (!NT_STATUS_IS_OK(status)) {
5015 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5019 status = cli_ntcreate(cli2, fname, 0,
5020 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5021 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5022 FILE_OPEN_IF, 0, 0, &fnum2);
5023 if (NT_STATUS_IS_OK(status)) {
5024 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5028 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5030 status = cli_close(cli1, fnum1);
5031 if (!NT_STATUS_IS_OK(status)) {
5032 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5036 printf("non-io open test #4 passed.\n");
5038 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5040 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5042 status = cli_ntcreate(cli1, fname, 0,
5043 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5044 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5045 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5046 if (!NT_STATUS_IS_OK(status)) {
5047 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5051 status = cli_ntcreate(cli2, fname, 0,
5052 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5053 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5054 FILE_OPEN_IF, 0, 0, &fnum2);
5055 if (!NT_STATUS_IS_OK(status)) {
5056 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5060 status = cli_close(cli1, fnum1);
5061 if (!NT_STATUS_IS_OK(status)) {
5062 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5066 status = cli_close(cli2, fnum2);
5067 if (!NT_STATUS_IS_OK(status)) {
5068 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5072 printf("non-io open test #5 passed.\n");
5074 printf("TEST #6 testing 1 non-io open, one io open\n");
5076 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5078 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5079 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5080 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5081 if (!NT_STATUS_IS_OK(status)) {
5082 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5086 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5087 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5088 FILE_OPEN_IF, 0, 0, &fnum2);
5089 if (!NT_STATUS_IS_OK(status)) {
5090 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5094 status = cli_close(cli1, fnum1);
5095 if (!NT_STATUS_IS_OK(status)) {
5096 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5100 status = cli_close(cli2, fnum2);
5101 if (!NT_STATUS_IS_OK(status)) {
5102 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5106 printf("non-io open test #6 passed.\n");
5108 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5110 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5112 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5113 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5114 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5115 if (!NT_STATUS_IS_OK(status)) {
5116 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5120 status = cli_ntcreate(cli2, fname, 0,
5121 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5122 FILE_ATTRIBUTE_NORMAL,
5123 FILE_SHARE_READ|FILE_SHARE_DELETE,
5124 FILE_OPEN_IF, 0, 0, &fnum2);
5125 if (NT_STATUS_IS_OK(status)) {
5126 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5130 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5132 status = cli_close(cli1, fnum1);
5133 if (!NT_STATUS_IS_OK(status)) {
5134 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5138 printf("non-io open test #7 passed.\n");
5140 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5142 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5143 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5144 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5145 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5146 if (!NT_STATUS_IS_OK(status)) {
5147 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5152 /* Write to ensure we have to update the file time. */
5153 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5155 if (!NT_STATUS_IS_OK(status)) {
5156 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5161 status = cli_close(cli1, fnum1);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5169 if (!torture_close_connection(cli1)) {
5172 if (!torture_close_connection(cli2)) {
5179 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5181 uint16 major, minor;
5182 uint32 caplow, caphigh;
5185 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5186 printf("Server doesn't support UNIX CIFS extensions.\n");
5187 return NT_STATUS_NOT_SUPPORTED;
5190 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5192 if (!NT_STATUS_IS_OK(status)) {
5193 printf("Server didn't return UNIX CIFS extensions: %s\n",
5198 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5200 if (!NT_STATUS_IS_OK(status)) {
5201 printf("Server doesn't support setting UNIX CIFS extensions: "
5202 "%s.\n", nt_errstr(status));
5206 return NT_STATUS_OK;
5210 Test POSIX open /mkdir calls.
5212 static bool run_simple_posix_open_test(int dummy)
5214 static struct cli_state *cli1;
5215 const char *fname = "posix:file";
5216 const char *hname = "posix:hlink";
5217 const char *sname = "posix:symlink";
5218 const char *dname = "posix:dir";
5221 uint16_t fnum1 = (uint16_t)-1;
5222 SMB_STRUCT_STAT sbuf;
5223 bool correct = false;
5226 printf("Starting simple POSIX open test\n");
5228 if (!torture_open_connection(&cli1, 0)) {
5232 cli_sockopt(cli1, sockops);
5234 status = torture_setup_unix_extensions(cli1);
5235 if (!NT_STATUS_IS_OK(status)) {
5239 cli_setatr(cli1, fname, 0, 0);
5240 cli_posix_unlink(cli1, fname);
5241 cli_setatr(cli1, dname, 0, 0);
5242 cli_posix_rmdir(cli1, dname);
5243 cli_setatr(cli1, hname, 0, 0);
5244 cli_posix_unlink(cli1, hname);
5245 cli_setatr(cli1, sname, 0, 0);
5246 cli_posix_unlink(cli1, sname);
5248 /* Create a directory. */
5249 status = cli_posix_mkdir(cli1, dname, 0777);
5250 if (!NT_STATUS_IS_OK(status)) {
5251 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5255 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5257 if (!NT_STATUS_IS_OK(status)) {
5258 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5262 /* Test ftruncate - set file size. */
5263 status = cli_ftruncate(cli1, fnum1, 1000);
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("ftruncate failed (%s)\n", nt_errstr(status));
5269 /* Ensure st_size == 1000 */
5270 status = cli_posix_stat(cli1, fname, &sbuf);
5271 if (!NT_STATUS_IS_OK(status)) {
5272 printf("stat failed (%s)\n", nt_errstr(status));
5276 if (sbuf.st_ex_size != 1000) {
5277 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5281 /* Test ftruncate - set file size back to zero. */
5282 status = cli_ftruncate(cli1, fnum1, 0);
5283 if (!NT_STATUS_IS_OK(status)) {
5284 printf("ftruncate failed (%s)\n", nt_errstr(status));
5288 status = cli_close(cli1, fnum1);
5289 if (!NT_STATUS_IS_OK(status)) {
5290 printf("close failed (%s)\n", nt_errstr(status));
5294 /* Now open the file again for read only. */
5295 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5296 if (!NT_STATUS_IS_OK(status)) {
5297 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5301 /* Now unlink while open. */
5302 status = cli_posix_unlink(cli1, fname);
5303 if (!NT_STATUS_IS_OK(status)) {
5304 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5308 status = cli_close(cli1, fnum1);
5309 if (!NT_STATUS_IS_OK(status)) {
5310 printf("close(2) failed (%s)\n", nt_errstr(status));
5314 /* Ensure the file has gone. */
5315 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5316 if (NT_STATUS_IS_OK(status)) {
5317 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5321 /* Create again to test open with O_TRUNC. */
5322 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5323 if (!NT_STATUS_IS_OK(status)) {
5324 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5328 /* Test ftruncate - set file size. */
5329 status = cli_ftruncate(cli1, fnum1, 1000);
5330 if (!NT_STATUS_IS_OK(status)) {
5331 printf("ftruncate failed (%s)\n", nt_errstr(status));
5335 /* Ensure st_size == 1000 */
5336 status = cli_posix_stat(cli1, fname, &sbuf);
5337 if (!NT_STATUS_IS_OK(status)) {
5338 printf("stat failed (%s)\n", nt_errstr(status));
5342 if (sbuf.st_ex_size != 1000) {
5343 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5347 status = cli_close(cli1, fnum1);
5348 if (!NT_STATUS_IS_OK(status)) {
5349 printf("close(2) failed (%s)\n", nt_errstr(status));
5353 /* Re-open with O_TRUNC. */
5354 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5355 if (!NT_STATUS_IS_OK(status)) {
5356 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5360 /* Ensure st_size == 0 */
5361 status = cli_posix_stat(cli1, fname, &sbuf);
5362 if (!NT_STATUS_IS_OK(status)) {
5363 printf("stat failed (%s)\n", nt_errstr(status));
5367 if (sbuf.st_ex_size != 0) {
5368 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5372 status = cli_close(cli1, fnum1);
5373 if (!NT_STATUS_IS_OK(status)) {
5374 printf("close failed (%s)\n", nt_errstr(status));
5378 status = cli_posix_unlink(cli1, fname);
5379 if (!NT_STATUS_IS_OK(status)) {
5380 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5384 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5385 if (!NT_STATUS_IS_OK(status)) {
5386 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5387 dname, nt_errstr(status));
5391 cli_close(cli1, fnum1);
5393 /* What happens when we try and POSIX open a directory for write ? */
5394 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5395 if (NT_STATUS_IS_OK(status)) {
5396 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5399 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5400 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5405 /* Create the file. */
5406 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5413 /* Write some data into it. */
5414 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5416 if (!NT_STATUS_IS_OK(status)) {
5417 printf("cli_write failed: %s\n", nt_errstr(status));
5421 cli_close(cli1, fnum1);
5423 /* Now create a hardlink. */
5424 status = cli_posix_hardlink(cli1, fname, hname);
5425 if (!NT_STATUS_IS_OK(status)) {
5426 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5430 /* Now create a symlink. */
5431 status = cli_posix_symlink(cli1, fname, sname);
5432 if (!NT_STATUS_IS_OK(status)) {
5433 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5437 /* Open the hardlink for read. */
5438 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5439 if (!NT_STATUS_IS_OK(status)) {
5440 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5444 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5445 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5449 if (memcmp(buf, "TEST DATA\n", 10)) {
5450 printf("invalid data read from hardlink\n");
5454 /* Do a POSIX lock/unlock. */
5455 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5456 if (!NT_STATUS_IS_OK(status)) {
5457 printf("POSIX lock failed %s\n", nt_errstr(status));
5461 /* Punch a hole in the locked area. */
5462 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5463 if (!NT_STATUS_IS_OK(status)) {
5464 printf("POSIX unlock failed %s\n", nt_errstr(status));
5468 cli_close(cli1, fnum1);
5470 /* Open the symlink for read - this should fail. A POSIX
5471 client should not be doing opens on a symlink. */
5472 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5473 if (NT_STATUS_IS_OK(status)) {
5474 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5477 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5478 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5479 printf("POSIX open of %s should have failed "
5480 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5481 "failed with %s instead.\n",
5482 sname, nt_errstr(status));
5487 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5488 if (!NT_STATUS_IS_OK(status)) {
5489 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5493 if (strcmp(namebuf, fname) != 0) {
5494 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5495 sname, fname, namebuf);
5499 status = cli_posix_rmdir(cli1, dname);
5500 if (!NT_STATUS_IS_OK(status)) {
5501 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5505 printf("Simple POSIX open test passed\n");
5510 if (fnum1 != (uint16_t)-1) {
5511 cli_close(cli1, fnum1);
5512 fnum1 = (uint16_t)-1;
5515 cli_setatr(cli1, sname, 0, 0);
5516 cli_posix_unlink(cli1, sname);
5517 cli_setatr(cli1, hname, 0, 0);
5518 cli_posix_unlink(cli1, hname);
5519 cli_setatr(cli1, fname, 0, 0);
5520 cli_posix_unlink(cli1, fname);
5521 cli_setatr(cli1, dname, 0, 0);
5522 cli_posix_rmdir(cli1, dname);
5524 if (!torture_close_connection(cli1)) {
5532 static uint32 open_attrs_table[] = {
5533 FILE_ATTRIBUTE_NORMAL,
5534 FILE_ATTRIBUTE_ARCHIVE,
5535 FILE_ATTRIBUTE_READONLY,
5536 FILE_ATTRIBUTE_HIDDEN,
5537 FILE_ATTRIBUTE_SYSTEM,
5539 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5540 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5541 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5542 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5543 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5544 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5546 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5547 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5548 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5549 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5552 struct trunc_open_results {
5559 static struct trunc_open_results attr_results[] = {
5560 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5561 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5562 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5563 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5564 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5565 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5566 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5567 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5568 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5569 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5570 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5571 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5572 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5573 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5574 { 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 },
5575 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5576 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5577 { 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 },
5578 { 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 },
5579 { 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 },
5580 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5581 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5582 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5583 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5584 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5585 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5588 static bool run_openattrtest(int dummy)
5590 static struct cli_state *cli1;
5591 const char *fname = "\\openattr.file";
5593 bool correct = True;
5595 unsigned int i, j, k, l;
5598 printf("starting open attr test\n");
5600 if (!torture_open_connection(&cli1, 0)) {
5604 cli_sockopt(cli1, sockops);
5606 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5607 cli_setatr(cli1, fname, 0, 0);
5608 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5610 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5611 open_attrs_table[i], FILE_SHARE_NONE,
5612 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5613 if (!NT_STATUS_IS_OK(status)) {
5614 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5618 status = cli_close(cli1, fnum1);
5619 if (!NT_STATUS_IS_OK(status)) {
5620 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5624 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5625 status = cli_ntcreate(cli1, fname, 0,
5626 FILE_READ_DATA|FILE_WRITE_DATA,
5627 open_attrs_table[j],
5628 FILE_SHARE_NONE, FILE_OVERWRITE,
5630 if (!NT_STATUS_IS_OK(status)) {
5631 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5632 if (attr_results[l].num == k) {
5633 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5634 k, open_attrs_table[i],
5635 open_attrs_table[j],
5636 fname, NT_STATUS_V(status), nt_errstr(status));
5641 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5642 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5643 k, open_attrs_table[i], open_attrs_table[j],
5648 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5654 status = cli_close(cli1, fnum1);
5655 if (!NT_STATUS_IS_OK(status)) {
5656 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5660 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5661 if (!NT_STATUS_IS_OK(status)) {
5662 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5667 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5668 k, open_attrs_table[i], open_attrs_table[j], attr );
5671 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5672 if (attr_results[l].num == k) {
5673 if (attr != attr_results[l].result_attr ||
5674 open_attrs_table[i] != attr_results[l].init_attr ||
5675 open_attrs_table[j] != attr_results[l].trunc_attr) {
5676 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5677 open_attrs_table[i],
5678 open_attrs_table[j],
5680 attr_results[l].result_attr);
5690 cli_setatr(cli1, fname, 0, 0);
5691 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5693 printf("open attr test %s.\n", correct ? "passed" : "failed");
5695 if (!torture_close_connection(cli1)) {
5701 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5702 const char *name, void *state)
5704 int *matched = (int *)state;
5705 if (matched != NULL) {
5708 return NT_STATUS_OK;
5712 test directory listing speed
5714 static bool run_dirtest(int dummy)
5717 static struct cli_state *cli;
5719 struct timeval core_start;
5720 bool correct = True;
5723 printf("starting directory test\n");
5725 if (!torture_open_connection(&cli, 0)) {
5729 cli_sockopt(cli, sockops);
5732 for (i=0;i<torture_numops;i++) {
5734 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5735 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5736 fprintf(stderr,"Failed to open %s\n", fname);
5739 cli_close(cli, fnum);
5742 core_start = timeval_current();
5745 cli_list(cli, "a*.*", 0, list_fn, &matched);
5746 printf("Matched %d\n", matched);
5749 cli_list(cli, "b*.*", 0, list_fn, &matched);
5750 printf("Matched %d\n", matched);
5753 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5754 printf("Matched %d\n", matched);
5756 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5759 for (i=0;i<torture_numops;i++) {
5761 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5762 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5765 if (!torture_close_connection(cli)) {
5769 printf("finished dirtest\n");
5774 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5777 struct cli_state *pcli = (struct cli_state *)state;
5779 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5781 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5782 return NT_STATUS_OK;
5784 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5785 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5786 printf("del_fn: failed to rmdir %s\n,", fname );
5788 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5789 printf("del_fn: failed to unlink %s\n,", fname );
5791 return NT_STATUS_OK;
5796 sees what IOCTLs are supported
5798 bool torture_ioctl_test(int dummy)
5800 static struct cli_state *cli;
5801 uint16_t device, function;
5803 const char *fname = "\\ioctl.dat";
5807 if (!torture_open_connection(&cli, 0)) {
5811 printf("starting ioctl test\n");
5813 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5815 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5816 if (!NT_STATUS_IS_OK(status)) {
5817 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5821 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5822 printf("ioctl device info: %s\n", nt_errstr(status));
5824 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5825 printf("ioctl job info: %s\n", nt_errstr(status));
5827 for (device=0;device<0x100;device++) {
5828 printf("ioctl test with device = 0x%x\n", device);
5829 for (function=0;function<0x100;function++) {
5830 uint32 code = (device<<16) | function;
5832 status = cli_raw_ioctl(cli, fnum, code, &blob);
5834 if (NT_STATUS_IS_OK(status)) {
5835 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5837 data_blob_free(&blob);
5842 if (!torture_close_connection(cli)) {
5851 tries varients of chkpath
5853 bool torture_chkpath_test(int dummy)
5855 static struct cli_state *cli;
5860 if (!torture_open_connection(&cli, 0)) {
5864 printf("starting chkpath test\n");
5866 /* cleanup from an old run */
5867 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5868 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5869 cli_rmdir(cli, "\\chkpath.dir");
5871 status = cli_mkdir(cli, "\\chkpath.dir");
5872 if (!NT_STATUS_IS_OK(status)) {
5873 printf("mkdir1 failed : %s\n", nt_errstr(status));
5877 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5878 if (!NT_STATUS_IS_OK(status)) {
5879 printf("mkdir2 failed : %s\n", nt_errstr(status));
5883 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5885 if (!NT_STATUS_IS_OK(status)) {
5886 printf("open1 failed (%s)\n", nt_errstr(status));
5889 cli_close(cli, fnum);
5891 status = cli_chkpath(cli, "\\chkpath.dir");
5892 if (!NT_STATUS_IS_OK(status)) {
5893 printf("chkpath1 failed: %s\n", nt_errstr(status));
5897 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5898 if (!NT_STATUS_IS_OK(status)) {
5899 printf("chkpath2 failed: %s\n", nt_errstr(status));
5903 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5904 if (!NT_STATUS_IS_OK(status)) {
5905 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5906 NT_STATUS_NOT_A_DIRECTORY);
5908 printf("* chkpath on a file should fail\n");
5912 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5913 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5914 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5916 printf("* chkpath on a non existant file should fail\n");
5920 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5921 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5922 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5924 printf("* chkpath on a non existent component should fail\n");
5928 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5929 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5930 cli_rmdir(cli, "\\chkpath.dir");
5932 if (!torture_close_connection(cli)) {
5939 static bool run_eatest(int dummy)
5941 static struct cli_state *cli;
5942 const char *fname = "\\eatest.txt";
5943 bool correct = True;
5947 struct ea_struct *ea_list = NULL;
5948 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5951 printf("starting eatest\n");
5953 if (!torture_open_connection(&cli, 0)) {
5954 talloc_destroy(mem_ctx);
5958 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5960 status = cli_ntcreate(cli, fname, 0,
5961 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5962 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5964 if (!NT_STATUS_IS_OK(status)) {
5965 printf("open failed - %s\n", nt_errstr(status));
5966 talloc_destroy(mem_ctx);
5970 for (i = 0; i < 10; i++) {
5971 fstring ea_name, ea_val;
5973 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5974 memset(ea_val, (char)i+1, i+1);
5975 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5976 if (!NT_STATUS_IS_OK(status)) {
5977 printf("ea_set of name %s failed - %s\n", ea_name,
5979 talloc_destroy(mem_ctx);
5984 cli_close(cli, fnum);
5985 for (i = 0; i < 10; i++) {
5986 fstring ea_name, ea_val;
5988 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5989 memset(ea_val, (char)i+1, i+1);
5990 status = cli_set_ea_path(cli, fname, 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 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6000 if (!NT_STATUS_IS_OK(status)) {
6001 printf("ea_get list failed - %s\n", nt_errstr(status));
6005 printf("num_eas = %d\n", (int)num_eas);
6007 if (num_eas != 20) {
6008 printf("Should be 20 EA's stored... failing.\n");
6012 for (i = 0; i < num_eas; i++) {
6013 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6014 dump_data(0, ea_list[i].value.data,
6015 ea_list[i].value.length);
6018 /* Setting EA's to zero length deletes them. Test this */
6019 printf("Now deleting all EA's - case indepenent....\n");
6022 cli_set_ea_path(cli, fname, "", "", 0);
6024 for (i = 0; i < 20; i++) {
6026 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6027 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6028 if (!NT_STATUS_IS_OK(status)) {
6029 printf("ea_set of name %s failed - %s\n", ea_name,
6031 talloc_destroy(mem_ctx);
6037 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6038 if (!NT_STATUS_IS_OK(status)) {
6039 printf("ea_get list failed - %s\n", nt_errstr(status));
6043 printf("num_eas = %d\n", (int)num_eas);
6044 for (i = 0; i < num_eas; i++) {
6045 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6046 dump_data(0, ea_list[i].value.data,
6047 ea_list[i].value.length);
6051 printf("deleting EA's failed.\n");
6055 /* Try and delete a non existant EA. */
6056 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6057 if (!NT_STATUS_IS_OK(status)) {
6058 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6063 talloc_destroy(mem_ctx);
6064 if (!torture_close_connection(cli)) {
6071 static bool run_dirtest1(int dummy)
6074 static struct cli_state *cli;
6077 bool correct = True;
6079 printf("starting directory test\n");
6081 if (!torture_open_connection(&cli, 0)) {
6085 cli_sockopt(cli, sockops);
6087 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6088 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6089 cli_rmdir(cli, "\\LISTDIR");
6090 cli_mkdir(cli, "\\LISTDIR");
6092 /* Create 1000 files and 1000 directories. */
6093 for (i=0;i<1000;i++) {
6095 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6096 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6097 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6098 fprintf(stderr,"Failed to open %s\n", fname);
6101 cli_close(cli, fnum);
6103 for (i=0;i<1000;i++) {
6105 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6106 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6107 fprintf(stderr,"Failed to open %s\n", fname);
6112 /* Now ensure that doing an old list sees both files and directories. */
6114 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6115 printf("num_seen = %d\n", num_seen );
6116 /* We should see 100 files + 1000 directories + . and .. */
6117 if (num_seen != 2002)
6120 /* Ensure if we have the "must have" bits we only see the
6124 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6125 printf("num_seen = %d\n", num_seen );
6126 if (num_seen != 1002)
6130 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6131 printf("num_seen = %d\n", num_seen );
6132 if (num_seen != 1000)
6135 /* Delete everything. */
6136 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6137 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6138 cli_rmdir(cli, "\\LISTDIR");
6141 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6142 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6143 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6146 if (!torture_close_connection(cli)) {
6150 printf("finished dirtest1\n");
6155 static bool run_error_map_extract(int dummy) {
6157 static struct cli_state *c_dos;
6158 static struct cli_state *c_nt;
6170 /* NT-Error connection */
6172 if (!(c_nt = open_nbt_connection())) {
6176 c_nt->use_spnego = False;
6178 status = cli_negprot(c_nt);
6180 if (!NT_STATUS_IS_OK(status)) {
6181 printf("%s rejected the NT-error negprot (%s)\n", host,
6187 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6188 if (!NT_STATUS_IS_OK(status)) {
6189 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6193 /* DOS-Error connection */
6195 if (!(c_dos = open_nbt_connection())) {
6199 c_dos->use_spnego = False;
6200 c_dos->force_dos_errors = True;
6202 status = cli_negprot(c_dos);
6203 if (!NT_STATUS_IS_OK(status)) {
6204 printf("%s rejected the DOS-error negprot (%s)\n", host,
6206 cli_shutdown(c_dos);
6210 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6211 if (!NT_STATUS_IS_OK(status)) {
6212 printf("%s rejected the DOS-error initial session setup (%s)\n",
6213 host, nt_errstr(status));
6217 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6218 fstr_sprintf(user, "%X", error);
6220 status = cli_session_setup(c_nt, user,
6221 password, strlen(password),
6222 password, strlen(password),
6224 if (NT_STATUS_IS_OK(status)) {
6225 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6228 /* Case #1: 32-bit NT errors */
6229 if (cli_is_nt_error(c_nt)) {
6230 nt_status = cli_nt_error(c_nt);
6232 printf("/** Dos error on NT connection! (%s) */\n",
6234 nt_status = NT_STATUS(0xc0000000);
6237 status = cli_session_setup(c_dos, user,
6238 password, strlen(password),
6239 password, strlen(password),
6241 if (NT_STATUS_IS_OK(status)) {
6242 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6245 /* Case #1: 32-bit NT errors */
6246 if (!cli_is_dos_error(c_dos)) {
6247 printf("/** NT error on DOS connection! (%s) */\n",
6249 errnum = errclass = 0;
6251 cli_dos_error(c_dos, &errclass, &errnum);
6254 if (NT_STATUS_V(nt_status) != error) {
6255 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6256 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6257 get_nt_error_c_code(talloc_tos(), nt_status));
6260 printf("\t{%s,\t%s,\t%s},\n",
6261 smb_dos_err_class(errclass),
6262 smb_dos_err_name(errclass, errnum),
6263 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6268 static bool run_sesssetup_bench(int dummy)
6270 static struct cli_state *c;
6271 const char *fname = "\\file.dat";
6276 if (!torture_open_connection(&c, 0)) {
6280 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6281 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6282 FILE_DELETE_ON_CLOSE, 0, &fnum);
6283 if (!NT_STATUS_IS_OK(status)) {
6284 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6288 for (i=0; i<torture_numops; i++) {
6289 status = cli_session_setup(
6291 password, strlen(password),
6292 password, strlen(password),
6294 if (!NT_STATUS_IS_OK(status)) {
6295 d_printf("(%s) cli_session_setup failed: %s\n",
6296 __location__, nt_errstr(status));
6300 d_printf("\r%d ", (int)c->vuid);
6302 status = cli_ulogoff(c);
6303 if (!NT_STATUS_IS_OK(status)) {
6304 d_printf("(%s) cli_ulogoff failed: %s\n",
6305 __location__, nt_errstr(status));
6314 static bool subst_test(const char *str, const char *user, const char *domain,
6315 uid_t uid, gid_t gid, const char *expected)
6320 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6322 if (strcmp(subst, expected) != 0) {
6323 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6324 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6333 static void chain1_open_completion(struct tevent_req *req)
6337 status = cli_open_recv(req, &fnum);
6340 d_printf("cli_open_recv returned %s: %d\n",
6342 NT_STATUS_IS_OK(status) ? fnum : -1);
6345 static void chain1_write_completion(struct tevent_req *req)
6349 status = cli_write_andx_recv(req, &written);
6352 d_printf("cli_write_andx_recv returned %s: %d\n",
6354 NT_STATUS_IS_OK(status) ? (int)written : -1);
6357 static void chain1_close_completion(struct tevent_req *req)
6360 bool *done = (bool *)tevent_req_callback_data_void(req);
6362 status = cli_close_recv(req);
6367 d_printf("cli_close returned %s\n", nt_errstr(status));
6370 static bool run_chain1(int dummy)
6372 struct cli_state *cli1;
6373 struct event_context *evt = event_context_init(NULL);
6374 struct tevent_req *reqs[3], *smbreqs[3];
6376 const char *str = "foobar";
6379 printf("starting chain1 test\n");
6380 if (!torture_open_connection(&cli1, 0)) {
6384 cli_sockopt(cli1, sockops);
6386 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6387 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6388 if (reqs[0] == NULL) return false;
6389 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6392 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6393 (const uint8_t *)str, 0, strlen(str)+1,
6394 smbreqs, 1, &smbreqs[1]);
6395 if (reqs[1] == NULL) return false;
6396 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6398 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6399 if (reqs[2] == NULL) return false;
6400 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6402 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6403 if (!NT_STATUS_IS_OK(status)) {
6408 event_loop_once(evt);
6411 torture_close_connection(cli1);
6415 static void chain2_sesssetup_completion(struct tevent_req *req)
6418 status = cli_session_setup_guest_recv(req);
6419 d_printf("sesssetup returned %s\n", nt_errstr(status));
6422 static void chain2_tcon_completion(struct tevent_req *req)
6424 bool *done = (bool *)tevent_req_callback_data_void(req);
6426 status = cli_tcon_andx_recv(req);
6427 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6431 static bool run_chain2(int dummy)
6433 struct cli_state *cli1;
6434 struct event_context *evt = event_context_init(NULL);
6435 struct tevent_req *reqs[2], *smbreqs[2];
6439 printf("starting chain2 test\n");
6440 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6441 port_to_use, Undefined, 0);
6442 if (!NT_STATUS_IS_OK(status)) {
6446 cli_sockopt(cli1, sockops);
6448 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6450 if (reqs[0] == NULL) return false;
6451 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6453 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6454 "?????", NULL, 0, &smbreqs[1]);
6455 if (reqs[1] == NULL) return false;
6456 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6458 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6459 if (!NT_STATUS_IS_OK(status)) {
6464 event_loop_once(evt);
6467 torture_close_connection(cli1);
6472 struct torture_createdel_state {
6473 struct tevent_context *ev;
6474 struct cli_state *cli;
6477 static void torture_createdel_created(struct tevent_req *subreq);
6478 static void torture_createdel_closed(struct tevent_req *subreq);
6480 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6481 struct tevent_context *ev,
6482 struct cli_state *cli,
6485 struct tevent_req *req, *subreq;
6486 struct torture_createdel_state *state;
6488 req = tevent_req_create(mem_ctx, &state,
6489 struct torture_createdel_state);
6496 subreq = cli_ntcreate_send(
6497 state, ev, cli, name, 0,
6498 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6499 FILE_ATTRIBUTE_NORMAL,
6500 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6501 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6503 if (tevent_req_nomem(subreq, req)) {
6504 return tevent_req_post(req, ev);
6506 tevent_req_set_callback(subreq, torture_createdel_created, req);
6510 static void torture_createdel_created(struct tevent_req *subreq)
6512 struct tevent_req *req = tevent_req_callback_data(
6513 subreq, struct tevent_req);
6514 struct torture_createdel_state *state = tevent_req_data(
6515 req, struct torture_createdel_state);
6519 status = cli_ntcreate_recv(subreq, &fnum);
6520 TALLOC_FREE(subreq);
6521 if (!NT_STATUS_IS_OK(status)) {
6522 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6523 nt_errstr(status)));
6524 tevent_req_nterror(req, status);
6528 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6529 if (tevent_req_nomem(subreq, req)) {
6532 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6535 static void torture_createdel_closed(struct tevent_req *subreq)
6537 struct tevent_req *req = tevent_req_callback_data(
6538 subreq, struct tevent_req);
6541 status = cli_close_recv(subreq);
6542 if (!NT_STATUS_IS_OK(status)) {
6543 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6544 tevent_req_nterror(req, status);
6547 tevent_req_done(req);
6550 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6552 return tevent_req_simple_recv_ntstatus(req);
6555 struct torture_createdels_state {
6556 struct tevent_context *ev;
6557 struct cli_state *cli;
6558 const char *base_name;
6562 struct tevent_req **reqs;
6565 static void torture_createdels_done(struct tevent_req *subreq);
6567 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6568 struct tevent_context *ev,
6569 struct cli_state *cli,
6570 const char *base_name,
6574 struct tevent_req *req;
6575 struct torture_createdels_state *state;
6578 req = tevent_req_create(mem_ctx, &state,
6579 struct torture_createdels_state);
6585 state->base_name = talloc_strdup(state, base_name);
6586 if (tevent_req_nomem(state->base_name, req)) {
6587 return tevent_req_post(req, ev);
6589 state->num_files = MAX(num_parallel, num_files);
6591 state->received = 0;
6593 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6594 if (tevent_req_nomem(state->reqs, req)) {
6595 return tevent_req_post(req, ev);
6598 for (i=0; i<num_parallel; i++) {
6601 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6603 if (tevent_req_nomem(name, req)) {
6604 return tevent_req_post(req, ev);
6606 state->reqs[i] = torture_createdel_send(
6607 state->reqs, state->ev, state->cli, name);
6608 if (tevent_req_nomem(state->reqs[i], req)) {
6609 return tevent_req_post(req, ev);
6611 name = talloc_move(state->reqs[i], &name);
6612 tevent_req_set_callback(state->reqs[i],
6613 torture_createdels_done, req);
6619 static void torture_createdels_done(struct tevent_req *subreq)
6621 struct tevent_req *req = tevent_req_callback_data(
6622 subreq, struct tevent_req);
6623 struct torture_createdels_state *state = tevent_req_data(
6624 req, struct torture_createdels_state);
6625 size_t num_parallel = talloc_array_length(state->reqs);
6630 status = torture_createdel_recv(subreq);
6631 if (!NT_STATUS_IS_OK(status)){
6632 DEBUG(10, ("torture_createdel_recv returned %s\n",
6633 nt_errstr(status)));
6634 TALLOC_FREE(subreq);
6635 tevent_req_nterror(req, status);
6639 for (i=0; i<num_parallel; i++) {
6640 if (subreq == state->reqs[i]) {
6644 if (i == num_parallel) {
6645 DEBUG(10, ("received something we did not send\n"));
6646 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6649 TALLOC_FREE(state->reqs[i]);
6651 if (state->sent >= state->num_files) {
6652 tevent_req_done(req);
6656 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6658 if (tevent_req_nomem(name, req)) {
6661 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6663 if (tevent_req_nomem(state->reqs[i], req)) {
6666 name = talloc_move(state->reqs[i], &name);
6667 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6671 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6673 return tevent_req_simple_recv_ntstatus(req);
6676 struct swallow_notify_state {
6677 struct tevent_context *ev;
6678 struct cli_state *cli;
6680 uint32_t completion_filter;
6682 bool (*fn)(uint32_t action, const char *name, void *priv);
6686 static void swallow_notify_done(struct tevent_req *subreq);
6688 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6689 struct tevent_context *ev,
6690 struct cli_state *cli,
6692 uint32_t completion_filter,
6694 bool (*fn)(uint32_t action,
6699 struct tevent_req *req, *subreq;
6700 struct swallow_notify_state *state;
6702 req = tevent_req_create(mem_ctx, &state,
6703 struct swallow_notify_state);
6710 state->completion_filter = completion_filter;
6711 state->recursive = recursive;
6715 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6716 0xffff, state->completion_filter,
6718 if (tevent_req_nomem(subreq, req)) {
6719 return tevent_req_post(req, ev);
6721 tevent_req_set_callback(subreq, swallow_notify_done, req);
6725 static void swallow_notify_done(struct tevent_req *subreq)
6727 struct tevent_req *req = tevent_req_callback_data(
6728 subreq, struct tevent_req);
6729 struct swallow_notify_state *state = tevent_req_data(
6730 req, struct swallow_notify_state);
6732 uint32_t i, num_changes;
6733 struct notify_change *changes;
6735 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6736 TALLOC_FREE(subreq);
6737 if (!NT_STATUS_IS_OK(status)) {
6738 DEBUG(10, ("cli_notify_recv returned %s\n",
6739 nt_errstr(status)));
6740 tevent_req_nterror(req, status);
6744 for (i=0; i<num_changes; i++) {
6745 state->fn(changes[i].action, changes[i].name, state->priv);
6747 TALLOC_FREE(changes);
6749 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6750 0xffff, state->completion_filter,
6752 if (tevent_req_nomem(subreq, req)) {
6755 tevent_req_set_callback(subreq, swallow_notify_done, req);
6758 static bool print_notifies(uint32_t action, const char *name, void *priv)
6760 if (DEBUGLEVEL > 5) {
6761 d_printf("%d %s\n", (int)action, name);
6766 static void notify_bench_done(struct tevent_req *req)
6768 int *num_finished = (int *)tevent_req_callback_data_void(req);
6772 static bool run_notify_bench(int dummy)
6774 const char *dname = "\\notify-bench";
6775 struct tevent_context *ev;
6778 struct tevent_req *req1;
6779 struct tevent_req *req2 = NULL;
6780 int i, num_unc_names;
6781 int num_finished = 0;
6783 printf("starting notify-bench test\n");
6785 if (use_multishare_conn) {
6787 unc_list = file_lines_load(multishare_conn_fname,
6788 &num_unc_names, 0, NULL);
6789 if (!unc_list || num_unc_names <= 0) {
6790 d_printf("Failed to load unc names list from '%s'\n",
6791 multishare_conn_fname);
6794 TALLOC_FREE(unc_list);
6799 ev = tevent_context_init(talloc_tos());
6801 d_printf("tevent_context_init failed\n");
6805 for (i=0; i<num_unc_names; i++) {
6806 struct cli_state *cli;
6809 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6811 if (base_fname == NULL) {
6815 if (!torture_open_connection(&cli, i)) {
6819 status = cli_ntcreate(cli, dname, 0,
6820 MAXIMUM_ALLOWED_ACCESS,
6821 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6823 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6826 if (!NT_STATUS_IS_OK(status)) {
6827 d_printf("Could not create %s: %s\n", dname,
6832 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6833 FILE_NOTIFY_CHANGE_FILE_NAME |
6834 FILE_NOTIFY_CHANGE_DIR_NAME |
6835 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6836 FILE_NOTIFY_CHANGE_LAST_WRITE,
6837 false, print_notifies, NULL);
6839 d_printf("Could not create notify request\n");
6843 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6844 base_fname, 10, torture_numops);
6846 d_printf("Could not create createdels request\n");
6849 TALLOC_FREE(base_fname);
6851 tevent_req_set_callback(req2, notify_bench_done,
6855 while (num_finished < num_unc_names) {
6857 ret = tevent_loop_once(ev);
6859 d_printf("tevent_loop_once failed\n");
6864 if (!tevent_req_poll(req2, ev)) {
6865 d_printf("tevent_req_poll failed\n");
6868 status = torture_createdels_recv(req2);
6869 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6874 static bool run_mangle1(int dummy)
6876 struct cli_state *cli;
6877 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6881 time_t change_time, access_time, write_time;
6885 printf("starting mangle1 test\n");
6886 if (!torture_open_connection(&cli, 0)) {
6890 cli_sockopt(cli, sockops);
6892 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6893 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6895 if (!NT_STATUS_IS_OK(status)) {
6896 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6899 cli_close(cli, fnum);
6901 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6902 if (!NT_STATUS_IS_OK(status)) {
6903 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6907 d_printf("alt_name: %s\n", alt_name);
6909 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6910 if (!NT_STATUS_IS_OK(status)) {
6911 d_printf("cli_open(%s) failed: %s\n", alt_name,
6915 cli_close(cli, fnum);
6917 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6918 &write_time, &size, &mode);
6919 if (!NT_STATUS_IS_OK(status)) {
6920 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6928 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6930 size_t *to_pull = (size_t *)priv;
6931 size_t thistime = *to_pull;
6933 thistime = MIN(thistime, n);
6934 if (thistime == 0) {
6938 memset(buf, 0, thistime);
6939 *to_pull -= thistime;
6943 static bool run_windows_write(int dummy)
6945 struct cli_state *cli1;
6949 const char *fname = "\\writetest.txt";
6950 struct timeval start_time;
6955 printf("starting windows_write test\n");
6956 if (!torture_open_connection(&cli1, 0)) {
6960 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6961 if (!NT_STATUS_IS_OK(status)) {
6962 printf("open failed (%s)\n", nt_errstr(status));
6966 cli_sockopt(cli1, sockops);
6968 start_time = timeval_current();
6970 for (i=0; i<torture_numops; i++) {
6972 off_t start = i * torture_blocksize;
6973 size_t to_pull = torture_blocksize - 1;
6975 status = cli_writeall(cli1, fnum, 0, &c,
6976 start + torture_blocksize - 1, 1, NULL);
6977 if (!NT_STATUS_IS_OK(status)) {
6978 printf("cli_write failed: %s\n", nt_errstr(status));
6982 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6983 null_source, &to_pull);
6984 if (!NT_STATUS_IS_OK(status)) {
6985 printf("cli_push returned: %s\n", nt_errstr(status));
6990 seconds = timeval_elapsed(&start_time);
6991 kbytes = (double)torture_blocksize * torture_numops;
6994 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6995 (double)seconds, (int)(kbytes/seconds));
6999 cli_close(cli1, fnum);
7000 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7001 torture_close_connection(cli1);
7005 static bool run_cli_echo(int dummy)
7007 struct cli_state *cli;
7010 printf("starting cli_echo test\n");
7011 if (!torture_open_connection(&cli, 0)) {
7014 cli_sockopt(cli, sockops);
7016 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7018 d_printf("cli_echo returned %s\n", nt_errstr(status));
7020 torture_close_connection(cli);
7021 return NT_STATUS_IS_OK(status);
7024 static bool run_uid_regression_test(int dummy)
7026 static struct cli_state *cli;
7029 bool correct = True;
7032 printf("starting uid regression test\n");
7034 if (!torture_open_connection(&cli, 0)) {
7038 cli_sockopt(cli, sockops);
7040 /* Ok - now save then logoff our current user. */
7041 old_vuid = cli->vuid;
7043 status = cli_ulogoff(cli);
7044 if (!NT_STATUS_IS_OK(status)) {
7045 d_printf("(%s) cli_ulogoff failed: %s\n",
7046 __location__, nt_errstr(status));
7051 cli->vuid = old_vuid;
7053 /* Try an operation. */
7054 status = cli_mkdir(cli, "\\uid_reg_test");
7055 if (NT_STATUS_IS_OK(status)) {
7056 d_printf("(%s) cli_mkdir succeeded\n",
7061 /* Should be bad uid. */
7062 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7063 NT_STATUS_USER_SESSION_DELETED)) {
7069 old_cnum = cli->cnum;
7071 /* Now try a SMBtdis with the invald vuid set to zero. */
7074 /* This should succeed. */
7075 status = cli_tdis(cli);
7077 if (NT_STATUS_IS_OK(status)) {
7078 d_printf("First tdis with invalid vuid should succeed.\n");
7080 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7085 cli->vuid = old_vuid;
7086 cli->cnum = old_cnum;
7088 /* This should fail. */
7089 status = cli_tdis(cli);
7090 if (NT_STATUS_IS_OK(status)) {
7091 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7095 /* Should be bad tid. */
7096 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7097 NT_STATUS_NETWORK_NAME_DELETED)) {
7103 cli_rmdir(cli, "\\uid_reg_test");
7112 static const char *illegal_chars = "*\\/?<>|\":";
7113 static char force_shortname_chars[] = " +,.[];=\177";
7115 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7116 const char *mask, void *state)
7118 struct cli_state *pcli = (struct cli_state *)state;
7120 NTSTATUS status = NT_STATUS_OK;
7122 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7124 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7125 return NT_STATUS_OK;
7127 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7128 status = cli_rmdir(pcli, fname);
7129 if (!NT_STATUS_IS_OK(status)) {
7130 printf("del_fn: failed to rmdir %s\n,", fname );
7133 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7134 if (!NT_STATUS_IS_OK(status)) {
7135 printf("del_fn: failed to unlink %s\n,", fname );
7147 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7148 const char *name, void *state)
7150 struct sn_state *s = (struct sn_state *)state;
7154 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7155 i, finfo->name, finfo->short_name);
7158 if (strchr(force_shortname_chars, i)) {
7159 if (!finfo->short_name) {
7160 /* Shortname not created when it should be. */
7161 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7162 __location__, finfo->name, i);
7165 } else if (finfo->short_name){
7166 /* Shortname created when it should not be. */
7167 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7168 __location__, finfo->short_name, finfo->name);
7172 return NT_STATUS_OK;
7175 static bool run_shortname_test(int dummy)
7177 static struct cli_state *cli;
7178 bool correct = True;
7184 printf("starting shortname test\n");
7186 if (!torture_open_connection(&cli, 0)) {
7190 cli_sockopt(cli, sockops);
7192 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7193 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7194 cli_rmdir(cli, "\\shortname");
7196 status = cli_mkdir(cli, "\\shortname");
7197 if (!NT_STATUS_IS_OK(status)) {
7198 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7199 __location__, nt_errstr(status));
7204 strlcpy(fname, "\\shortname\\", sizeof(fname));
7205 strlcat(fname, "test .txt", sizeof(fname));
7209 for (i = 32; i < 128; i++) {
7210 uint16_t fnum = (uint16_t)-1;
7214 if (strchr(illegal_chars, i)) {
7219 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7220 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7221 if (!NT_STATUS_IS_OK(status)) {
7222 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7223 __location__, fname, nt_errstr(status));
7227 cli_close(cli, fnum);
7230 status = cli_list(cli, "\\shortname\\test*.*", 0,
7231 shortname_list_fn, &s);
7232 if (s.matched != 1) {
7233 d_printf("(%s) failed to list %s: %s\n",
7234 __location__, fname, nt_errstr(status));
7239 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7240 if (!NT_STATUS_IS_OK(status)) {
7241 d_printf("(%s) failed to delete %s: %s\n",
7242 __location__, fname, nt_errstr(status));
7255 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7256 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7257 cli_rmdir(cli, "\\shortname");
7258 torture_close_connection(cli);
7262 static void pagedsearch_cb(struct tevent_req *req)
7265 struct tldap_message *msg;
7268 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7269 if (rc != TLDAP_SUCCESS) {
7270 d_printf("tldap_search_paged_recv failed: %s\n",
7271 tldap_err2string(rc));
7274 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7278 if (!tldap_entry_dn(msg, &dn)) {
7279 d_printf("tldap_entry_dn failed\n");
7282 d_printf("%s\n", dn);
7286 static bool run_tldap(int dummy)
7288 struct tldap_context *ld;
7291 struct sockaddr_storage addr;
7292 struct tevent_context *ev;
7293 struct tevent_req *req;
7297 if (!resolve_name(host, &addr, 0, false)) {
7298 d_printf("could not find host %s\n", host);
7301 status = open_socket_out(&addr, 389, 9999, &fd);
7302 if (!NT_STATUS_IS_OK(status)) {
7303 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7307 ld = tldap_context_create(talloc_tos(), fd);
7310 d_printf("tldap_context_create failed\n");
7314 rc = tldap_fetch_rootdse(ld);
7315 if (rc != TLDAP_SUCCESS) {
7316 d_printf("tldap_fetch_rootdse failed: %s\n",
7317 tldap_errstr(talloc_tos(), ld, rc));
7321 basedn = tldap_talloc_single_attribute(
7322 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7323 if (basedn == NULL) {
7324 d_printf("no defaultNamingContext\n");
7327 d_printf("defaultNamingContext: %s\n", basedn);
7329 ev = tevent_context_init(talloc_tos());
7331 d_printf("tevent_context_init failed\n");
7335 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7336 TLDAP_SCOPE_SUB, "(objectclass=*)",
7338 NULL, 0, NULL, 0, 0, 0, 0, 5);
7340 d_printf("tldap_search_paged_send failed\n");
7343 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7345 tevent_req_poll(req, ev);
7349 /* test search filters against rootDSE */
7350 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7351 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7353 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7354 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7355 talloc_tos(), NULL, NULL);
7356 if (rc != TLDAP_SUCCESS) {
7357 d_printf("tldap_search with complex filter failed: %s\n",
7358 tldap_errstr(talloc_tos(), ld, rc));
7366 /* Torture test to ensure no regression of :
7367 https://bugzilla.samba.org/show_bug.cgi?id=7084
7370 static bool run_dir_createtime(int dummy)
7372 struct cli_state *cli;
7373 const char *dname = "\\testdir";
7374 const char *fname = "\\testdir\\testfile";
7376 struct timespec create_time;
7377 struct timespec create_time1;
7381 if (!torture_open_connection(&cli, 0)) {
7385 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7386 cli_rmdir(cli, dname);
7388 status = cli_mkdir(cli, dname);
7389 if (!NT_STATUS_IS_OK(status)) {
7390 printf("mkdir failed: %s\n", nt_errstr(status));
7394 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7396 if (!NT_STATUS_IS_OK(status)) {
7397 printf("cli_qpathinfo2 returned %s\n",
7402 /* Sleep 3 seconds, then create a file. */
7405 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7407 if (!NT_STATUS_IS_OK(status)) {
7408 printf("cli_open failed: %s\n", nt_errstr(status));
7412 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7414 if (!NT_STATUS_IS_OK(status)) {
7415 printf("cli_qpathinfo2 (2) returned %s\n",
7420 if (timespec_compare(&create_time1, &create_time)) {
7421 printf("run_dir_createtime: create time was updated (error)\n");
7423 printf("run_dir_createtime: create time was not updated (correct)\n");
7429 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7430 cli_rmdir(cli, dname);
7431 if (!torture_close_connection(cli)) {
7438 static bool run_streamerror(int dummy)
7440 struct cli_state *cli;
7441 const char *dname = "\\testdir";
7442 const char *streamname =
7443 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7445 time_t change_time, access_time, write_time;
7447 uint16_t mode, fnum;
7450 if (!torture_open_connection(&cli, 0)) {
7454 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7455 cli_rmdir(cli, dname);
7457 status = cli_mkdir(cli, dname);
7458 if (!NT_STATUS_IS_OK(status)) {
7459 printf("mkdir failed: %s\n", nt_errstr(status));
7463 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7465 status = cli_nt_error(cli);
7467 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7468 printf("pathinfo returned %s, expected "
7469 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7474 status = cli_ntcreate(cli, streamname, 0x16,
7475 FILE_READ_DATA|FILE_READ_EA|
7476 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7477 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7478 FILE_OPEN, 0, 0, &fnum);
7480 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7481 printf("ntcreate returned %s, expected "
7482 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7488 cli_rmdir(cli, dname);
7492 static bool run_local_substitute(int dummy)
7496 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7497 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7498 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7499 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7500 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7501 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7502 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7503 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7505 /* Different captialization rules in sub_basic... */
7507 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7513 static bool run_local_base64(int dummy)
7518 for (i=1; i<2000; i++) {
7519 DATA_BLOB blob1, blob2;
7522 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7524 generate_random_buffer(blob1.data, blob1.length);
7526 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7528 d_fprintf(stderr, "base64_encode_data_blob failed "
7529 "for %d bytes\n", i);
7532 blob2 = base64_decode_data_blob(b64);
7535 if (data_blob_cmp(&blob1, &blob2)) {
7536 d_fprintf(stderr, "data_blob_cmp failed for %d "
7540 TALLOC_FREE(blob1.data);
7541 data_blob_free(&blob2);
7546 static bool run_local_gencache(int dummy)
7552 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7553 d_printf("%s: gencache_set() failed\n", __location__);
7557 if (!gencache_get("foo", NULL, NULL)) {
7558 d_printf("%s: gencache_get() failed\n", __location__);
7562 if (!gencache_get("foo", &val, &tm)) {
7563 d_printf("%s: gencache_get() failed\n", __location__);
7567 if (strcmp(val, "bar") != 0) {
7568 d_printf("%s: gencache_get() returned %s, expected %s\n",
7569 __location__, val, "bar");
7576 if (!gencache_del("foo")) {
7577 d_printf("%s: gencache_del() failed\n", __location__);
7580 if (gencache_del("foo")) {
7581 d_printf("%s: second gencache_del() succeeded\n",
7586 if (gencache_get("foo", &val, &tm)) {
7587 d_printf("%s: gencache_get() on deleted entry "
7588 "succeeded\n", __location__);
7592 blob = data_blob_string_const_null("bar");
7593 tm = time(NULL) + 60;
7595 if (!gencache_set_data_blob("foo", &blob, tm)) {
7596 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7600 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7601 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7605 if (strcmp((const char *)blob.data, "bar") != 0) {
7606 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7607 __location__, (const char *)blob.data, "bar");
7608 data_blob_free(&blob);
7612 data_blob_free(&blob);
7614 if (!gencache_del("foo")) {
7615 d_printf("%s: gencache_del() failed\n", __location__);
7618 if (gencache_del("foo")) {
7619 d_printf("%s: second gencache_del() succeeded\n",
7624 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7625 d_printf("%s: gencache_get_data_blob() on deleted entry "
7626 "succeeded\n", __location__);
7633 static bool rbt_testval(struct db_context *db, const char *key,
7636 struct db_record *rec;
7637 TDB_DATA data = string_tdb_data(value);
7641 rec = db->fetch_locked(db, db, string_tdb_data(key));
7643 d_fprintf(stderr, "fetch_locked failed\n");
7646 status = rec->store(rec, data, 0);
7647 if (!NT_STATUS_IS_OK(status)) {
7648 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7653 rec = db->fetch_locked(db, db, string_tdb_data(key));
7655 d_fprintf(stderr, "second fetch_locked failed\n");
7658 if ((rec->value.dsize != data.dsize)
7659 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7660 d_fprintf(stderr, "Got wrong data back\n");
7670 static bool run_local_rbtree(int dummy)
7672 struct db_context *db;
7676 db = db_open_rbt(NULL);
7679 d_fprintf(stderr, "db_open_rbt failed\n");
7683 for (i=0; i<1000; i++) {
7686 if (asprintf(&key, "key%ld", random()) == -1) {
7689 if (asprintf(&value, "value%ld", random()) == -1) {
7694 if (!rbt_testval(db, key, value)) {
7701 if (asprintf(&value, "value%ld", random()) == -1) {
7706 if (!rbt_testval(db, key, value)) {
7725 local test for character set functions
7727 This is a very simple test for the functionality in convert_string_error()
7729 static bool run_local_convert_string(int dummy)
7731 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7732 const char *test_strings[2] = { "March", "M\303\244rz" };
7736 for (i=0; i<2; i++) {
7737 const char *str = test_strings[i];
7738 int len = strlen(str);
7739 size_t converted_size;
7742 memset(dst, 'X', sizeof(dst));
7744 /* first try with real source length */
7745 ret = convert_string_error(CH_UNIX, CH_UTF8,
7750 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7754 if (converted_size != len) {
7755 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7756 str, len, (int)converted_size);
7760 if (strncmp(str, dst, converted_size) != 0) {
7761 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7765 if (strlen(str) != converted_size) {
7766 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7767 (int)strlen(str), (int)converted_size);
7771 if (dst[converted_size] != 'X') {
7772 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7776 /* now with srclen==-1, this causes the nul to be
7778 ret = convert_string_error(CH_UNIX, CH_UTF8,
7783 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7787 if (converted_size != len+1) {
7788 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7789 str, len, (int)converted_size);
7793 if (strncmp(str, dst, converted_size) != 0) {
7794 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7798 if (len+1 != converted_size) {
7799 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7800 len+1, (int)converted_size);
7804 if (dst[converted_size] != 'X') {
7805 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7812 TALLOC_FREE(tmp_ctx);
7815 TALLOC_FREE(tmp_ctx);
7820 struct talloc_dict_test {
7824 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7826 int *count = (int *)priv;
7831 static bool run_local_talloc_dict(int dummy)
7833 struct talloc_dict *dict;
7834 struct talloc_dict_test *t;
7837 dict = talloc_dict_init(talloc_tos());
7842 t = talloc(talloc_tos(), struct talloc_dict_test);
7849 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7854 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7867 static bool run_local_string_to_sid(int dummy) {
7870 if (string_to_sid(&sid, "S--1-5-32-545")) {
7871 printf("allowing S--1-5-32-545\n");
7874 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7875 printf("allowing S-1-5-32-+545\n");
7878 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")) {
7879 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7882 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7883 printf("allowing S-1-5-32-545-abc\n");
7886 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7887 printf("could not parse S-1-5-32-545\n");
7890 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7891 printf("mis-parsed S-1-5-32-545 as %s\n",
7892 sid_string_tos(&sid));
7898 static bool run_local_binary_to_sid(int dummy) {
7899 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7900 static const char good_binary_sid[] = {
7901 0x1, /* revision number */
7903 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7904 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7905 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7906 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7907 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7908 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7909 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7910 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7914 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7915 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7916 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7917 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7918 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7921 static const char long_binary_sid[] = {
7922 0x1, /* revision number */
7924 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7925 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7938 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7939 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7940 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7941 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7942 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7945 static const char long_binary_sid2[] = {
7946 0x1, /* revision number */
7948 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7949 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7950 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7951 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7952 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7953 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7954 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7955 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7956 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7957 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7958 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7959 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7960 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7961 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7962 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7963 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7964 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7965 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7966 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7967 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7968 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7969 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7970 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7971 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7972 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7973 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7974 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7975 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7976 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7977 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7978 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7979 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7980 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7983 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7986 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7989 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7995 /* Split a path name into filename and stream name components. Canonicalise
7996 * such that an implicit $DATA token is always explicit.
7998 * The "specification" of this function can be found in the
7999 * run_local_stream_name() function in torture.c, I've tried those
8000 * combinations against a W2k3 server.
8003 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8004 char **pbase, char **pstream)
8007 char *stream = NULL;
8008 char *sname; /* stream name */
8009 const char *stype; /* stream type */
8011 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8013 sname = strchr_m(fname, ':');
8015 if (lp_posix_pathnames() || (sname == NULL)) {
8016 if (pbase != NULL) {
8017 base = talloc_strdup(mem_ctx, fname);
8018 NT_STATUS_HAVE_NO_MEMORY(base);
8023 if (pbase != NULL) {
8024 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8025 NT_STATUS_HAVE_NO_MEMORY(base);
8030 stype = strchr_m(sname, ':');
8032 if (stype == NULL) {
8033 sname = talloc_strdup(mem_ctx, sname);
8037 if (strcasecmp_m(stype, ":$DATA") != 0) {
8039 * If there is an explicit stream type, so far we only
8040 * allow $DATA. Is there anything else allowed? -- vl
8042 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8044 return NT_STATUS_OBJECT_NAME_INVALID;
8046 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8050 if (sname == NULL) {
8052 return NT_STATUS_NO_MEMORY;
8055 if (sname[0] == '\0') {
8057 * no stream name, so no stream
8062 if (pstream != NULL) {
8063 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8064 if (stream == NULL) {
8067 return NT_STATUS_NO_MEMORY;
8070 * upper-case the type field
8072 strupper_m(strchr_m(stream, ':')+1);
8076 if (pbase != NULL) {
8079 if (pstream != NULL) {
8082 return NT_STATUS_OK;
8085 static bool test_stream_name(const char *fname, const char *expected_base,
8086 const char *expected_stream,
8087 NTSTATUS expected_status)
8091 char *stream = NULL;
8093 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8094 if (!NT_STATUS_EQUAL(status, expected_status)) {
8098 if (!NT_STATUS_IS_OK(status)) {
8102 if (base == NULL) goto error;
8104 if (strcmp(expected_base, base) != 0) goto error;
8106 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8107 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8109 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8113 TALLOC_FREE(stream);
8117 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8118 fname, expected_base ? expected_base : "<NULL>",
8119 expected_stream ? expected_stream : "<NULL>",
8120 nt_errstr(expected_status));
8121 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8122 base ? base : "<NULL>", stream ? stream : "<NULL>",
8125 TALLOC_FREE(stream);
8129 static bool run_local_stream_name(int dummy)
8133 ret &= test_stream_name(
8134 "bla", "bla", NULL, NT_STATUS_OK);
8135 ret &= test_stream_name(
8136 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8137 ret &= test_stream_name(
8138 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8139 ret &= test_stream_name(
8140 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8141 ret &= test_stream_name(
8142 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8143 ret &= test_stream_name(
8144 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8145 ret &= test_stream_name(
8146 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8147 ret &= test_stream_name(
8148 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8153 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8155 if (a.length != b.length) {
8156 printf("a.length=%d != b.length=%d\n",
8157 (int)a.length, (int)b.length);
8160 if (memcmp(a.data, b.data, a.length) != 0) {
8161 printf("a.data and b.data differ\n");
8167 static bool run_local_memcache(int dummy)
8169 struct memcache *cache;
8171 DATA_BLOB d1, d2, d3;
8172 DATA_BLOB v1, v2, v3;
8174 TALLOC_CTX *mem_ctx;
8176 size_t size1, size2;
8179 cache = memcache_init(NULL, 100);
8181 if (cache == NULL) {
8182 printf("memcache_init failed\n");
8186 d1 = data_blob_const("d1", 2);
8187 d2 = data_blob_const("d2", 2);
8188 d3 = data_blob_const("d3", 2);
8190 k1 = data_blob_const("d1", 2);
8191 k2 = data_blob_const("d2", 2);
8193 memcache_add(cache, STAT_CACHE, k1, d1);
8194 memcache_add(cache, GETWD_CACHE, k2, d2);
8196 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8197 printf("could not find k1\n");
8200 if (!data_blob_equal(d1, v1)) {
8204 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8205 printf("could not find k2\n");
8208 if (!data_blob_equal(d2, v2)) {
8212 memcache_add(cache, STAT_CACHE, k1, d3);
8214 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8215 printf("could not find replaced k1\n");
8218 if (!data_blob_equal(d3, v3)) {
8222 memcache_add(cache, GETWD_CACHE, k1, d1);
8224 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8225 printf("Did find k2, should have been purged\n");
8231 cache = memcache_init(NULL, 0);
8233 mem_ctx = talloc_init("foo");
8235 str1 = talloc_strdup(mem_ctx, "string1");
8236 str2 = talloc_strdup(mem_ctx, "string2");
8238 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8239 data_blob_string_const("torture"), &str1);
8240 size1 = talloc_total_size(cache);
8242 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8243 data_blob_string_const("torture"), &str2);
8244 size2 = talloc_total_size(cache);
8246 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8248 if (size2 > size1) {
8249 printf("memcache leaks memory!\n");
8259 static void wbclient_done(struct tevent_req *req)
8262 struct winbindd_response *wb_resp;
8263 int *i = (int *)tevent_req_callback_data_void(req);
8265 wbc_err = wb_trans_recv(req, req, &wb_resp);
8268 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8271 static bool run_local_wbclient(int dummy)
8273 struct event_context *ev;
8274 struct wb_context **wb_ctx;
8275 struct winbindd_request wb_req;
8276 bool result = false;
8279 BlockSignals(True, SIGPIPE);
8281 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8286 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8287 if (wb_ctx == NULL) {
8291 ZERO_STRUCT(wb_req);
8292 wb_req.cmd = WINBINDD_PING;
8294 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8296 for (i=0; i<nprocs; i++) {
8297 wb_ctx[i] = wb_context_init(ev, NULL);
8298 if (wb_ctx[i] == NULL) {
8301 for (j=0; j<torture_numops; j++) {
8302 struct tevent_req *req;
8303 req = wb_trans_send(ev, ev, wb_ctx[i],
8304 (j % 2) == 0, &wb_req);
8308 tevent_req_set_callback(req, wbclient_done, &i);
8314 while (i < nprocs * torture_numops) {
8315 event_loop_once(ev);
8324 static void getaddrinfo_finished(struct tevent_req *req)
8326 char *name = (char *)tevent_req_callback_data_void(req);
8327 struct addrinfo *ainfo;
8330 res = getaddrinfo_recv(req, &ainfo);
8332 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8335 d_printf("gai(%s) succeeded\n", name);
8336 freeaddrinfo(ainfo);
8339 static bool run_getaddrinfo_send(int dummy)
8341 TALLOC_CTX *frame = talloc_stackframe();
8342 struct fncall_context *ctx;
8343 struct tevent_context *ev;
8344 bool result = false;
8345 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8346 "www.slashdot.org", "heise.de" };
8347 struct tevent_req *reqs[4];
8350 ev = event_context_init(frame);
8355 ctx = fncall_context_init(frame, 4);
8357 for (i=0; i<ARRAY_SIZE(names); i++) {
8358 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8360 if (reqs[i] == NULL) {
8363 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8364 discard_const_p(void, names[i]));
8367 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8368 tevent_loop_once(ev);
8377 static bool dbtrans_inc(struct db_context *db)
8379 struct db_record *rec;
8384 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8386 printf(__location__ "fetch_lock failed\n");
8390 if (rec->value.dsize != sizeof(uint32_t)) {
8391 printf(__location__ "value.dsize = %d\n",
8392 (int)rec->value.dsize);
8396 val = (uint32_t *)rec->value.dptr;
8399 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8402 if (!NT_STATUS_IS_OK(status)) {
8403 printf(__location__ "store failed: %s\n",
8414 static bool run_local_dbtrans(int dummy)
8416 struct db_context *db;
8417 struct db_record *rec;
8422 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8423 O_RDWR|O_CREAT, 0600);
8425 printf("Could not open transtest.db\n");
8429 res = db->transaction_start(db);
8431 printf(__location__ "transaction_start failed\n");
8435 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8437 printf(__location__ "fetch_lock failed\n");
8441 if (rec->value.dptr == NULL) {
8443 status = rec->store(
8444 rec, make_tdb_data((uint8_t *)&initial,
8447 if (!NT_STATUS_IS_OK(status)) {
8448 printf(__location__ "store returned %s\n",
8456 res = db->transaction_commit(db);
8458 printf(__location__ "transaction_commit failed\n");
8466 res = db->transaction_start(db);
8468 printf(__location__ "transaction_start failed\n");
8472 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8473 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8477 for (i=0; i<10; i++) {
8478 if (!dbtrans_inc(db)) {
8483 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8484 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8488 if (val2 != val + 10) {
8489 printf(__location__ "val=%d, val2=%d\n",
8490 (int)val, (int)val2);
8494 printf("val2=%d\r", val2);
8496 res = db->transaction_commit(db);
8498 printf(__location__ "transaction_commit failed\n");
8508 * Just a dummy test to be run under a debugger. There's no real way
8509 * to inspect the tevent_select specific function from outside of
8513 static bool run_local_tevent_select(int dummy)
8515 struct tevent_context *ev;
8516 struct tevent_fd *fd1, *fd2;
8517 bool result = false;
8519 ev = tevent_context_init_byname(NULL, "select");
8521 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8525 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8527 d_fprintf(stderr, "tevent_add_fd failed\n");
8530 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8532 d_fprintf(stderr, "tevent_add_fd failed\n");
8537 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8539 d_fprintf(stderr, "tevent_add_fd failed\n");
8549 static double create_procs(bool (*fn)(int), bool *result)
8552 volatile pid_t *child_status;
8553 volatile bool *child_status_out;
8556 struct timeval start;
8560 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8561 if (!child_status) {
8562 printf("Failed to setup shared memory\n");
8566 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8567 if (!child_status_out) {
8568 printf("Failed to setup result status shared memory\n");
8572 for (i = 0; i < nprocs; i++) {
8573 child_status[i] = 0;
8574 child_status_out[i] = True;
8577 start = timeval_current();
8579 for (i=0;i<nprocs;i++) {
8582 pid_t mypid = getpid();
8583 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8585 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8588 if (torture_open_connection(¤t_cli, i)) break;
8590 printf("pid %d failed to start\n", (int)getpid());
8596 child_status[i] = getpid();
8598 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8600 child_status_out[i] = fn(i);
8607 for (i=0;i<nprocs;i++) {
8608 if (child_status[i]) synccount++;
8610 if (synccount == nprocs) break;
8612 } while (timeval_elapsed(&start) < 30);
8614 if (synccount != nprocs) {
8615 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8617 return timeval_elapsed(&start);
8620 /* start the client load */
8621 start = timeval_current();
8623 for (i=0;i<nprocs;i++) {
8624 child_status[i] = 0;
8627 printf("%d clients started\n", nprocs);
8629 for (i=0;i<nprocs;i++) {
8630 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8635 for (i=0;i<nprocs;i++) {
8636 if (!child_status_out[i]) {
8640 return timeval_elapsed(&start);
8643 #define FLAG_MULTIPROC 1
8650 {"FDPASS", run_fdpasstest, 0},
8651 {"LOCK1", run_locktest1, 0},
8652 {"LOCK2", run_locktest2, 0},
8653 {"LOCK3", run_locktest3, 0},
8654 {"LOCK4", run_locktest4, 0},
8655 {"LOCK5", run_locktest5, 0},
8656 {"LOCK6", run_locktest6, 0},
8657 {"LOCK7", run_locktest7, 0},
8658 {"LOCK8", run_locktest8, 0},
8659 {"LOCK9", run_locktest9, 0},
8660 {"UNLINK", run_unlinktest, 0},
8661 {"BROWSE", run_browsetest, 0},
8662 {"ATTR", run_attrtest, 0},
8663 {"TRANS2", run_trans2test, 0},
8664 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8665 {"TORTURE",run_torture, FLAG_MULTIPROC},
8666 {"RANDOMIPC", run_randomipc, 0},
8667 {"NEGNOWAIT", run_negprot_nowait, 0},
8668 {"NBENCH", run_nbench, 0},
8669 {"NBENCH2", run_nbench2, 0},
8670 {"OPLOCK1", run_oplock1, 0},
8671 {"OPLOCK2", run_oplock2, 0},
8672 {"OPLOCK4", run_oplock4, 0},
8673 {"DIR", run_dirtest, 0},
8674 {"DIR1", run_dirtest1, 0},
8675 {"DIR-CREATETIME", run_dir_createtime, 0},
8676 {"DENY1", torture_denytest1, 0},
8677 {"DENY2", torture_denytest2, 0},
8678 {"TCON", run_tcon_test, 0},
8679 {"TCONDEV", run_tcon_devtype_test, 0},
8680 {"RW1", run_readwritetest, 0},
8681 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8682 {"RW3", run_readwritelarge, 0},
8683 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8684 {"OPEN", run_opentest, 0},
8685 {"POSIX", run_simple_posix_open_test, 0},
8686 {"POSIX-APPEND", run_posix_append, 0},
8687 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8688 {"ASYNC-ECHO", run_async_echo, 0},
8689 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8690 { "SHORTNAME-TEST", run_shortname_test, 0},
8691 { "ADDRCHANGE", run_addrchange, 0},
8693 {"OPENATTR", run_openattrtest, 0},
8695 {"XCOPY", run_xcopy, 0},
8696 {"RENAME", run_rename, 0},
8697 {"DELETE", run_deletetest, 0},
8698 {"DELETE-LN", run_deletetest_ln, 0},
8699 {"PROPERTIES", run_properties, 0},
8700 {"MANGLE", torture_mangle, 0},
8701 {"MANGLE1", run_mangle1, 0},
8702 {"W2K", run_w2ktest, 0},
8703 {"TRANS2SCAN", torture_trans2_scan, 0},
8704 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8705 {"UTABLE", torture_utable, 0},
8706 {"CASETABLE", torture_casetable, 0},
8707 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8708 {"PIPE_NUMBER", run_pipe_number, 0},
8709 {"TCON2", run_tcon2_test, 0},
8710 {"IOCTL", torture_ioctl_test, 0},
8711 {"CHKPATH", torture_chkpath_test, 0},
8712 {"FDSESS", run_fdsesstest, 0},
8713 { "EATEST", run_eatest, 0},
8714 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8715 { "CHAIN1", run_chain1, 0},
8716 { "CHAIN2", run_chain2, 0},
8717 { "WINDOWS-WRITE", run_windows_write, 0},
8718 { "NTTRANS-CREATE", run_nttrans_create, 0},
8719 { "CLI_ECHO", run_cli_echo, 0},
8720 { "GETADDRINFO", run_getaddrinfo_send, 0},
8721 { "TLDAP", run_tldap },
8722 { "STREAMERROR", run_streamerror },
8723 { "NOTIFY-BENCH", run_notify_bench },
8724 { "BAD-NBT-SESSION", run_bad_nbt_session },
8725 { "SMB-ANY-CONNECT", run_smb_any_connect },
8726 { "NOTIFY-ONLINE", run_notify_online },
8727 { "SMB2-BASIC", run_smb2_basic },
8728 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8729 { "LOCAL-GENCACHE", run_local_gencache, 0},
8730 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8731 { "LOCAL-BASE64", run_local_base64, 0},
8732 { "LOCAL-RBTREE", run_local_rbtree, 0},
8733 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8734 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8735 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8736 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8737 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8738 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8739 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8740 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8745 /****************************************************************************
8746 run a specified test or "ALL"
8747 ****************************************************************************/
8748 static bool run_test(const char *name)
8755 if (strequal(name,"ALL")) {
8756 for (i=0;torture_ops[i].name;i++) {
8757 run_test(torture_ops[i].name);
8762 for (i=0;torture_ops[i].name;i++) {
8763 fstr_sprintf(randomfname, "\\XX%x",
8764 (unsigned)random());
8766 if (strequal(name, torture_ops[i].name)) {
8768 printf("Running %s\n", name);
8769 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8770 t = create_procs(torture_ops[i].fn, &result);
8773 printf("TEST %s FAILED!\n", name);
8776 struct timeval start;
8777 start = timeval_current();
8778 if (!torture_ops[i].fn(0)) {
8780 printf("TEST %s FAILED!\n", name);
8782 t = timeval_elapsed(&start);
8784 printf("%s took %g secs\n\n", name, t);
8789 printf("Did not find a test named %s\n", name);
8797 static void usage(void)
8801 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8802 printf("Please use samba4 torture.\n\n");
8804 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8806 printf("\t-d debuglevel\n");
8807 printf("\t-U user%%pass\n");
8808 printf("\t-k use kerberos\n");
8809 printf("\t-N numprocs\n");
8810 printf("\t-n my_netbios_name\n");
8811 printf("\t-W workgroup\n");
8812 printf("\t-o num_operations\n");
8813 printf("\t-O socket_options\n");
8814 printf("\t-m maximum protocol\n");
8815 printf("\t-L use oplocks\n");
8816 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8817 printf("\t-A showall\n");
8818 printf("\t-p port\n");
8819 printf("\t-s seed\n");
8820 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8821 printf("\t-f filename filename to test\n");
8824 printf("tests are:");
8825 for (i=0;torture_ops[i].name;i++) {
8826 printf(" %s", torture_ops[i].name);
8830 printf("default test is ALL\n");
8835 /****************************************************************************
8837 ****************************************************************************/
8838 int main(int argc,char *argv[])
8844 bool correct = True;
8845 TALLOC_CTX *frame = talloc_stackframe();
8846 int seed = time(NULL);
8848 #ifdef HAVE_SETBUFFER
8849 setbuffer(stdout, NULL, 0);
8852 setup_logging("smbtorture", DEBUG_STDOUT);
8856 if (is_default_dyn_CONFIGFILE()) {
8857 if(getenv("SMB_CONF_PATH")) {
8858 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8861 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8868 for(p = argv[1]; *p; p++)
8872 if (strncmp(argv[1], "//", 2)) {
8876 fstrcpy(host, &argv[1][2]);
8877 p = strchr_m(&host[2],'/');
8882 fstrcpy(share, p+1);
8884 fstrcpy(myname, get_myname(talloc_tos()));
8886 fprintf(stderr, "Failed to get my hostname.\n");
8890 if (*username == 0 && getenv("LOGNAME")) {
8891 fstrcpy(username,getenv("LOGNAME"));
8897 fstrcpy(workgroup, lp_workgroup());
8899 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8903 port_to_use = atoi(optarg);
8906 seed = atoi(optarg);
8909 fstrcpy(workgroup,optarg);
8912 max_protocol = interpret_protocol(optarg, max_protocol);
8915 nprocs = atoi(optarg);
8918 torture_numops = atoi(optarg);
8921 lp_set_cmdline("log level", optarg);
8930 local_path = optarg;
8933 torture_showall = True;
8936 fstrcpy(myname, optarg);
8939 client_txt = optarg;
8946 use_kerberos = True;
8948 d_printf("No kerberos support compiled in\n");
8954 fstrcpy(username,optarg);
8955 p = strchr_m(username,'%');
8958 fstrcpy(password, p+1);
8963 fstrcpy(multishare_conn_fname, optarg);
8964 use_multishare_conn = True;
8967 torture_blocksize = atoi(optarg);
8970 test_filename = SMB_STRDUP(optarg);
8973 printf("Unknown option %c (%d)\n", (char)opt, opt);
8978 d_printf("using seed %d\n", seed);
8982 if(use_kerberos && !gotuser) gotpass = True;
8985 p = getpass("Password:");
8987 fstrcpy(password, p);
8992 printf("host=%s share=%s user=%s myname=%s\n",
8993 host, share, username, myname);
8995 if (argc == optind) {
8996 correct = run_test("ALL");
8998 for (i=optind;i<argc;i++) {
8999 if (!run_test(argv[i])) {