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 static 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_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
419 uint16 old_vuid = cli->vuid;
420 fstring old_user_name;
421 size_t passlen = strlen(password);
425 fstrcpy(old_user_name, cli->user_name);
427 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
431 *new_vuid = cli->vuid;
432 cli->vuid = old_vuid;
433 status = cli_set_username(cli, old_user_name);
434 if (!NT_STATUS_IS_OK(status)) {
441 bool torture_close_connection(struct cli_state *c)
446 status = cli_tdis(c);
447 if (!NT_STATUS_IS_OK(status)) {
448 printf("tdis failed (%s)\n", nt_errstr(status));
458 /* check if the server produced the expected dos or nt error code */
459 static bool check_both_error(int line, NTSTATUS status,
460 uint8 eclass, uint32 ecode, NTSTATUS nterr)
462 if (NT_STATUS_IS_DOS(status)) {
466 /* Check DOS error */
467 cclass = NT_STATUS_DOS_CLASS(status);
468 num = NT_STATUS_DOS_CODE(status);
470 if (eclass != cclass || ecode != num) {
471 printf("unexpected error code class=%d code=%d\n",
472 (int)cclass, (int)num);
473 printf(" expected %d/%d %s (line=%d)\n",
474 (int)eclass, (int)ecode, nt_errstr(nterr), line);
479 if (!NT_STATUS_EQUAL(nterr, status)) {
480 printf("unexpected error code %s\n",
482 printf(" expected %s (line=%d)\n",
483 nt_errstr(nterr), line);
492 /* check if the server produced the expected error code */
493 static bool check_error(int line, struct cli_state *c,
494 uint8 eclass, uint32 ecode, NTSTATUS nterr)
496 if (cli_is_dos_error(c)) {
500 /* Check DOS error */
502 cli_dos_error(c, &cclass, &num);
504 if (eclass != cclass || ecode != num) {
505 printf("unexpected error code class=%d code=%d\n",
506 (int)cclass, (int)num);
507 printf(" expected %d/%d %s (line=%d)\n",
508 (int)eclass, (int)ecode, nt_errstr(nterr), line);
517 status = cli_nt_error(c);
519 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
520 printf("unexpected error code %s\n", nt_errstr(status));
521 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
530 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
532 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
533 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
539 static bool rw_torture(struct cli_state *c)
541 const char *lockfname = "\\torture.lck";
545 pid_t pid2, pid = getpid();
551 memset(buf, '\0', sizeof(buf));
553 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
555 if (!NT_STATUS_IS_OK(status)) {
556 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
558 if (!NT_STATUS_IS_OK(status)) {
559 printf("open of %s failed (%s)\n",
560 lockfname, nt_errstr(status));
564 for (i=0;i<torture_numops;i++) {
565 unsigned n = (unsigned)sys_random()%10;
568 printf("%d\r", i); fflush(stdout);
570 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
572 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
576 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("open failed (%s)\n", nt_errstr(status));
584 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("write failed (%s)\n", nt_errstr(status));
592 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
593 sizeof(pid)+(j*sizeof(buf)),
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("write failed (%s)\n",
604 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
605 printf("read failed (%s)\n", cli_errstr(c));
610 printf("data corruption!\n");
614 status = cli_close(c, fnum);
615 if (!NT_STATUS_IS_OK(status)) {
616 printf("close failed (%s)\n", nt_errstr(status));
620 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
621 if (!NT_STATUS_IS_OK(status)) {
622 printf("unlink failed (%s)\n", nt_errstr(status));
626 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("unlock failed (%s)\n", nt_errstr(status));
634 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
641 static bool run_torture(int dummy)
643 struct cli_state *cli;
648 cli_sockopt(cli, sockops);
650 ret = rw_torture(cli);
652 if (!torture_close_connection(cli)) {
659 static bool rw_torture3(struct cli_state *c, char *lockfname)
661 uint16_t fnum = (uint16_t)-1;
666 unsigned countprev = 0;
669 NTSTATUS status = NT_STATUS_OK;
672 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
674 SIVAL(buf, i, sys_random());
681 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
682 if (!NT_STATUS_IS_OK(status)) {
683 printf("unlink failed (%s) (normal, this file should "
684 "not exist)\n", nt_errstr(status));
687 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
689 if (!NT_STATUS_IS_OK(status)) {
690 printf("first open read/write of %s failed (%s)\n",
691 lockfname, nt_errstr(status));
697 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
699 status = cli_open(c, lockfname, O_RDONLY,
701 if (!NT_STATUS_IS_OK(status)) {
706 if (!NT_STATUS_IS_OK(status)) {
707 printf("second open read-only of %s failed (%s)\n",
708 lockfname, nt_errstr(status));
714 for (count = 0; count < sizeof(buf); count += sent)
716 if (count >= countprev) {
717 printf("%d %8d\r", i, count);
720 countprev += (sizeof(buf) / 20);
725 sent = ((unsigned)sys_random()%(20))+ 1;
726 if (sent > sizeof(buf) - count)
728 sent = sizeof(buf) - count;
731 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
732 count, (size_t)sent, NULL);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("write failed (%s)\n",
741 sent = cli_read(c, fnum, buf_rd+count, count,
745 printf("read failed offset:%d size:%ld (%s)\n",
746 count, (unsigned long)sizeof(buf)-count,
753 if (memcmp(buf_rd+count, buf+count, sent) != 0)
755 printf("read/write compare failed\n");
756 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
765 status = cli_close(c, fnum);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("close failed (%s)\n", nt_errstr(status));
774 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
776 const char *lockfname = "\\torture2.lck";
786 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
787 if (!NT_STATUS_IS_OK(status)) {
788 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
791 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
793 if (!NT_STATUS_IS_OK(status)) {
794 printf("first open read/write of %s failed (%s)\n",
795 lockfname, nt_errstr(status));
799 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
800 if (!NT_STATUS_IS_OK(status)) {
801 printf("second open read-only of %s failed (%s)\n",
802 lockfname, nt_errstr(status));
803 cli_close(c1, fnum1);
807 for (i = 0; i < torture_numops; i++)
809 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
811 printf("%d\r", i); fflush(stdout);
814 generate_random_buffer((unsigned char *)buf, buf_size);
816 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
818 if (!NT_STATUS_IS_OK(status)) {
819 printf("write failed (%s)\n", nt_errstr(status));
824 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
825 printf("read failed (%s)\n", cli_errstr(c2));
826 printf("read %d, expected %ld\n", (int)bytes_read,
827 (unsigned long)buf_size);
832 if (memcmp(buf_rd, buf, buf_size) != 0)
834 printf("read/write compare failed\n");
840 status = cli_close(c2, fnum2);
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("close failed (%s)\n", nt_errstr(status));
846 status = cli_close(c1, fnum1);
847 if (!NT_STATUS_IS_OK(status)) {
848 printf("close failed (%s)\n", nt_errstr(status));
852 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
853 if (!NT_STATUS_IS_OK(status)) {
854 printf("unlink failed (%s)\n", nt_errstr(status));
861 static bool run_readwritetest(int dummy)
863 struct cli_state *cli1, *cli2;
864 bool test1, test2 = False;
866 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
869 cli_sockopt(cli1, sockops);
870 cli_sockopt(cli2, sockops);
872 printf("starting readwritetest\n");
874 test1 = rw_torture2(cli1, cli2);
875 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
878 test2 = rw_torture2(cli1, cli1);
879 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
882 if (!torture_close_connection(cli1)) {
886 if (!torture_close_connection(cli2)) {
890 return (test1 && test2);
893 static bool run_readwritemulti(int dummy)
895 struct cli_state *cli;
900 cli_sockopt(cli, sockops);
902 printf("run_readwritemulti: fname %s\n", randomfname);
903 test = rw_torture3(cli, randomfname);
905 if (!torture_close_connection(cli)) {
912 static bool run_readwritelarge_internal(int max_xmit_k)
914 static struct cli_state *cli1;
916 const char *lockfname = "\\large.dat";
922 if (!torture_open_connection(&cli1, 0)) {
925 cli_sockopt(cli1, sockops);
926 memset(buf,'\0',sizeof(buf));
928 cli1->max_xmit = max_xmit_k*1024;
930 if (signing_state == Required) {
931 /* Horrible cheat to force
932 multiple signed outstanding
933 packets against a Samba server.
935 cli1->is_samba = false;
938 printf("starting readwritelarge_internal\n");
940 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
942 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
944 if (!NT_STATUS_IS_OK(status)) {
945 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
949 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
951 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
953 if (!NT_STATUS_IS_OK(status)) {
954 printf("qfileinfo failed (%s)\n", nt_errstr(status));
958 if (fsize == sizeof(buf))
959 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
960 (unsigned long)fsize);
962 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
963 (unsigned long)fsize);
967 status = cli_close(cli1, fnum1);
968 if (!NT_STATUS_IS_OK(status)) {
969 printf("close failed (%s)\n", nt_errstr(status));
973 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
974 if (!NT_STATUS_IS_OK(status)) {
975 printf("unlink failed (%s)\n", nt_errstr(status));
979 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
981 if (!NT_STATUS_IS_OK(status)) {
982 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
986 cli1->max_xmit = 4*1024;
988 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
990 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
992 if (!NT_STATUS_IS_OK(status)) {
993 printf("qfileinfo failed (%s)\n", nt_errstr(status));
997 if (fsize == sizeof(buf))
998 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
999 (unsigned long)fsize);
1001 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1002 (unsigned long)fsize);
1007 /* ToDo - set allocation. JRA */
1008 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1009 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1012 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1014 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1018 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1021 status = cli_close(cli1, fnum1);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("close failed (%s)\n", nt_errstr(status));
1027 if (!torture_close_connection(cli1)) {
1033 static bool run_readwritelarge(int dummy)
1035 return run_readwritelarge_internal(128);
1038 static bool run_readwritelarge_signtest(int dummy)
1041 signing_state = Required;
1042 ret = run_readwritelarge_internal(2);
1043 signing_state = Undefined;
1050 #define ival(s) strtol(s, NULL, 0)
1052 /* run a test that simulates an approximate netbench client load */
1053 static bool run_netbench(int client)
1055 struct cli_state *cli;
1060 const char *params[20];
1061 bool correct = True;
1067 cli_sockopt(cli, sockops);
1071 slprintf(cname,sizeof(cname)-1, "client%d", client);
1073 f = fopen(client_txt, "r");
1080 while (fgets(line, sizeof(line)-1, f)) {
1084 line[strlen(line)-1] = 0;
1086 /* printf("[%d] %s\n", line_count, line); */
1088 all_string_sub(line,"client1", cname, sizeof(line));
1090 /* parse the command parameters */
1091 params[0] = strtok_r(line, " ", &saveptr);
1093 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1097 if (i < 2) continue;
1099 if (!strncmp(params[0],"SMB", 3)) {
1100 printf("ERROR: You are using a dbench 1 load file\n");
1104 if (!strcmp(params[0],"NTCreateX")) {
1105 nb_createx(params[1], ival(params[2]), ival(params[3]),
1107 } else if (!strcmp(params[0],"Close")) {
1108 nb_close(ival(params[1]));
1109 } else if (!strcmp(params[0],"Rename")) {
1110 nb_rename(params[1], params[2]);
1111 } else if (!strcmp(params[0],"Unlink")) {
1112 nb_unlink(params[1]);
1113 } else if (!strcmp(params[0],"Deltree")) {
1114 nb_deltree(params[1]);
1115 } else if (!strcmp(params[0],"Rmdir")) {
1116 nb_rmdir(params[1]);
1117 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1118 nb_qpathinfo(params[1]);
1119 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1120 nb_qfileinfo(ival(params[1]));
1121 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1122 nb_qfsinfo(ival(params[1]));
1123 } else if (!strcmp(params[0],"FIND_FIRST")) {
1124 nb_findfirst(params[1]);
1125 } else if (!strcmp(params[0],"WriteX")) {
1126 nb_writex(ival(params[1]),
1127 ival(params[2]), ival(params[3]), ival(params[4]));
1128 } else if (!strcmp(params[0],"ReadX")) {
1129 nb_readx(ival(params[1]),
1130 ival(params[2]), ival(params[3]), ival(params[4]));
1131 } else if (!strcmp(params[0],"Flush")) {
1132 nb_flush(ival(params[1]));
1134 printf("Unknown operation %s\n", params[0]);
1142 if (!torture_close_connection(cli)) {
1150 /* run a test that simulates an approximate netbench client load */
1151 static bool run_nbench(int dummy)
1154 bool correct = True;
1160 signal(SIGALRM, nb_alarm);
1162 t = create_procs(run_netbench, &correct);
1165 printf("\nThroughput %g MB/sec\n",
1166 1.0e-6 * nbio_total() / t);
1172 This test checks for two things:
1174 1) correct support for retaining locks over a close (ie. the server
1175 must not use posix semantics)
1176 2) support for lock timeouts
1178 static bool run_locktest1(int dummy)
1180 struct cli_state *cli1, *cli2;
1181 const char *fname = "\\lockt1.lck";
1182 uint16_t fnum1, fnum2, fnum3;
1184 unsigned lock_timeout;
1187 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1190 cli_sockopt(cli1, sockops);
1191 cli_sockopt(cli2, sockops);
1193 printf("starting locktest1\n");
1195 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1197 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1199 if (!NT_STATUS_IS_OK(status)) {
1200 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1204 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1210 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1216 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1217 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1222 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1223 printf("lock2 succeeded! This is a locking bug\n");
1226 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1227 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1231 lock_timeout = (1 + (random() % 20));
1232 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1234 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1235 printf("lock3 succeeded! This is a locking bug\n");
1238 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1239 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1243 if (ABS(t2 - t1) < lock_timeout-1) {
1244 printf("error: This server appears not to support timed lock requests\n");
1247 printf("server slept for %u seconds for a %u second timeout\n",
1248 (unsigned int)(t2-t1), lock_timeout);
1250 status = cli_close(cli1, fnum2);
1251 if (!NT_STATUS_IS_OK(status)) {
1252 printf("close1 failed (%s)\n", nt_errstr(status));
1256 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1257 printf("lock4 succeeded! This is a locking bug\n");
1260 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1261 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1264 status = cli_close(cli1, fnum1);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 printf("close2 failed (%s)\n", nt_errstr(status));
1270 status = cli_close(cli2, fnum3);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 printf("close3 failed (%s)\n", nt_errstr(status));
1276 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 printf("unlink failed (%s)\n", nt_errstr(status));
1283 if (!torture_close_connection(cli1)) {
1287 if (!torture_close_connection(cli2)) {
1291 printf("Passed locktest1\n");
1296 this checks to see if a secondary tconx can use open files from an
1299 static bool run_tcon_test(int dummy)
1301 static struct cli_state *cli;
1302 const char *fname = "\\tcontest.tmp";
1304 uint16 cnum1, cnum2, cnum3;
1305 uint16 vuid1, vuid2;
1310 memset(buf, '\0', sizeof(buf));
1312 if (!torture_open_connection(&cli, 0)) {
1315 cli_sockopt(cli, sockops);
1317 printf("starting tcontest\n");
1319 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1321 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1322 if (!NT_STATUS_IS_OK(status)) {
1323 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1330 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("initial write failed (%s)", nt_errstr(status));
1336 status = cli_tcon_andx(cli, share, "?????",
1337 password, strlen(password)+1);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("%s refused 2nd tree connect (%s)\n", host,
1346 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1347 vuid2 = cli->vuid + 1;
1349 /* try a write with the wrong tid */
1352 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1353 if (NT_STATUS_IS_OK(status)) {
1354 printf("* server allows write with wrong TID\n");
1357 printf("server fails write with wrong TID : %s\n",
1362 /* try a write with an invalid tid */
1365 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1366 if (NT_STATUS_IS_OK(status)) {
1367 printf("* server allows write with invalid TID\n");
1370 printf("server fails write with invalid TID : %s\n",
1374 /* try a write with an invalid vuid */
1378 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1379 if (NT_STATUS_IS_OK(status)) {
1380 printf("* server allows write with invalid VUID\n");
1383 printf("server fails write with invalid VUID : %s\n",
1390 status = cli_close(cli, fnum1);
1391 if (!NT_STATUS_IS_OK(status)) {
1392 printf("close failed (%s)\n", nt_errstr(status));
1398 status = cli_tdis(cli);
1399 if (!NT_STATUS_IS_OK(status)) {
1400 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1406 if (!torture_close_connection(cli)) {
1415 checks for old style tcon support
1417 static bool run_tcon2_test(int dummy)
1419 static struct cli_state *cli;
1420 uint16 cnum, max_xmit;
1424 if (!torture_open_connection(&cli, 0)) {
1427 cli_sockopt(cli, sockops);
1429 printf("starting tcon2 test\n");
1431 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1435 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 printf("tcon2 failed : %s\n", nt_errstr(status));
1442 printf("tcon OK : max_xmit=%d cnum=%d\n",
1443 (int)max_xmit, (int)cnum);
1446 if (!torture_close_connection(cli)) {
1450 printf("Passed tcon2 test\n");
1454 static bool tcon_devtest(struct cli_state *cli,
1455 const char *myshare, const char *devtype,
1456 const char *return_devtype,
1457 NTSTATUS expected_error)
1462 status = cli_tcon_andx(cli, myshare, devtype,
1463 password, strlen(password)+1);
1465 if (NT_STATUS_IS_OK(expected_error)) {
1466 if (NT_STATUS_IS_OK(status)) {
1467 if (strcmp(cli->dev, return_devtype) == 0) {
1470 printf("tconX to share %s with type %s "
1471 "succeeded but returned the wrong "
1472 "device type (got [%s] but should have got [%s])\n",
1473 myshare, devtype, cli->dev, return_devtype);
1477 printf("tconX to share %s with type %s "
1478 "should have succeeded but failed\n",
1484 if (NT_STATUS_IS_OK(status)) {
1485 printf("tconx to share %s with type %s "
1486 "should have failed but succeeded\n",
1490 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1494 printf("Returned unexpected error\n");
1503 checks for correct tconX support
1505 static bool run_tcon_devtype_test(int dummy)
1507 static struct cli_state *cli1 = NULL;
1512 status = cli_full_connection(&cli1, myname,
1513 host, NULL, port_to_use,
1515 username, workgroup,
1516 password, flags, signing_state);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 printf("could not open connection\n");
1523 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1526 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1529 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1532 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1535 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1538 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1541 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1544 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1547 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1550 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1556 printf("Passed tcondevtest\n");
1563 This test checks that
1565 1) the server supports multiple locking contexts on the one SMB
1566 connection, distinguished by PID.
1568 2) the server correctly fails overlapping locks made by the same PID (this
1569 goes against POSIX behaviour, which is why it is tricky to implement)
1571 3) the server denies unlock requests by an incorrect client PID
1573 static bool run_locktest2(int dummy)
1575 static struct cli_state *cli;
1576 const char *fname = "\\lockt2.lck";
1577 uint16_t fnum1, fnum2, fnum3;
1578 bool correct = True;
1581 if (!torture_open_connection(&cli, 0)) {
1585 cli_sockopt(cli, sockops);
1587 printf("starting locktest2\n");
1589 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1593 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1599 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1607 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1608 if (!NT_STATUS_IS_OK(status)) {
1609 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1615 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1616 printf("lock1 failed (%s)\n", cli_errstr(cli));
1620 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1621 printf("WRITE lock1 succeeded! This is a locking bug\n");
1624 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1625 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1628 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1629 printf("WRITE lock2 succeeded! This is a locking bug\n");
1632 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1633 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1636 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1637 printf("READ lock2 succeeded! This is a locking bug\n");
1640 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1641 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1644 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1645 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1648 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1649 printf("unlock at 100 succeeded! This is a locking bug\n");
1653 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1654 printf("unlock1 succeeded! This is a locking bug\n");
1657 if (!check_error(__LINE__, cli,
1659 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1662 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1663 printf("unlock2 succeeded! This is a locking bug\n");
1666 if (!check_error(__LINE__, cli,
1668 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1671 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1672 printf("lock3 succeeded! This is a locking bug\n");
1675 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1680 status = cli_close(cli, fnum1);
1681 if (!NT_STATUS_IS_OK(status)) {
1682 printf("close1 failed (%s)\n", nt_errstr(status));
1686 status = cli_close(cli, fnum2);
1687 if (!NT_STATUS_IS_OK(status)) {
1688 printf("close2 failed (%s)\n", nt_errstr(status));
1692 status = cli_close(cli, fnum3);
1693 if (!NT_STATUS_IS_OK(status)) {
1694 printf("close3 failed (%s)\n", nt_errstr(status));
1698 if (!torture_close_connection(cli)) {
1702 printf("locktest2 finished\n");
1709 This test checks that
1711 1) the server supports the full offset range in lock requests
1713 static bool run_locktest3(int dummy)
1715 static struct cli_state *cli1, *cli2;
1716 const char *fname = "\\lockt3.lck";
1717 uint16_t fnum1, fnum2;
1720 bool correct = True;
1723 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1725 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1728 cli_sockopt(cli1, sockops);
1729 cli_sockopt(cli2, sockops);
1731 printf("starting locktest3\n");
1733 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1735 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1737 if (!NT_STATUS_IS_OK(status)) {
1738 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1742 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1743 if (!NT_STATUS_IS_OK(status)) {
1744 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1748 for (offset=i=0;i<torture_numops;i++) {
1750 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1751 printf("lock1 %d failed (%s)\n",
1757 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1758 printf("lock2 %d failed (%s)\n",
1765 for (offset=i=0;i<torture_numops;i++) {
1768 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1769 printf("error: lock1 %d succeeded!\n", i);
1773 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1774 printf("error: lock2 %d succeeded!\n", i);
1778 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1779 printf("error: lock3 %d succeeded!\n", i);
1783 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1784 printf("error: lock4 %d succeeded!\n", i);
1789 for (offset=i=0;i<torture_numops;i++) {
1792 status = cli_unlock(cli1, fnum1, offset-1, 1);
1793 if (!NT_STATUS_IS_OK(status)) {
1794 printf("unlock1 %d failed (%s)\n",
1800 status = cli_unlock(cli2, fnum2, offset-2, 1);
1801 if (!NT_STATUS_IS_OK(status)) {
1802 printf("unlock2 %d failed (%s)\n",
1809 status = cli_close(cli1, fnum1);
1810 if (!NT_STATUS_IS_OK(status)) {
1811 printf("close1 failed (%s)\n", nt_errstr(status));
1815 status = cli_close(cli2, fnum2);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 printf("close2 failed (%s)\n", nt_errstr(status));
1821 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1822 if (!NT_STATUS_IS_OK(status)) {
1823 printf("unlink failed (%s)\n", nt_errstr(status));
1827 if (!torture_close_connection(cli1)) {
1831 if (!torture_close_connection(cli2)) {
1835 printf("finished locktest3\n");
1840 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1841 printf("** "); correct = False; \
1845 looks at overlapping locks
1847 static bool run_locktest4(int dummy)
1849 static struct cli_state *cli1, *cli2;
1850 const char *fname = "\\lockt4.lck";
1851 uint16_t fnum1, fnum2, f;
1854 bool correct = True;
1857 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1861 cli_sockopt(cli1, sockops);
1862 cli_sockopt(cli2, sockops);
1864 printf("starting locktest4\n");
1866 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1868 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1869 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1871 memset(buf, 0, sizeof(buf));
1873 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1875 if (!NT_STATUS_IS_OK(status)) {
1876 printf("Failed to create file: %s\n", nt_errstr(status));
1881 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1882 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1883 EXPECTED(ret, False);
1884 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1886 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1887 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1888 EXPECTED(ret, True);
1889 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1891 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1892 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1893 EXPECTED(ret, False);
1894 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1896 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1897 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1898 EXPECTED(ret, True);
1899 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1901 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1902 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1903 EXPECTED(ret, False);
1904 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1906 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1907 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1908 EXPECTED(ret, True);
1909 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1911 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1912 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1913 EXPECTED(ret, True);
1914 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1916 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1917 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1918 EXPECTED(ret, False);
1919 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1921 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1922 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1923 EXPECTED(ret, False);
1924 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1926 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1927 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1928 EXPECTED(ret, True);
1929 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1931 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1932 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1933 EXPECTED(ret, False);
1934 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1936 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1937 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1938 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1939 EXPECTED(ret, False);
1940 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1943 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1944 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1945 EXPECTED(ret, False);
1946 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1948 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1950 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1952 ret = NT_STATUS_IS_OK(status);
1954 EXPECTED(ret, False);
1955 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1958 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1959 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1960 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1961 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1962 EXPECTED(ret, True);
1963 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1966 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1967 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1968 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1969 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1970 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1972 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1973 EXPECTED(ret, True);
1974 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1976 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1977 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1978 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1980 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1981 EXPECTED(ret, True);
1982 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1984 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1985 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1986 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1988 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1989 EXPECTED(ret, True);
1990 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1992 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1993 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1994 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1995 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1997 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1998 EXPECTED(ret, True);
1999 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2001 cli_close(cli1, fnum1);
2002 cli_close(cli2, fnum2);
2003 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2004 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2005 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2006 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
2007 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2008 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2009 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2011 cli_close(cli1, fnum1);
2012 EXPECTED(ret, True);
2013 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2016 cli_close(cli1, fnum1);
2017 cli_close(cli2, fnum2);
2018 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2019 torture_close_connection(cli1);
2020 torture_close_connection(cli2);
2022 printf("finished locktest4\n");
2027 looks at lock upgrade/downgrade.
2029 static bool run_locktest5(int dummy)
2031 static struct cli_state *cli1, *cli2;
2032 const char *fname = "\\lockt5.lck";
2033 uint16_t fnum1, fnum2, fnum3;
2036 bool correct = True;
2039 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2043 cli_sockopt(cli1, sockops);
2044 cli_sockopt(cli2, sockops);
2046 printf("starting locktest5\n");
2048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2050 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2051 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2052 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2054 memset(buf, 0, sizeof(buf));
2056 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2058 if (!NT_STATUS_IS_OK(status)) {
2059 printf("Failed to create file: %s\n", nt_errstr(status));
2064 /* Check for NT bug... */
2065 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2066 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2067 cli_close(cli1, fnum1);
2068 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2069 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2070 EXPECTED(ret, True);
2071 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2072 cli_close(cli1, fnum1);
2073 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2074 cli_unlock(cli1, fnum3, 0, 1);
2076 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2077 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2078 EXPECTED(ret, True);
2079 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2081 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2082 EXPECTED(ret, False);
2084 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2086 /* Unlock the process 2 lock. */
2087 cli_unlock(cli2, fnum2, 0, 4);
2089 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2090 EXPECTED(ret, False);
2092 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2094 /* Unlock the process 1 fnum3 lock. */
2095 cli_unlock(cli1, fnum3, 0, 4);
2097 /* Stack 2 more locks here. */
2098 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2099 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2101 EXPECTED(ret, True);
2102 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2104 /* Unlock the first process lock, then check this was the WRITE lock that was
2107 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2108 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2110 EXPECTED(ret, True);
2111 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2113 /* Unlock the process 2 lock. */
2114 cli_unlock(cli2, fnum2, 0, 4);
2116 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2118 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2119 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2120 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2122 EXPECTED(ret, True);
2123 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2125 /* Ensure the next unlock fails. */
2126 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2127 EXPECTED(ret, False);
2128 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2130 /* Ensure connection 2 can get a write lock. */
2131 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2132 EXPECTED(ret, True);
2134 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2138 cli_close(cli1, fnum1);
2139 cli_close(cli2, fnum2);
2140 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2141 if (!torture_close_connection(cli1)) {
2144 if (!torture_close_connection(cli2)) {
2148 printf("finished locktest5\n");
2154 tries the unusual lockingX locktype bits
2156 static bool run_locktest6(int dummy)
2158 static struct cli_state *cli;
2159 const char *fname[1] = { "\\lock6.txt" };
2164 if (!torture_open_connection(&cli, 0)) {
2168 cli_sockopt(cli, sockops);
2170 printf("starting locktest6\n");
2173 printf("Testing %s\n", fname[i]);
2175 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2177 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2178 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2179 cli_close(cli, fnum);
2180 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2182 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2183 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2184 cli_close(cli, fnum);
2185 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2187 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2190 torture_close_connection(cli);
2192 printf("finished locktest6\n");
2196 static bool run_locktest7(int dummy)
2198 struct cli_state *cli1;
2199 const char *fname = "\\lockt7.lck";
2202 bool correct = False;
2205 if (!torture_open_connection(&cli1, 0)) {
2209 cli_sockopt(cli1, sockops);
2211 printf("starting locktest7\n");
2213 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2215 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2217 memset(buf, 0, sizeof(buf));
2219 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2221 if (!NT_STATUS_IS_OK(status)) {
2222 printf("Failed to create file: %s\n", nt_errstr(status));
2226 cli_setpid(cli1, 1);
2228 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2229 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2232 printf("pid1 successfully locked range 130:4 for READ\n");
2235 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2236 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2239 printf("pid1 successfully read the range 130:4\n");
2242 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2243 if (!NT_STATUS_IS_OK(status)) {
2244 printf("pid1 unable to write to the range 130:4, error was "
2245 "%s\n", nt_errstr(status));
2246 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2247 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2251 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2255 cli_setpid(cli1, 2);
2257 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2258 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2260 printf("pid2 successfully read the range 130:4\n");
2263 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2264 if (!NT_STATUS_IS_OK(status)) {
2265 printf("pid2 unable to write to the range 130:4, error was "
2266 "%s\n", nt_errstr(status));
2267 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2268 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2272 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2276 cli_setpid(cli1, 1);
2277 cli_unlock(cli1, fnum1, 130, 4);
2279 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2280 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2283 printf("pid1 successfully locked range 130:4 for WRITE\n");
2286 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2287 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2290 printf("pid1 successfully read the range 130:4\n");
2293 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2294 if (!NT_STATUS_IS_OK(status)) {
2295 printf("pid1 unable to write to the range 130:4, error was "
2296 "%s\n", nt_errstr(status));
2299 printf("pid1 successfully wrote to the range 130:4\n");
2302 cli_setpid(cli1, 2);
2304 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2305 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2306 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2307 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2311 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2315 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2316 if (!NT_STATUS_IS_OK(status)) {
2317 printf("pid2 unable to write to the range 130:4, error was "
2318 "%s\n", nt_errstr(status));
2319 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2320 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2324 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2328 cli_unlock(cli1, fnum1, 130, 0);
2332 cli_close(cli1, fnum1);
2333 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2334 torture_close_connection(cli1);
2336 printf("finished locktest7\n");
2341 * This demonstrates a problem with our use of GPFS share modes: A file
2342 * descriptor sitting in the pending close queue holding a GPFS share mode
2343 * blocks opening a file another time. Happens with Word 2007 temp files.
2344 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2345 * open is denied with NT_STATUS_SHARING_VIOLATION.
2348 static bool run_locktest8(int dummy)
2350 struct cli_state *cli1;
2351 const char *fname = "\\lockt8.lck";
2352 uint16_t fnum1, fnum2;
2354 bool correct = False;
2357 if (!torture_open_connection(&cli1, 0)) {
2361 cli_sockopt(cli1, sockops);
2363 printf("starting locktest8\n");
2365 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2367 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2369 if (!NT_STATUS_IS_OK(status)) {
2370 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2374 memset(buf, 0, sizeof(buf));
2376 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 d_fprintf(stderr, "cli_open second time returned %s\n",
2383 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2384 printf("Unable to apply read lock on range 1:1, error was "
2385 "%s\n", cli_errstr(cli1));
2389 status = cli_close(cli1, fnum1);
2390 if (!NT_STATUS_IS_OK(status)) {
2391 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2395 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2396 if (!NT_STATUS_IS_OK(status)) {
2397 d_fprintf(stderr, "cli_open third time returned %s\n",
2405 cli_close(cli1, fnum1);
2406 cli_close(cli1, fnum2);
2407 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2408 torture_close_connection(cli1);
2410 printf("finished locktest8\n");
2415 * This test is designed to be run in conjunction with
2416 * external NFS or POSIX locks taken in the filesystem.
2417 * It checks that the smbd server will block until the
2418 * lock is released and then acquire it. JRA.
2421 static bool got_alarm;
2422 static int alarm_fd;
2424 static void alarm_handler(int dummy)
2429 static void alarm_handler_parent(int dummy)
2434 static void do_local_lock(int read_fd, int write_fd)
2439 const char *local_pathname = NULL;
2442 local_pathname = talloc_asprintf(talloc_tos(),
2443 "%s/lockt9.lck", local_path);
2444 if (!local_pathname) {
2445 printf("child: alloc fail\n");
2449 unlink(local_pathname);
2450 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2452 printf("child: open of %s failed %s.\n",
2453 local_pathname, strerror(errno));
2457 /* Now take a fcntl lock. */
2458 lock.l_type = F_WRLCK;
2459 lock.l_whence = SEEK_SET;
2462 lock.l_pid = getpid();
2464 ret = fcntl(fd,F_SETLK,&lock);
2466 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2467 local_pathname, strerror(errno));
2470 printf("child: got lock 0:4 on file %s.\n",
2475 CatchSignal(SIGALRM, alarm_handler);
2477 /* Signal the parent. */
2478 if (write(write_fd, &c, 1) != 1) {
2479 printf("child: start signal fail %s.\n",
2486 /* Wait for the parent to be ready. */
2487 if (read(read_fd, &c, 1) != 1) {
2488 printf("child: reply signal fail %s.\n",
2496 printf("child: released lock 0:4 on file %s.\n",
2502 static bool run_locktest9(int dummy)
2504 struct cli_state *cli1;
2505 const char *fname = "\\lockt9.lck";
2507 bool correct = False;
2508 int pipe_in[2], pipe_out[2];
2512 struct timeval start;
2516 printf("starting locktest9\n");
2518 if (local_path == NULL) {
2519 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2523 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2528 if (child_pid == -1) {
2532 if (child_pid == 0) {
2534 do_local_lock(pipe_out[0], pipe_in[1]);
2544 ret = read(pipe_in[0], &c, 1);
2546 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2551 if (!torture_open_connection(&cli1, 0)) {
2555 cli_sockopt(cli1, sockops);
2557 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2559 if (!NT_STATUS_IS_OK(status)) {
2560 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2564 /* Ensure the child has the lock. */
2565 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2566 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2569 d_printf("Child has the lock.\n");
2572 /* Tell the child to wait 5 seconds then exit. */
2573 ret = write(pipe_out[1], &c, 1);
2575 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2580 /* Wait 20 seconds for the lock. */
2581 alarm_fd = cli1->fd;
2582 CatchSignal(SIGALRM, alarm_handler_parent);
2585 start = timeval_current();
2587 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2588 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2589 "%s\n", cli_errstr(cli1));
2594 seconds = timeval_elapsed(&start);
2596 printf("Parent got the lock after %.2f seconds.\n",
2599 status = cli_close(cli1, fnum);
2600 if (!NT_STATUS_IS_OK(status)) {
2601 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2608 cli_close(cli1, fnum);
2609 torture_close_connection(cli1);
2613 printf("finished locktest9\n");
2618 test whether fnums and tids open on one VC are available on another (a major
2621 static bool run_fdpasstest(int dummy)
2623 struct cli_state *cli1, *cli2;
2624 const char *fname = "\\fdpass.tst";
2629 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2632 cli_sockopt(cli1, sockops);
2633 cli_sockopt(cli2, sockops);
2635 printf("starting fdpasstest\n");
2637 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2639 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2641 if (!NT_STATUS_IS_OK(status)) {
2642 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2646 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2648 if (!NT_STATUS_IS_OK(status)) {
2649 printf("write failed (%s)\n", nt_errstr(status));
2653 cli2->vuid = cli1->vuid;
2654 cli2->cnum = cli1->cnum;
2655 cli2->pid = cli1->pid;
2657 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2658 printf("read succeeded! nasty security hole [%s]\n",
2663 cli_close(cli1, fnum1);
2664 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2666 torture_close_connection(cli1);
2667 torture_close_connection(cli2);
2669 printf("finished fdpasstest\n");
2673 static bool run_fdsesstest(int dummy)
2675 struct cli_state *cli;
2680 const char *fname = "\\fdsess.tst";
2681 const char *fname1 = "\\fdsess1.tst";
2688 if (!torture_open_connection(&cli, 0))
2690 cli_sockopt(cli, sockops);
2692 if (!torture_cli_session_setup2(cli, &new_vuid))
2695 saved_cnum = cli->cnum;
2696 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2698 new_cnum = cli->cnum;
2699 cli->cnum = saved_cnum;
2701 printf("starting fdsesstest\n");
2703 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2704 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2706 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2712 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2714 if (!NT_STATUS_IS_OK(status)) {
2715 printf("write failed (%s)\n", nt_errstr(status));
2719 saved_vuid = cli->vuid;
2720 cli->vuid = new_vuid;
2722 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2723 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2727 /* Try to open a file with different vuid, samba cnum. */
2728 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2729 printf("create with different vuid, same cnum succeeded.\n");
2730 cli_close(cli, fnum2);
2731 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2733 printf("create with different vuid, same cnum failed.\n");
2734 printf("This will cause problems with service clients.\n");
2738 cli->vuid = saved_vuid;
2740 /* Try with same vuid, different cnum. */
2741 cli->cnum = new_cnum;
2743 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2744 printf("read succeeded with different cnum![%s]\n",
2749 cli->cnum = saved_cnum;
2750 cli_close(cli, fnum1);
2751 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2753 torture_close_connection(cli);
2755 printf("finished fdsesstest\n");
2760 This test checks that
2762 1) the server does not allow an unlink on a file that is open
2764 static bool run_unlinktest(int dummy)
2766 struct cli_state *cli;
2767 const char *fname = "\\unlink.tst";
2769 bool correct = True;
2772 if (!torture_open_connection(&cli, 0)) {
2776 cli_sockopt(cli, sockops);
2778 printf("starting unlink test\n");
2780 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2784 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2785 if (!NT_STATUS_IS_OK(status)) {
2786 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2790 status = cli_unlink(cli, fname,
2791 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2792 if (NT_STATUS_IS_OK(status)) {
2793 printf("error: server allowed unlink on an open file\n");
2796 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2797 NT_STATUS_SHARING_VIOLATION);
2800 cli_close(cli, fnum);
2801 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2803 if (!torture_close_connection(cli)) {
2807 printf("unlink test finished\n");
2814 test how many open files this server supports on the one socket
2816 static bool run_maxfidtest(int dummy)
2818 struct cli_state *cli;
2820 uint16_t fnums[0x11000];
2823 bool correct = True;
2829 printf("failed to connect\n");
2833 cli_sockopt(cli, sockops);
2835 for (i=0; i<0x11000; i++) {
2836 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2837 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2839 if (!NT_STATUS_IS_OK(status)) {
2840 printf("open of %s failed (%s)\n",
2841 fname, nt_errstr(status));
2842 printf("maximum fnum is %d\n", i);
2850 printf("cleaning up\n");
2852 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2853 cli_close(cli, fnums[i]);
2855 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 printf("unlink of %s failed (%s)\n",
2858 fname, nt_errstr(status));
2865 printf("maxfid test finished\n");
2866 if (!torture_close_connection(cli)) {
2872 /* generate a random buffer */
2873 static void rand_buf(char *buf, int len)
2876 *buf = (char)sys_random();
2881 /* send smb negprot commands, not reading the response */
2882 static bool run_negprot_nowait(int dummy)
2884 struct tevent_context *ev;
2886 struct cli_state *cli;
2887 bool correct = True;
2889 printf("starting negprot nowait test\n");
2891 ev = tevent_context_init(talloc_tos());
2896 if (!(cli = open_nbt_connection())) {
2901 for (i=0;i<50000;i++) {
2902 struct tevent_req *req;
2904 req = cli_negprot_send(ev, ev, cli);
2909 if (!tevent_req_poll(req, ev)) {
2910 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2918 if (torture_close_connection(cli)) {
2922 printf("finished negprot nowait test\n");
2927 /* send smb negprot commands, not reading the response */
2928 static bool run_bad_nbt_session(int dummy)
2930 struct nmb_name called, calling;
2931 struct sockaddr_storage ss;
2936 printf("starting bad nbt session test\n");
2938 make_nmb_name(&calling, myname, 0x0);
2939 make_nmb_name(&called , host, 0x20);
2941 if (!resolve_name(host, &ss, 0x20, true)) {
2942 d_fprintf(stderr, "Could not resolve name %s\n", host);
2946 status = open_socket_out(&ss, 139, 10000, &fd);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 d_fprintf(stderr, "open_socket_out failed: %s\n",
2953 ret = cli_bad_session_request(fd, &calling, &called);
2956 d_fprintf(stderr, "open_socket_out failed: %s\n",
2961 printf("finished bad nbt session test\n");
2965 /* send random IPC commands */
2966 static bool run_randomipc(int dummy)
2968 char *rparam = NULL;
2970 unsigned int rdrcnt,rprcnt;
2972 int api, param_len, i;
2973 struct cli_state *cli;
2974 bool correct = True;
2977 printf("starting random ipc test\n");
2979 if (!torture_open_connection(&cli, 0)) {
2983 for (i=0;i<count;i++) {
2984 api = sys_random() % 500;
2985 param_len = (sys_random() % 64);
2987 rand_buf(param, param_len);
2992 param, param_len, 8,
2993 NULL, 0, BUFFER_SIZE,
2997 printf("%d/%d\r", i,count);
3000 printf("%d/%d\n", i, count);
3002 if (!torture_close_connection(cli)) {
3006 printf("finished random ipc test\n");
3013 static void browse_callback(const char *sname, uint32 stype,
3014 const char *comment, void *state)
3016 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3022 This test checks the browse list code
3025 static bool run_browsetest(int dummy)
3027 static struct cli_state *cli;
3028 bool correct = True;
3030 printf("starting browse test\n");
3032 if (!torture_open_connection(&cli, 0)) {
3036 printf("domain list:\n");
3037 cli_NetServerEnum(cli, cli->server_domain,
3038 SV_TYPE_DOMAIN_ENUM,
3039 browse_callback, NULL);
3041 printf("machine list:\n");
3042 cli_NetServerEnum(cli, cli->server_domain,
3044 browse_callback, NULL);
3046 if (!torture_close_connection(cli)) {
3050 printf("browse test finished\n");
3058 This checks how the getatr calls works
3060 static bool run_attrtest(int dummy)
3062 struct cli_state *cli;
3065 const char *fname = "\\attrib123456789.tst";
3066 bool correct = True;
3069 printf("starting attrib test\n");
3071 if (!torture_open_connection(&cli, 0)) {
3075 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3076 cli_open(cli, fname,
3077 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3078 cli_close(cli, fnum);
3080 status = cli_getatr(cli, fname, NULL, NULL, &t);
3081 if (!NT_STATUS_IS_OK(status)) {
3082 printf("getatr failed (%s)\n", nt_errstr(status));
3086 if (abs(t - time(NULL)) > 60*60*24*10) {
3087 printf("ERROR: SMBgetatr bug. time is %s",
3093 t2 = t-60*60*24; /* 1 day ago */
3095 status = cli_setatr(cli, fname, 0, t2);
3096 if (!NT_STATUS_IS_OK(status)) {
3097 printf("setatr failed (%s)\n", nt_errstr(status));
3101 status = cli_getatr(cli, fname, NULL, NULL, &t);
3102 if (!NT_STATUS_IS_OK(status)) {
3103 printf("getatr failed (%s)\n", nt_errstr(status));
3108 printf("ERROR: getatr/setatr bug. times are\n%s",
3110 printf("%s", ctime(&t2));
3114 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3116 if (!torture_close_connection(cli)) {
3120 printf("attrib test finished\n");
3127 This checks a couple of trans2 calls
3129 static bool run_trans2test(int dummy)
3131 struct cli_state *cli;
3134 time_t c_time, a_time, m_time;
3135 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3136 const char *fname = "\\trans2.tst";
3137 const char *dname = "\\trans2";
3138 const char *fname2 = "\\trans2\\trans2.tst";
3140 bool correct = True;
3144 printf("starting trans2 test\n");
3146 if (!torture_open_connection(&cli, 0)) {
3150 status = cli_get_fs_attr_info(cli, &fs_attr);
3151 if (!NT_STATUS_IS_OK(status)) {
3152 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3157 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3158 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3159 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3160 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3166 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3172 if (strcmp(pname, fname)) {
3173 printf("qfilename gave different name? [%s] [%s]\n",
3178 cli_close(cli, fnum);
3182 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3183 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3185 if (!NT_STATUS_IS_OK(status)) {
3186 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3189 cli_close(cli, fnum);
3191 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3193 if (!NT_STATUS_IS_OK(status)) {
3194 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3197 if (c_time != m_time) {
3198 printf("create time=%s", ctime(&c_time));
3199 printf("modify time=%s", ctime(&m_time));
3200 printf("This system appears to have sticky create times\n");
3202 if (a_time % (60*60) == 0) {
3203 printf("access time=%s", ctime(&a_time));
3204 printf("This system appears to set a midnight access time\n");
3208 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3209 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3215 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3216 cli_open(cli, fname,
3217 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3218 cli_close(cli, fnum);
3219 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3220 &m_time_ts, &size, NULL, NULL);
3221 if (!NT_STATUS_IS_OK(status)) {
3222 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3225 if (w_time_ts.tv_sec < 60*60*24*2) {
3226 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3227 printf("This system appears to set a initial 0 write time\n");
3232 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3235 /* check if the server updates the directory modification time
3236 when creating a new file */
3237 status = cli_mkdir(cli, dname);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3243 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3244 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3245 if (!NT_STATUS_IS_OK(status)) {
3246 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3250 cli_open(cli, fname2,
3251 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3252 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3253 cli_close(cli, fnum);
3254 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3255 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3256 if (!NT_STATUS_IS_OK(status)) {
3257 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3260 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3262 printf("This system does not update directory modification times\n");
3266 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3267 cli_rmdir(cli, dname);
3269 if (!torture_close_connection(cli)) {
3273 printf("trans2 test finished\n");
3279 This checks new W2K calls.
3282 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3284 uint8_t *buf = NULL;
3288 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3289 pcli->max_xmit, NULL, &buf, &len);
3290 if (!NT_STATUS_IS_OK(status)) {
3291 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3294 printf("qfileinfo: level %d, len = %u\n", level, len);
3295 dump_data(0, (uint8 *)buf, len);
3302 static bool run_w2ktest(int dummy)
3304 struct cli_state *cli;
3306 const char *fname = "\\w2ktest\\w2k.tst";
3308 bool correct = True;
3310 printf("starting w2k test\n");
3312 if (!torture_open_connection(&cli, 0)) {
3316 cli_open(cli, fname,
3317 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3319 for (level = 1004; level < 1040; level++) {
3320 new_trans(cli, fnum, level);
3323 cli_close(cli, fnum);
3325 if (!torture_close_connection(cli)) {
3329 printf("w2k test finished\n");
3336 this is a harness for some oplock tests
3338 static bool run_oplock1(int dummy)
3340 struct cli_state *cli1;
3341 const char *fname = "\\lockt1.lck";
3343 bool correct = True;
3346 printf("starting oplock test 1\n");
3348 if (!torture_open_connection(&cli1, 0)) {
3352 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3354 cli_sockopt(cli1, sockops);
3356 cli1->use_oplocks = True;
3358 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3360 if (!NT_STATUS_IS_OK(status)) {
3361 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3365 cli1->use_oplocks = False;
3367 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3368 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3370 status = cli_close(cli1, fnum1);
3371 if (!NT_STATUS_IS_OK(status)) {
3372 printf("close2 failed (%s)\n", nt_errstr(status));
3376 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3377 if (!NT_STATUS_IS_OK(status)) {
3378 printf("unlink failed (%s)\n", nt_errstr(status));
3382 if (!torture_close_connection(cli1)) {
3386 printf("finished oplock test 1\n");
3391 static bool run_oplock2(int dummy)
3393 struct cli_state *cli1, *cli2;
3394 const char *fname = "\\lockt2.lck";
3395 uint16_t fnum1, fnum2;
3396 int saved_use_oplocks = use_oplocks;
3398 bool correct = True;
3399 volatile bool *shared_correct;
3402 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3403 *shared_correct = True;
3405 use_level_II_oplocks = True;
3408 printf("starting oplock test 2\n");
3410 if (!torture_open_connection(&cli1, 0)) {
3411 use_level_II_oplocks = False;
3412 use_oplocks = saved_use_oplocks;
3416 cli1->use_oplocks = True;
3417 cli1->use_level_II_oplocks = True;
3419 if (!torture_open_connection(&cli2, 1)) {
3420 use_level_II_oplocks = False;
3421 use_oplocks = saved_use_oplocks;
3425 cli2->use_oplocks = True;
3426 cli2->use_level_II_oplocks = True;
3428 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3430 cli_sockopt(cli1, sockops);
3431 cli_sockopt(cli2, sockops);
3433 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3435 if (!NT_STATUS_IS_OK(status)) {
3436 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3440 /* Don't need the globals any more. */
3441 use_level_II_oplocks = False;
3442 use_oplocks = saved_use_oplocks;
3446 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3447 if (!NT_STATUS_IS_OK(status)) {
3448 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3449 *shared_correct = False;
3455 status = cli_close(cli2, fnum2);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 printf("close2 failed (%s)\n", nt_errstr(status));
3458 *shared_correct = False;
3466 /* Ensure cli1 processes the break. Empty file should always return 0
3469 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3470 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3474 /* Should now be at level II. */
3475 /* Test if sending a write locks causes a break to none. */
3477 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3478 printf("lock failed (%s)\n", cli_errstr(cli1));
3482 cli_unlock(cli1, fnum1, 0, 4);
3486 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3487 printf("lock failed (%s)\n", cli_errstr(cli1));
3491 cli_unlock(cli1, fnum1, 0, 4);
3495 cli_read(cli1, fnum1, buf, 0, 4);
3497 status = cli_close(cli1, fnum1);
3498 if (!NT_STATUS_IS_OK(status)) {
3499 printf("close1 failed (%s)\n", nt_errstr(status));
3505 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3506 if (!NT_STATUS_IS_OK(status)) {
3507 printf("unlink failed (%s)\n", nt_errstr(status));
3511 if (!torture_close_connection(cli1)) {
3515 if (!*shared_correct) {
3519 printf("finished oplock test 2\n");
3524 struct oplock4_state {
3525 struct tevent_context *ev;
3526 struct cli_state *cli;
3531 static void oplock4_got_break(struct tevent_req *req);
3532 static void oplock4_got_open(struct tevent_req *req);
3534 static bool run_oplock4(int dummy)
3536 struct tevent_context *ev;
3537 struct cli_state *cli1, *cli2;
3538 struct tevent_req *oplock_req, *open_req;
3539 const char *fname = "\\lockt4.lck";
3540 const char *fname_ln = "\\lockt4_ln.lck";
3541 uint16_t fnum1, fnum2;
3542 int saved_use_oplocks = use_oplocks;
3544 bool correct = true;
3548 struct oplock4_state *state;
3550 printf("starting oplock test 4\n");
3552 if (!torture_open_connection(&cli1, 0)) {
3553 use_level_II_oplocks = false;
3554 use_oplocks = saved_use_oplocks;
3558 if (!torture_open_connection(&cli2, 1)) {
3559 use_level_II_oplocks = false;
3560 use_oplocks = saved_use_oplocks;
3564 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3565 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3567 cli_sockopt(cli1, sockops);
3568 cli_sockopt(cli2, sockops);
3570 /* Create the file. */
3571 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3573 if (!NT_STATUS_IS_OK(status)) {
3574 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3578 status = cli_close(cli1, fnum1);
3579 if (!NT_STATUS_IS_OK(status)) {
3580 printf("close1 failed (%s)\n", nt_errstr(status));
3584 /* Now create a hardlink. */
3585 status = cli_nt_hardlink(cli1, fname, fname_ln);
3586 if (!NT_STATUS_IS_OK(status)) {
3587 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3591 /* Prove that opening hardlinks cause deny modes to conflict. */
3592 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3593 if (!NT_STATUS_IS_OK(status)) {
3594 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3598 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3599 if (NT_STATUS_IS_OK(status)) {
3600 printf("open of %s succeeded - should fail with sharing violation.\n",
3605 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3606 printf("open of %s should fail with sharing violation. Got %s\n",
3607 fname_ln, nt_errstr(status));
3611 status = cli_close(cli1, fnum1);
3612 if (!NT_STATUS_IS_OK(status)) {
3613 printf("close1 failed (%s)\n", nt_errstr(status));
3617 cli1->use_oplocks = true;
3618 cli1->use_level_II_oplocks = true;
3620 cli2->use_oplocks = true;
3621 cli2->use_level_II_oplocks = true;
3623 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3629 ev = tevent_context_init(talloc_tos());
3631 printf("tevent_req_create failed\n");
3635 state = talloc(ev, struct oplock4_state);
3636 if (state == NULL) {
3637 printf("talloc failed\n");
3642 state->got_break = &got_break;
3643 state->fnum2 = &fnum2;
3645 oplock_req = cli_smb_oplock_break_waiter_send(
3646 talloc_tos(), ev, cli1);
3647 if (oplock_req == NULL) {
3648 printf("cli_smb_oplock_break_waiter_send failed\n");
3651 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3653 open_req = cli_open_send(
3654 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3655 if (oplock_req == NULL) {
3656 printf("cli_open_send failed\n");
3659 tevent_req_set_callback(open_req, oplock4_got_open, state);
3664 while (!got_break || fnum2 == 0xffff) {
3666 ret = tevent_loop_once(ev);
3668 printf("tevent_loop_once failed: %s\n",
3674 status = cli_close(cli2, fnum2);
3675 if (!NT_STATUS_IS_OK(status)) {
3676 printf("close2 failed (%s)\n", nt_errstr(status));
3680 status = cli_close(cli1, fnum1);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 printf("close1 failed (%s)\n", nt_errstr(status));
3686 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3687 if (!NT_STATUS_IS_OK(status)) {
3688 printf("unlink failed (%s)\n", nt_errstr(status));
3692 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3693 if (!NT_STATUS_IS_OK(status)) {
3694 printf("unlink failed (%s)\n", nt_errstr(status));
3698 if (!torture_close_connection(cli1)) {
3706 printf("finished oplock test 4\n");
3711 static void oplock4_got_break(struct tevent_req *req)
3713 struct oplock4_state *state = tevent_req_callback_data(
3714 req, struct oplock4_state);
3719 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3721 if (!NT_STATUS_IS_OK(status)) {
3722 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3726 *state->got_break = true;
3728 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3731 printf("cli_oplock_ack_send failed\n");
3736 static void oplock4_got_open(struct tevent_req *req)
3738 struct oplock4_state *state = tevent_req_callback_data(
3739 req, struct oplock4_state);
3742 status = cli_open_recv(req, state->fnum2);
3743 if (!NT_STATUS_IS_OK(status)) {
3744 printf("cli_open_recv returned %s\n", nt_errstr(status));
3745 *state->fnum2 = 0xffff;
3750 Test delete on close semantics.
3752 static bool run_deletetest(int dummy)
3754 struct cli_state *cli1 = NULL;
3755 struct cli_state *cli2 = NULL;
3756 const char *fname = "\\delete.file";
3757 uint16_t fnum1 = (uint16_t)-1;
3758 uint16_t fnum2 = (uint16_t)-1;
3759 bool correct = True;
3762 printf("starting delete test\n");
3764 if (!torture_open_connection(&cli1, 0)) {
3768 cli_sockopt(cli1, sockops);
3770 /* Test 1 - this should delete the file on close. */
3772 cli_setatr(cli1, fname, 0, 0);
3773 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3775 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3776 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3777 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3778 if (!NT_STATUS_IS_OK(status)) {
3779 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3784 status = cli_close(cli1, fnum1);
3785 if (!NT_STATUS_IS_OK(status)) {
3786 printf("[1] close failed (%s)\n", nt_errstr(status));
3791 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3792 printf("[1] open of %s succeeded (should fail)\n", fname);
3797 printf("first delete on close test succeeded.\n");
3799 /* Test 2 - this should delete the file on close. */
3801 cli_setatr(cli1, fname, 0, 0);
3802 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3804 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3805 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3806 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3807 if (!NT_STATUS_IS_OK(status)) {
3808 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3813 status = cli_nt_delete_on_close(cli1, fnum1, true);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3820 status = cli_close(cli1, fnum1);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 printf("[2] close failed (%s)\n", nt_errstr(status));
3827 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3828 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3829 status = cli_close(cli1, fnum1);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 printf("[2] close failed (%s)\n", nt_errstr(status));
3835 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3837 printf("second delete on close test succeeded.\n");
3840 cli_setatr(cli1, fname, 0, 0);
3841 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3843 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3844 FILE_ATTRIBUTE_NORMAL,
3845 FILE_SHARE_READ|FILE_SHARE_WRITE,
3846 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3847 if (!NT_STATUS_IS_OK(status)) {
3848 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3853 /* This should fail with a sharing violation - open for delete is only compatible
3854 with SHARE_DELETE. */
3856 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3857 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3858 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3863 /* This should succeed. */
3864 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3865 FILE_ATTRIBUTE_NORMAL,
3866 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3867 FILE_OPEN, 0, 0, &fnum2);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3874 status = cli_nt_delete_on_close(cli1, fnum1, true);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3881 status = cli_close(cli1, fnum1);
3882 if (!NT_STATUS_IS_OK(status)) {
3883 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3888 status = cli_close(cli1, fnum2);
3889 if (!NT_STATUS_IS_OK(status)) {
3890 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3895 /* This should fail - file should no longer be there. */
3897 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3898 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3899 status = cli_close(cli1, fnum1);
3900 if (!NT_STATUS_IS_OK(status)) {
3901 printf("[3] close failed (%s)\n", nt_errstr(status));
3903 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3907 printf("third delete on close test succeeded.\n");
3910 cli_setatr(cli1, fname, 0, 0);
3911 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3913 status = cli_ntcreate(cli1, fname, 0,
3914 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3915 FILE_ATTRIBUTE_NORMAL,
3916 FILE_SHARE_READ|FILE_SHARE_WRITE,
3917 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3924 /* This should succeed. */
3925 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3926 FILE_ATTRIBUTE_NORMAL,
3927 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3928 FILE_OPEN, 0, 0, &fnum2);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3935 status = cli_close(cli1, fnum2);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3942 status = cli_nt_delete_on_close(cli1, fnum1, true);
3943 if (!NT_STATUS_IS_OK(status)) {
3944 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3949 /* This should fail - no more opens once delete on close set. */
3950 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3951 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3952 FILE_OPEN, 0, 0, &fnum2))) {
3953 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3957 printf("fourth delete on close test succeeded.\n");
3959 status = cli_close(cli1, fnum1);
3960 if (!NT_STATUS_IS_OK(status)) {
3961 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3967 cli_setatr(cli1, fname, 0, 0);
3968 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3970 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3971 if (!NT_STATUS_IS_OK(status)) {
3972 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3977 /* This should fail - only allowed on NT opens with DELETE access. */
3979 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3980 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3985 status = cli_close(cli1, fnum1);
3986 if (!NT_STATUS_IS_OK(status)) {
3987 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3992 printf("fifth delete on close test succeeded.\n");
3995 cli_setatr(cli1, fname, 0, 0);
3996 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3998 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3999 FILE_ATTRIBUTE_NORMAL,
4000 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4001 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("[6] open of %s failed (%s)\n", fname,
4009 /* This should fail - only allowed on NT opens with DELETE access. */
4011 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4012 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4017 status = cli_close(cli1, fnum1);
4018 if (!NT_STATUS_IS_OK(status)) {
4019 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4024 printf("sixth delete on close test succeeded.\n");
4027 cli_setatr(cli1, fname, 0, 0);
4028 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4030 status = cli_ntcreate(cli1, fname, 0,
4031 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4032 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4034 if (!NT_STATUS_IS_OK(status)) {
4035 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4040 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4041 printf("[7] setting delete_on_close on file failed !\n");
4046 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4047 printf("[7] unsetting delete_on_close on file failed !\n");
4052 status = cli_close(cli1, fnum1);
4053 if (!NT_STATUS_IS_OK(status)) {
4054 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4059 /* This next open should succeed - we reset the flag. */
4060 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4061 if (!NT_STATUS_IS_OK(status)) {
4062 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4067 status = cli_close(cli1, fnum1);
4068 if (!NT_STATUS_IS_OK(status)) {
4069 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4074 printf("seventh delete on close test succeeded.\n");
4077 cli_setatr(cli1, fname, 0, 0);
4078 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4080 if (!torture_open_connection(&cli2, 1)) {
4081 printf("[8] failed to open second connection.\n");
4086 cli_sockopt(cli1, sockops);
4088 status = cli_ntcreate(cli1, fname, 0,
4089 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4090 FILE_ATTRIBUTE_NORMAL,
4091 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4092 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4093 if (!NT_STATUS_IS_OK(status)) {
4094 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4099 status = cli_ntcreate(cli2, fname, 0,
4100 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4101 FILE_ATTRIBUTE_NORMAL,
4102 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4103 FILE_OPEN, 0, 0, &fnum2);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4110 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4111 printf("[8] setting delete_on_close on file failed !\n");
4116 status = cli_close(cli1, fnum1);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4123 status = cli_close(cli2, fnum2);
4124 if (!NT_STATUS_IS_OK(status)) {
4125 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4130 /* This should fail.. */
4131 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4132 if (NT_STATUS_IS_OK(status)) {
4133 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4137 printf("eighth delete on close test succeeded.\n");
4139 /* This should fail - we need to set DELETE_ACCESS. */
4140 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4141 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4142 printf("[9] open of %s succeeded should have failed!\n", fname);
4147 printf("ninth delete on close test succeeded.\n");
4149 status = cli_ntcreate(cli1, fname, 0,
4150 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4151 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4152 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4154 if (!NT_STATUS_IS_OK(status)) {
4155 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4160 /* This should delete the file. */
4161 status = cli_close(cli1, fnum1);
4162 if (!NT_STATUS_IS_OK(status)) {
4163 printf("[10] close failed (%s)\n", nt_errstr(status));
4168 /* This should fail.. */
4169 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4170 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4174 printf("tenth delete on close test succeeded.\n");
4176 cli_setatr(cli1, fname, 0, 0);
4177 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4179 /* What error do we get when attempting to open a read-only file with
4182 /* Create a readonly file. */
4183 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4184 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4185 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4186 if (!NT_STATUS_IS_OK(status)) {
4187 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4192 status = cli_close(cli1, fnum1);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 printf("[11] close failed (%s)\n", nt_errstr(status));
4199 /* Now try open for delete access. */
4200 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4201 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4202 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4203 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4204 cli_close(cli1, fnum1);
4208 NTSTATUS nterr = cli_nt_error(cli1);
4209 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4210 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4214 printf("eleventh delete on close test succeeded.\n");
4218 printf("finished delete test\n");
4221 /* FIXME: This will crash if we aborted before cli2 got
4222 * intialized, because these functions don't handle
4223 * uninitialized connections. */
4225 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4226 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4227 cli_setatr(cli1, fname, 0, 0);
4228 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4230 if (cli1 && !torture_close_connection(cli1)) {
4233 if (cli2 && !torture_close_connection(cli2)) {
4239 static bool run_deletetest_ln(int dummy)
4241 struct cli_state *cli;
4242 const char *fname = "\\delete1";
4243 const char *fname_ln = "\\delete1_ln";
4247 bool correct = true;
4250 printf("starting deletetest-ln\n");
4252 if (!torture_open_connection(&cli, 0)) {
4256 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4257 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4259 cli_sockopt(cli, sockops);
4261 /* Create the file. */
4262 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4263 if (!NT_STATUS_IS_OK(status)) {
4264 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4268 status = cli_close(cli, fnum);
4269 if (!NT_STATUS_IS_OK(status)) {
4270 printf("close1 failed (%s)\n", nt_errstr(status));
4274 /* Now create a hardlink. */
4275 status = cli_nt_hardlink(cli, fname, fname_ln);
4276 if (!NT_STATUS_IS_OK(status)) {
4277 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4281 /* Open the original file. */
4282 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4283 FILE_ATTRIBUTE_NORMAL,
4284 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4285 FILE_OPEN_IF, 0, 0, &fnum);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4291 /* Unlink the hard link path. */
4292 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4293 FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4295 FILE_OPEN_IF, 0, 0, &fnum1);
4296 if (!NT_STATUS_IS_OK(status)) {
4297 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4300 status = cli_nt_delete_on_close(cli, fnum1, true);
4301 if (!NT_STATUS_IS_OK(status)) {
4302 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4303 __location__, fname_ln, nt_errstr(status));
4307 status = cli_close(cli, fnum1);
4308 if (!NT_STATUS_IS_OK(status)) {
4309 printf("close %s failed (%s)\n",
4310 fname_ln, nt_errstr(status));
4314 status = cli_close(cli, fnum);
4315 if (!NT_STATUS_IS_OK(status)) {
4316 printf("close %s failed (%s)\n",
4317 fname, nt_errstr(status));
4321 /* Ensure the original file is still there. */
4322 status = cli_getatr(cli, fname, NULL, NULL, &t);
4323 if (!NT_STATUS_IS_OK(status)) {
4324 printf("%s getatr on file %s failed (%s)\n",
4331 /* Ensure the link path is gone. */
4332 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4333 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4334 printf("%s, getatr for file %s returned wrong error code %s "
4335 "- should have been deleted\n",
4337 fname_ln, nt_errstr(status));
4341 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4342 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4344 if (!torture_close_connection(cli)) {
4348 printf("finished deletetest-ln\n");
4354 print out server properties
4356 static bool run_properties(int dummy)
4358 struct cli_state *cli;
4359 bool correct = True;
4361 printf("starting properties test\n");
4365 if (!torture_open_connection(&cli, 0)) {
4369 cli_sockopt(cli, sockops);
4371 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4373 if (!torture_close_connection(cli)) {
4382 /* FIRST_DESIRED_ACCESS 0xf019f */
4383 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4384 FILE_READ_EA| /* 0xf */ \
4385 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4386 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4387 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4388 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4389 /* SECOND_DESIRED_ACCESS 0xe0080 */
4390 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4391 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4392 WRITE_OWNER_ACCESS /* 0xe0000 */
4395 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4396 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4398 WRITE_OWNER_ACCESS /* */
4402 Test ntcreate calls made by xcopy
4404 static bool run_xcopy(int dummy)
4406 static struct cli_state *cli1;
4407 const char *fname = "\\test.txt";
4408 bool correct = True;
4409 uint16_t fnum1, fnum2;
4412 printf("starting xcopy test\n");
4414 if (!torture_open_connection(&cli1, 0)) {
4418 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4419 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4420 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4421 if (!NT_STATUS_IS_OK(status)) {
4422 printf("First open failed - %s\n", nt_errstr(status));
4426 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4427 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4428 FILE_OPEN, 0x200000, 0, &fnum2);
4429 if (!NT_STATUS_IS_OK(status)) {
4430 printf("second open failed - %s\n", nt_errstr(status));
4434 if (!torture_close_connection(cli1)) {
4442 Test rename on files open with share delete and no share delete.
4444 static bool run_rename(int dummy)
4446 static struct cli_state *cli1;
4447 const char *fname = "\\test.txt";
4448 const char *fname1 = "\\test1.txt";
4449 bool correct = True;
4454 printf("starting rename test\n");
4456 if (!torture_open_connection(&cli1, 0)) {
4460 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4461 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4463 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4464 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4465 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("First open failed - %s\n", nt_errstr(status));
4471 status = cli_rename(cli1, fname, fname1);
4472 if (!NT_STATUS_IS_OK(status)) {
4473 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4475 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4479 status = cli_close(cli1, fnum1);
4480 if (!NT_STATUS_IS_OK(status)) {
4481 printf("close - 1 failed (%s)\n", nt_errstr(status));
4485 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4486 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4487 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4489 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4491 FILE_SHARE_DELETE|FILE_SHARE_READ,
4493 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4494 if (!NT_STATUS_IS_OK(status)) {
4495 printf("Second open failed - %s\n", nt_errstr(status));
4499 status = cli_rename(cli1, fname, fname1);
4500 if (!NT_STATUS_IS_OK(status)) {
4501 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4504 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4507 status = cli_close(cli1, fnum1);
4508 if (!NT_STATUS_IS_OK(status)) {
4509 printf("close - 2 failed (%s)\n", nt_errstr(status));
4513 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4514 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4516 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4517 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4518 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4519 if (!NT_STATUS_IS_OK(status)) {
4520 printf("Third open failed - %s\n", nt_errstr(status));
4529 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4530 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4531 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4534 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4535 printf("[8] setting delete_on_close on file failed !\n");
4539 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4540 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4546 status = cli_rename(cli1, fname, fname1);
4547 if (!NT_STATUS_IS_OK(status)) {
4548 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4551 printf("Third rename succeeded (SHARE_NONE)\n");
4554 status = cli_close(cli1, fnum1);
4555 if (!NT_STATUS_IS_OK(status)) {
4556 printf("close - 3 failed (%s)\n", nt_errstr(status));
4560 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4561 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4565 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4566 FILE_ATTRIBUTE_NORMAL,
4567 FILE_SHARE_READ | FILE_SHARE_WRITE,
4568 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 printf("Fourth open failed - %s\n", nt_errstr(status));
4574 status = cli_rename(cli1, fname, fname1);
4575 if (!NT_STATUS_IS_OK(status)) {
4576 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4578 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4582 status = cli_close(cli1, fnum1);
4583 if (!NT_STATUS_IS_OK(status)) {
4584 printf("close - 4 failed (%s)\n", nt_errstr(status));
4588 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4589 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4593 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4594 FILE_ATTRIBUTE_NORMAL,
4595 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4596 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4597 if (!NT_STATUS_IS_OK(status)) {
4598 printf("Fifth open failed - %s\n", nt_errstr(status));
4602 status = cli_rename(cli1, fname, fname1);
4603 if (!NT_STATUS_IS_OK(status)) {
4604 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4607 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4611 * Now check if the first name still exists ...
4614 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4615 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4616 printf("Opening original file after rename of open file fails: %s\n",
4620 printf("Opening original file after rename of open file works ...\n");
4621 (void)cli_close(cli1, fnum2);
4625 status = cli_close(cli1, fnum1);
4626 if (!NT_STATUS_IS_OK(status)) {
4627 printf("close - 5 failed (%s)\n", nt_errstr(status));
4631 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4632 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4633 if (!NT_STATUS_IS_OK(status)) {
4634 printf("getatr on file %s failed - %s ! \n",
4635 fname1, nt_errstr(status));
4638 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4639 printf("Renamed file %s has wrong attr 0x%x "
4640 "(should be 0x%x)\n",
4643 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4646 printf("Renamed file %s has archive bit set\n", fname1);
4650 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4651 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4653 if (!torture_close_connection(cli1)) {
4660 static bool run_pipe_number(int dummy)
4662 struct cli_state *cli1;
4663 const char *pipe_name = "\\SPOOLSS";
4668 printf("starting pipenumber test\n");
4669 if (!torture_open_connection(&cli1, 0)) {
4673 cli_sockopt(cli1, sockops);
4675 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4676 FILE_ATTRIBUTE_NORMAL,
4677 FILE_SHARE_READ|FILE_SHARE_WRITE,
4678 FILE_OPEN_IF, 0, 0, &fnum);
4679 if (!NT_STATUS_IS_OK(status)) {
4680 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4684 printf("\r%6d", num_pipes);
4687 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4688 torture_close_connection(cli1);
4693 Test open mode returns on read-only files.
4695 static bool run_opentest(int dummy)
4697 static struct cli_state *cli1;
4698 static struct cli_state *cli2;
4699 const char *fname = "\\readonly.file";
4700 uint16_t fnum1, fnum2;
4703 bool correct = True;
4707 printf("starting open test\n");
4709 if (!torture_open_connection(&cli1, 0)) {
4713 cli_setatr(cli1, fname, 0, 0);
4714 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4716 cli_sockopt(cli1, sockops);
4718 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4719 if (!NT_STATUS_IS_OK(status)) {
4720 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4724 status = cli_close(cli1, fnum1);
4725 if (!NT_STATUS_IS_OK(status)) {
4726 printf("close2 failed (%s)\n", nt_errstr(status));
4730 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4731 if (!NT_STATUS_IS_OK(status)) {
4732 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4736 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4742 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4743 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4745 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4746 NT_STATUS_ACCESS_DENIED)) {
4747 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4750 printf("finished open test 1\n");
4752 cli_close(cli1, fnum1);
4754 /* Now try not readonly and ensure ERRbadshare is returned. */
4756 cli_setatr(cli1, fname, 0, 0);
4758 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4759 if (!NT_STATUS_IS_OK(status)) {
4760 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4764 /* This will fail - but the error should be ERRshare. */
4765 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4767 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4768 NT_STATUS_SHARING_VIOLATION)) {
4769 printf("correct error code ERRDOS/ERRbadshare returned\n");
4772 status = cli_close(cli1, fnum1);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 printf("close2 failed (%s)\n", nt_errstr(status));
4778 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4780 printf("finished open test 2\n");
4782 /* Test truncate open disposition on file opened for read. */
4783 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4784 if (!NT_STATUS_IS_OK(status)) {
4785 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4789 /* write 20 bytes. */
4791 memset(buf, '\0', 20);
4793 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4794 if (!NT_STATUS_IS_OK(status)) {
4795 printf("write failed (%s)\n", nt_errstr(status));
4799 status = cli_close(cli1, fnum1);
4800 if (!NT_STATUS_IS_OK(status)) {
4801 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4805 /* Ensure size == 20. */
4806 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4807 if (!NT_STATUS_IS_OK(status)) {
4808 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4813 printf("(3) file size != 20\n");
4817 /* Now test if we can truncate a file opened for readonly. */
4818 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4819 if (!NT_STATUS_IS_OK(status)) {
4820 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4824 status = cli_close(cli1, fnum1);
4825 if (!NT_STATUS_IS_OK(status)) {
4826 printf("close2 failed (%s)\n", nt_errstr(status));
4830 /* Ensure size == 0. */
4831 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4832 if (!NT_STATUS_IS_OK(status)) {
4833 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4838 printf("(3) file size != 0\n");
4841 printf("finished open test 3\n");
4843 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4845 printf("Do ctemp tests\n");
4846 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4847 if (!NT_STATUS_IS_OK(status)) {
4848 printf("ctemp failed (%s)\n", nt_errstr(status));
4852 printf("ctemp gave path %s\n", tmp_path);
4853 status = cli_close(cli1, fnum1);
4854 if (!NT_STATUS_IS_OK(status)) {
4855 printf("close of temp failed (%s)\n", nt_errstr(status));
4858 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4859 if (!NT_STATUS_IS_OK(status)) {
4860 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4863 /* Test the non-io opens... */
4865 if (!torture_open_connection(&cli2, 1)) {
4869 cli_setatr(cli2, fname, 0, 0);
4870 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4872 cli_sockopt(cli2, sockops);
4874 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4875 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4876 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4877 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4883 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4884 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4885 FILE_OPEN_IF, 0, 0, &fnum2);
4886 if (!NT_STATUS_IS_OK(status)) {
4887 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4891 status = cli_close(cli1, fnum1);
4892 if (!NT_STATUS_IS_OK(status)) {
4893 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4897 status = cli_close(cli2, fnum2);
4898 if (!NT_STATUS_IS_OK(status)) {
4899 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4903 printf("non-io open test #1 passed.\n");
4905 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4907 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4909 status = cli_ntcreate(cli1, fname, 0,
4910 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4911 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4912 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4913 if (!NT_STATUS_IS_OK(status)) {
4914 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4918 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4919 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4920 FILE_OPEN_IF, 0, 0, &fnum2);
4921 if (!NT_STATUS_IS_OK(status)) {
4922 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4926 status = cli_close(cli1, fnum1);
4927 if (!NT_STATUS_IS_OK(status)) {
4928 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4932 status = cli_close(cli2, fnum2);
4933 if (!NT_STATUS_IS_OK(status)) {
4934 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4938 printf("non-io open test #2 passed.\n");
4940 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4942 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4944 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4945 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4946 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4947 if (!NT_STATUS_IS_OK(status)) {
4948 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4952 status = cli_ntcreate(cli2, fname, 0,
4953 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4954 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4955 FILE_OPEN_IF, 0, 0, &fnum2);
4956 if (!NT_STATUS_IS_OK(status)) {
4957 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4961 status = cli_close(cli1, fnum1);
4962 if (!NT_STATUS_IS_OK(status)) {
4963 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4967 status = cli_close(cli2, fnum2);
4968 if (!NT_STATUS_IS_OK(status)) {
4969 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4973 printf("non-io open test #3 passed.\n");
4975 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4977 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4979 status = cli_ntcreate(cli1, fname, 0,
4980 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4981 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4982 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4983 if (!NT_STATUS_IS_OK(status)) {
4984 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4988 status = cli_ntcreate(cli2, fname, 0,
4989 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4990 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4991 FILE_OPEN_IF, 0, 0, &fnum2);
4992 if (NT_STATUS_IS_OK(status)) {
4993 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4997 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4999 status = cli_close(cli1, fnum1);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5005 printf("non-io open test #4 passed.\n");
5007 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5009 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5011 status = cli_ntcreate(cli1, fname, 0,
5012 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5013 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5014 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5015 if (!NT_STATUS_IS_OK(status)) {
5016 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5020 status = cli_ntcreate(cli2, fname, 0,
5021 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5022 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5023 FILE_OPEN_IF, 0, 0, &fnum2);
5024 if (!NT_STATUS_IS_OK(status)) {
5025 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5029 status = cli_close(cli1, fnum1);
5030 if (!NT_STATUS_IS_OK(status)) {
5031 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5035 status = cli_close(cli2, fnum2);
5036 if (!NT_STATUS_IS_OK(status)) {
5037 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5041 printf("non-io open test #5 passed.\n");
5043 printf("TEST #6 testing 1 non-io open, one io open\n");
5045 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5047 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5048 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5049 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5050 if (!NT_STATUS_IS_OK(status)) {
5051 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5055 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5056 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5057 FILE_OPEN_IF, 0, 0, &fnum2);
5058 if (!NT_STATUS_IS_OK(status)) {
5059 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5063 status = cli_close(cli1, fnum1);
5064 if (!NT_STATUS_IS_OK(status)) {
5065 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5069 status = cli_close(cli2, fnum2);
5070 if (!NT_STATUS_IS_OK(status)) {
5071 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5075 printf("non-io open test #6 passed.\n");
5077 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5079 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5081 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5082 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5083 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5084 if (!NT_STATUS_IS_OK(status)) {
5085 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5089 status = cli_ntcreate(cli2, fname, 0,
5090 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5091 FILE_ATTRIBUTE_NORMAL,
5092 FILE_SHARE_READ|FILE_SHARE_DELETE,
5093 FILE_OPEN_IF, 0, 0, &fnum2);
5094 if (NT_STATUS_IS_OK(status)) {
5095 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5099 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5101 status = cli_close(cli1, fnum1);
5102 if (!NT_STATUS_IS_OK(status)) {
5103 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5107 printf("non-io open test #7 passed.\n");
5109 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5111 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5112 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5113 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5114 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5115 if (!NT_STATUS_IS_OK(status)) {
5116 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5121 /* Write to ensure we have to update the file time. */
5122 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5124 if (!NT_STATUS_IS_OK(status)) {
5125 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5130 status = cli_close(cli1, fnum1);
5131 if (!NT_STATUS_IS_OK(status)) {
5132 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5138 if (!torture_close_connection(cli1)) {
5141 if (!torture_close_connection(cli2)) {
5148 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5150 uint16 major, minor;
5151 uint32 caplow, caphigh;
5154 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5155 printf("Server doesn't support UNIX CIFS extensions.\n");
5156 return NT_STATUS_NOT_SUPPORTED;
5159 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5161 if (!NT_STATUS_IS_OK(status)) {
5162 printf("Server didn't return UNIX CIFS extensions: %s\n",
5167 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5169 if (!NT_STATUS_IS_OK(status)) {
5170 printf("Server doesn't support setting UNIX CIFS extensions: "
5171 "%s.\n", nt_errstr(status));
5175 return NT_STATUS_OK;
5179 Test POSIX open /mkdir calls.
5181 static bool run_simple_posix_open_test(int dummy)
5183 static struct cli_state *cli1;
5184 const char *fname = "posix:file";
5185 const char *hname = "posix:hlink";
5186 const char *sname = "posix:symlink";
5187 const char *dname = "posix:dir";
5190 uint16_t fnum1 = (uint16_t)-1;
5191 SMB_STRUCT_STAT sbuf;
5192 bool correct = false;
5195 printf("Starting simple POSIX open test\n");
5197 if (!torture_open_connection(&cli1, 0)) {
5201 cli_sockopt(cli1, sockops);
5203 status = torture_setup_unix_extensions(cli1);
5204 if (!NT_STATUS_IS_OK(status)) {
5208 cli_setatr(cli1, fname, 0, 0);
5209 cli_posix_unlink(cli1, fname);
5210 cli_setatr(cli1, dname, 0, 0);
5211 cli_posix_rmdir(cli1, dname);
5212 cli_setatr(cli1, hname, 0, 0);
5213 cli_posix_unlink(cli1, hname);
5214 cli_setatr(cli1, sname, 0, 0);
5215 cli_posix_unlink(cli1, sname);
5217 /* Create a directory. */
5218 status = cli_posix_mkdir(cli1, dname, 0777);
5219 if (!NT_STATUS_IS_OK(status)) {
5220 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5224 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5226 if (!NT_STATUS_IS_OK(status)) {
5227 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5231 /* Test ftruncate - set file size. */
5232 status = cli_ftruncate(cli1, fnum1, 1000);
5233 if (!NT_STATUS_IS_OK(status)) {
5234 printf("ftruncate failed (%s)\n", nt_errstr(status));
5238 /* Ensure st_size == 1000 */
5239 status = cli_posix_stat(cli1, fname, &sbuf);
5240 if (!NT_STATUS_IS_OK(status)) {
5241 printf("stat failed (%s)\n", nt_errstr(status));
5245 if (sbuf.st_ex_size != 1000) {
5246 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5250 /* Test ftruncate - set file size back to zero. */
5251 status = cli_ftruncate(cli1, fnum1, 0);
5252 if (!NT_STATUS_IS_OK(status)) {
5253 printf("ftruncate failed (%s)\n", nt_errstr(status));
5257 status = cli_close(cli1, fnum1);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("close failed (%s)\n", nt_errstr(status));
5263 /* Now open the file again for read only. */
5264 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5270 /* Now unlink while open. */
5271 status = cli_posix_unlink(cli1, fname);
5272 if (!NT_STATUS_IS_OK(status)) {
5273 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5277 status = cli_close(cli1, fnum1);
5278 if (!NT_STATUS_IS_OK(status)) {
5279 printf("close(2) failed (%s)\n", nt_errstr(status));
5283 /* Ensure the file has gone. */
5284 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5285 if (NT_STATUS_IS_OK(status)) {
5286 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5290 /* Create again to test open with O_TRUNC. */
5291 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5292 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5296 /* Test ftruncate - set file size. */
5297 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5298 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5302 /* Ensure st_size == 1000 */
5303 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5304 printf("stat failed (%s)\n", cli_errstr(cli1));
5308 if (sbuf.st_ex_size != 1000) {
5309 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5313 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5314 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5318 /* Re-open with O_TRUNC. */
5319 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5320 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5324 /* Ensure st_size == 0 */
5325 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5326 printf("stat failed (%s)\n", cli_errstr(cli1));
5330 if (sbuf.st_ex_size != 0) {
5331 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5335 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5336 printf("close failed (%s)\n", cli_errstr(cli1));
5340 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5341 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5345 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5346 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5347 dname, cli_errstr(cli1));
5351 cli_close(cli1, fnum1);
5353 /* What happens when we try and POSIX open a directory for write ? */
5354 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5355 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5358 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5359 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5364 /* Create the file. */
5365 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5367 if (!NT_STATUS_IS_OK(status)) {
5368 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5372 /* Write some data into it. */
5373 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5375 if (!NT_STATUS_IS_OK(status)) {
5376 printf("cli_write failed: %s\n", nt_errstr(status));
5380 cli_close(cli1, fnum1);
5382 /* Now create a hardlink. */
5383 status = cli_posix_hardlink(cli1, fname, hname);
5384 if (!NT_STATUS_IS_OK(status)) {
5385 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5389 /* Now create a symlink. */
5390 status = cli_posix_symlink(cli1, fname, sname);
5391 if (!NT_STATUS_IS_OK(status)) {
5392 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5396 /* Open the hardlink for read. */
5397 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5398 if (!NT_STATUS_IS_OK(status)) {
5399 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5403 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5404 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5408 if (memcmp(buf, "TEST DATA\n", 10)) {
5409 printf("invalid data read from hardlink\n");
5413 /* Do a POSIX lock/unlock. */
5414 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5415 if (!NT_STATUS_IS_OK(status)) {
5416 printf("POSIX lock failed %s\n", nt_errstr(status));
5420 /* Punch a hole in the locked area. */
5421 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5422 if (!NT_STATUS_IS_OK(status)) {
5423 printf("POSIX unlock failed %s\n", nt_errstr(status));
5427 cli_close(cli1, fnum1);
5429 /* Open the symlink for read - this should fail. A POSIX
5430 client should not be doing opens on a symlink. */
5431 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5432 if (NT_STATUS_IS_OK(status)) {
5433 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5436 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5437 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5438 printf("POSIX open of %s should have failed "
5439 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5440 "failed with %s instead.\n",
5441 sname, nt_errstr(status));
5446 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5452 if (strcmp(namebuf, fname) != 0) {
5453 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5454 sname, fname, namebuf);
5458 status = cli_posix_rmdir(cli1, dname);
5459 if (!NT_STATUS_IS_OK(status)) {
5460 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5464 printf("Simple POSIX open test passed\n");
5469 if (fnum1 != (uint16_t)-1) {
5470 cli_close(cli1, fnum1);
5471 fnum1 = (uint16_t)-1;
5474 cli_setatr(cli1, sname, 0, 0);
5475 cli_posix_unlink(cli1, sname);
5476 cli_setatr(cli1, hname, 0, 0);
5477 cli_posix_unlink(cli1, hname);
5478 cli_setatr(cli1, fname, 0, 0);
5479 cli_posix_unlink(cli1, fname);
5480 cli_setatr(cli1, dname, 0, 0);
5481 cli_posix_rmdir(cli1, dname);
5483 if (!torture_close_connection(cli1)) {
5491 static uint32 open_attrs_table[] = {
5492 FILE_ATTRIBUTE_NORMAL,
5493 FILE_ATTRIBUTE_ARCHIVE,
5494 FILE_ATTRIBUTE_READONLY,
5495 FILE_ATTRIBUTE_HIDDEN,
5496 FILE_ATTRIBUTE_SYSTEM,
5498 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5499 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5500 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5501 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5502 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5503 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5505 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5506 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5507 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5508 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5511 struct trunc_open_results {
5518 static struct trunc_open_results attr_results[] = {
5519 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5520 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5521 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5522 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5523 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5524 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5525 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5526 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5527 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5528 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5529 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5530 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5531 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5532 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5533 { 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 },
5534 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5535 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5536 { 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 },
5537 { 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 },
5538 { 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 },
5539 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5540 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5541 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5542 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5543 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5544 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5547 static bool run_openattrtest(int dummy)
5549 static struct cli_state *cli1;
5550 const char *fname = "\\openattr.file";
5552 bool correct = True;
5554 unsigned int i, j, k, l;
5557 printf("starting open attr test\n");
5559 if (!torture_open_connection(&cli1, 0)) {
5563 cli_sockopt(cli1, sockops);
5565 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5566 cli_setatr(cli1, fname, 0, 0);
5567 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5569 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5570 open_attrs_table[i], FILE_SHARE_NONE,
5571 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5577 status = cli_close(cli1, fnum1);
5578 if (!NT_STATUS_IS_OK(status)) {
5579 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5583 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5584 status = cli_ntcreate(cli1, fname, 0,
5585 FILE_READ_DATA|FILE_WRITE_DATA,
5586 open_attrs_table[j],
5587 FILE_SHARE_NONE, FILE_OVERWRITE,
5589 if (!NT_STATUS_IS_OK(status)) {
5590 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5591 if (attr_results[l].num == k) {
5592 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5593 k, open_attrs_table[i],
5594 open_attrs_table[j],
5595 fname, NT_STATUS_V(status), nt_errstr(status));
5600 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5601 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5602 k, open_attrs_table[i], open_attrs_table[j],
5607 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5613 status = cli_close(cli1, fnum1);
5614 if (!NT_STATUS_IS_OK(status)) {
5615 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5619 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5620 if (!NT_STATUS_IS_OK(status)) {
5621 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5626 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5627 k, open_attrs_table[i], open_attrs_table[j], attr );
5630 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5631 if (attr_results[l].num == k) {
5632 if (attr != attr_results[l].result_attr ||
5633 open_attrs_table[i] != attr_results[l].init_attr ||
5634 open_attrs_table[j] != attr_results[l].trunc_attr) {
5635 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5636 open_attrs_table[i],
5637 open_attrs_table[j],
5639 attr_results[l].result_attr);
5649 cli_setatr(cli1, fname, 0, 0);
5650 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5652 printf("open attr test %s.\n", correct ? "passed" : "failed");
5654 if (!torture_close_connection(cli1)) {
5660 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5661 const char *name, void *state)
5663 int *matched = (int *)state;
5664 if (matched != NULL) {
5667 return NT_STATUS_OK;
5671 test directory listing speed
5673 static bool run_dirtest(int dummy)
5676 static struct cli_state *cli;
5678 struct timeval core_start;
5679 bool correct = True;
5682 printf("starting directory test\n");
5684 if (!torture_open_connection(&cli, 0)) {
5688 cli_sockopt(cli, sockops);
5691 for (i=0;i<torture_numops;i++) {
5693 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5694 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5695 fprintf(stderr,"Failed to open %s\n", fname);
5698 cli_close(cli, fnum);
5701 core_start = timeval_current();
5704 cli_list(cli, "a*.*", 0, list_fn, &matched);
5705 printf("Matched %d\n", matched);
5708 cli_list(cli, "b*.*", 0, list_fn, &matched);
5709 printf("Matched %d\n", matched);
5712 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5713 printf("Matched %d\n", matched);
5715 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5718 for (i=0;i<torture_numops;i++) {
5720 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5721 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5724 if (!torture_close_connection(cli)) {
5728 printf("finished dirtest\n");
5733 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5736 struct cli_state *pcli = (struct cli_state *)state;
5738 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5740 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5741 return NT_STATUS_OK;
5743 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5744 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5745 printf("del_fn: failed to rmdir %s\n,", fname );
5747 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5748 printf("del_fn: failed to unlink %s\n,", fname );
5750 return NT_STATUS_OK;
5755 sees what IOCTLs are supported
5757 bool torture_ioctl_test(int dummy)
5759 static struct cli_state *cli;
5760 uint16_t device, function;
5762 const char *fname = "\\ioctl.dat";
5766 if (!torture_open_connection(&cli, 0)) {
5770 printf("starting ioctl test\n");
5772 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5774 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5775 if (!NT_STATUS_IS_OK(status)) {
5776 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5780 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5781 printf("ioctl device info: %s\n", nt_errstr(status));
5783 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5784 printf("ioctl job info: %s\n", nt_errstr(status));
5786 for (device=0;device<0x100;device++) {
5787 printf("ioctl test with device = 0x%x\n", device);
5788 for (function=0;function<0x100;function++) {
5789 uint32 code = (device<<16) | function;
5791 status = cli_raw_ioctl(cli, fnum, code, &blob);
5793 if (NT_STATUS_IS_OK(status)) {
5794 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5796 data_blob_free(&blob);
5801 if (!torture_close_connection(cli)) {
5810 tries varients of chkpath
5812 bool torture_chkpath_test(int dummy)
5814 static struct cli_state *cli;
5819 if (!torture_open_connection(&cli, 0)) {
5823 printf("starting chkpath test\n");
5825 /* cleanup from an old run */
5826 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5827 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5828 cli_rmdir(cli, "\\chkpath.dir");
5830 status = cli_mkdir(cli, "\\chkpath.dir");
5831 if (!NT_STATUS_IS_OK(status)) {
5832 printf("mkdir1 failed : %s\n", nt_errstr(status));
5836 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5837 if (!NT_STATUS_IS_OK(status)) {
5838 printf("mkdir2 failed : %s\n", nt_errstr(status));
5842 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5844 if (!NT_STATUS_IS_OK(status)) {
5845 printf("open1 failed (%s)\n", nt_errstr(status));
5848 cli_close(cli, fnum);
5850 status = cli_chkpath(cli, "\\chkpath.dir");
5851 if (!NT_STATUS_IS_OK(status)) {
5852 printf("chkpath1 failed: %s\n", nt_errstr(status));
5856 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5857 if (!NT_STATUS_IS_OK(status)) {
5858 printf("chkpath2 failed: %s\n", nt_errstr(status));
5862 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5863 if (!NT_STATUS_IS_OK(status)) {
5864 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5865 NT_STATUS_NOT_A_DIRECTORY);
5867 printf("* chkpath on a file should fail\n");
5871 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5872 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5873 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5875 printf("* chkpath on a non existant file should fail\n");
5879 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5880 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5881 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5883 printf("* chkpath on a non existent component should fail\n");
5887 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5888 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5889 cli_rmdir(cli, "\\chkpath.dir");
5891 if (!torture_close_connection(cli)) {
5898 static bool run_eatest(int dummy)
5900 static struct cli_state *cli;
5901 const char *fname = "\\eatest.txt";
5902 bool correct = True;
5906 struct ea_struct *ea_list = NULL;
5907 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5910 printf("starting eatest\n");
5912 if (!torture_open_connection(&cli, 0)) {
5913 talloc_destroy(mem_ctx);
5917 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5919 status = cli_ntcreate(cli, fname, 0,
5920 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5921 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5923 if (!NT_STATUS_IS_OK(status)) {
5924 printf("open failed - %s\n", nt_errstr(status));
5925 talloc_destroy(mem_ctx);
5929 for (i = 0; i < 10; i++) {
5930 fstring ea_name, ea_val;
5932 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5933 memset(ea_val, (char)i+1, i+1);
5934 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5935 if (!NT_STATUS_IS_OK(status)) {
5936 printf("ea_set of name %s failed - %s\n", ea_name,
5938 talloc_destroy(mem_ctx);
5943 cli_close(cli, fnum);
5944 for (i = 0; i < 10; i++) {
5945 fstring ea_name, ea_val;
5947 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5948 memset(ea_val, (char)i+1, i+1);
5949 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5950 if (!NT_STATUS_IS_OK(status)) {
5951 printf("ea_set of name %s failed - %s\n", ea_name,
5953 talloc_destroy(mem_ctx);
5958 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5959 if (!NT_STATUS_IS_OK(status)) {
5960 printf("ea_get list failed - %s\n", nt_errstr(status));
5964 printf("num_eas = %d\n", (int)num_eas);
5966 if (num_eas != 20) {
5967 printf("Should be 20 EA's stored... failing.\n");
5971 for (i = 0; i < num_eas; i++) {
5972 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5973 dump_data(0, ea_list[i].value.data,
5974 ea_list[i].value.length);
5977 /* Setting EA's to zero length deletes them. Test this */
5978 printf("Now deleting all EA's - case indepenent....\n");
5981 cli_set_ea_path(cli, fname, "", "", 0);
5983 for (i = 0; i < 20; i++) {
5985 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5986 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5987 if (!NT_STATUS_IS_OK(status)) {
5988 printf("ea_set of name %s failed - %s\n", ea_name,
5990 talloc_destroy(mem_ctx);
5996 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5997 if (!NT_STATUS_IS_OK(status)) {
5998 printf("ea_get list failed - %s\n", nt_errstr(status));
6002 printf("num_eas = %d\n", (int)num_eas);
6003 for (i = 0; i < num_eas; i++) {
6004 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6005 dump_data(0, ea_list[i].value.data,
6006 ea_list[i].value.length);
6010 printf("deleting EA's failed.\n");
6014 /* Try and delete a non existant EA. */
6015 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6016 if (!NT_STATUS_IS_OK(status)) {
6017 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6022 talloc_destroy(mem_ctx);
6023 if (!torture_close_connection(cli)) {
6030 static bool run_dirtest1(int dummy)
6033 static struct cli_state *cli;
6036 bool correct = True;
6038 printf("starting directory test\n");
6040 if (!torture_open_connection(&cli, 0)) {
6044 cli_sockopt(cli, sockops);
6046 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6047 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6048 cli_rmdir(cli, "\\LISTDIR");
6049 cli_mkdir(cli, "\\LISTDIR");
6051 /* Create 1000 files and 1000 directories. */
6052 for (i=0;i<1000;i++) {
6054 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6055 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6056 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6057 fprintf(stderr,"Failed to open %s\n", fname);
6060 cli_close(cli, fnum);
6062 for (i=0;i<1000;i++) {
6064 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6065 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6066 fprintf(stderr,"Failed to open %s\n", fname);
6071 /* Now ensure that doing an old list sees both files and directories. */
6073 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6074 printf("num_seen = %d\n", num_seen );
6075 /* We should see 100 files + 1000 directories + . and .. */
6076 if (num_seen != 2002)
6079 /* Ensure if we have the "must have" bits we only see the
6083 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6084 printf("num_seen = %d\n", num_seen );
6085 if (num_seen != 1002)
6089 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6090 printf("num_seen = %d\n", num_seen );
6091 if (num_seen != 1000)
6094 /* Delete everything. */
6095 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6096 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6097 cli_rmdir(cli, "\\LISTDIR");
6100 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6101 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6102 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6105 if (!torture_close_connection(cli)) {
6109 printf("finished dirtest1\n");
6114 static bool run_error_map_extract(int dummy) {
6116 static struct cli_state *c_dos;
6117 static struct cli_state *c_nt;
6122 uint32 flgs2, errnum;
6129 /* NT-Error connection */
6131 if (!(c_nt = open_nbt_connection())) {
6135 c_nt->use_spnego = False;
6137 status = cli_negprot(c_nt);
6139 if (!NT_STATUS_IS_OK(status)) {
6140 printf("%s rejected the NT-error negprot (%s)\n", host,
6146 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6147 if (!NT_STATUS_IS_OK(status)) {
6148 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6152 /* DOS-Error connection */
6154 if (!(c_dos = open_nbt_connection())) {
6158 c_dos->use_spnego = False;
6159 c_dos->force_dos_errors = True;
6161 status = cli_negprot(c_dos);
6162 if (!NT_STATUS_IS_OK(status)) {
6163 printf("%s rejected the DOS-error negprot (%s)\n", host,
6165 cli_shutdown(c_dos);
6169 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6170 if (!NT_STATUS_IS_OK(status)) {
6171 printf("%s rejected the DOS-error initial session setup (%s)\n",
6172 host, nt_errstr(status));
6176 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6177 fstr_sprintf(user, "%X", error);
6179 status = cli_session_setup(c_nt, user,
6180 password, strlen(password),
6181 password, strlen(password),
6183 if (NT_STATUS_IS_OK(status)) {
6184 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6187 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6189 /* Case #1: 32-bit NT errors */
6190 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6191 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6193 printf("/** Dos error on NT connection! (%s) */\n",
6195 nt_status = NT_STATUS(0xc0000000);
6198 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6199 password, strlen(password),
6200 password, strlen(password),
6202 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6204 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6206 /* Case #1: 32-bit NT errors */
6207 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6208 printf("/** NT error on DOS connection! (%s) */\n",
6210 errnum = errclass = 0;
6212 cli_dos_error(c_dos, &errclass, &errnum);
6215 if (NT_STATUS_V(nt_status) != error) {
6216 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6217 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6218 get_nt_error_c_code(talloc_tos(), nt_status));
6221 printf("\t{%s,\t%s,\t%s},\n",
6222 smb_dos_err_class(errclass),
6223 smb_dos_err_name(errclass, errnum),
6224 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6229 static bool run_sesssetup_bench(int dummy)
6231 static struct cli_state *c;
6232 const char *fname = "\\file.dat";
6237 if (!torture_open_connection(&c, 0)) {
6241 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6242 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6243 FILE_DELETE_ON_CLOSE, 0, &fnum);
6244 if (!NT_STATUS_IS_OK(status)) {
6245 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6249 for (i=0; i<torture_numops; i++) {
6250 status = cli_session_setup(
6252 password, strlen(password),
6253 password, strlen(password),
6255 if (!NT_STATUS_IS_OK(status)) {
6256 d_printf("(%s) cli_session_setup failed: %s\n",
6257 __location__, nt_errstr(status));
6261 d_printf("\r%d ", (int)c->vuid);
6263 status = cli_ulogoff(c);
6264 if (!NT_STATUS_IS_OK(status)) {
6265 d_printf("(%s) cli_ulogoff failed: %s\n",
6266 __location__, nt_errstr(status));
6275 static bool subst_test(const char *str, const char *user, const char *domain,
6276 uid_t uid, gid_t gid, const char *expected)
6281 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6283 if (strcmp(subst, expected) != 0) {
6284 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6285 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6294 static void chain1_open_completion(struct tevent_req *req)
6298 status = cli_open_recv(req, &fnum);
6301 d_printf("cli_open_recv returned %s: %d\n",
6303 NT_STATUS_IS_OK(status) ? fnum : -1);
6306 static void chain1_write_completion(struct tevent_req *req)
6310 status = cli_write_andx_recv(req, &written);
6313 d_printf("cli_write_andx_recv returned %s: %d\n",
6315 NT_STATUS_IS_OK(status) ? (int)written : -1);
6318 static void chain1_close_completion(struct tevent_req *req)
6321 bool *done = (bool *)tevent_req_callback_data_void(req);
6323 status = cli_close_recv(req);
6328 d_printf("cli_close returned %s\n", nt_errstr(status));
6331 static bool run_chain1(int dummy)
6333 struct cli_state *cli1;
6334 struct event_context *evt = event_context_init(NULL);
6335 struct tevent_req *reqs[3], *smbreqs[3];
6337 const char *str = "foobar";
6340 printf("starting chain1 test\n");
6341 if (!torture_open_connection(&cli1, 0)) {
6345 cli_sockopt(cli1, sockops);
6347 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6348 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6349 if (reqs[0] == NULL) return false;
6350 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6353 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6354 (const uint8_t *)str, 0, strlen(str)+1,
6355 smbreqs, 1, &smbreqs[1]);
6356 if (reqs[1] == NULL) return false;
6357 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6359 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6360 if (reqs[2] == NULL) return false;
6361 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6363 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6364 if (!NT_STATUS_IS_OK(status)) {
6369 event_loop_once(evt);
6372 torture_close_connection(cli1);
6376 static void chain2_sesssetup_completion(struct tevent_req *req)
6379 status = cli_session_setup_guest_recv(req);
6380 d_printf("sesssetup returned %s\n", nt_errstr(status));
6383 static void chain2_tcon_completion(struct tevent_req *req)
6385 bool *done = (bool *)tevent_req_callback_data_void(req);
6387 status = cli_tcon_andx_recv(req);
6388 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6392 static bool run_chain2(int dummy)
6394 struct cli_state *cli1;
6395 struct event_context *evt = event_context_init(NULL);
6396 struct tevent_req *reqs[2], *smbreqs[2];
6400 printf("starting chain2 test\n");
6401 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6402 port_to_use, Undefined, 0);
6403 if (!NT_STATUS_IS_OK(status)) {
6407 cli_sockopt(cli1, sockops);
6409 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6411 if (reqs[0] == NULL) return false;
6412 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6414 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6415 "?????", NULL, 0, &smbreqs[1]);
6416 if (reqs[1] == NULL) return false;
6417 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6419 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6420 if (!NT_STATUS_IS_OK(status)) {
6425 event_loop_once(evt);
6428 torture_close_connection(cli1);
6433 struct torture_createdel_state {
6434 struct tevent_context *ev;
6435 struct cli_state *cli;
6438 static void torture_createdel_created(struct tevent_req *subreq);
6439 static void torture_createdel_closed(struct tevent_req *subreq);
6441 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6442 struct tevent_context *ev,
6443 struct cli_state *cli,
6446 struct tevent_req *req, *subreq;
6447 struct torture_createdel_state *state;
6449 req = tevent_req_create(mem_ctx, &state,
6450 struct torture_createdel_state);
6457 subreq = cli_ntcreate_send(
6458 state, ev, cli, name, 0,
6459 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6460 FILE_ATTRIBUTE_NORMAL,
6461 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6462 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6464 if (tevent_req_nomem(subreq, req)) {
6465 return tevent_req_post(req, ev);
6467 tevent_req_set_callback(subreq, torture_createdel_created, req);
6471 static void torture_createdel_created(struct tevent_req *subreq)
6473 struct tevent_req *req = tevent_req_callback_data(
6474 subreq, struct tevent_req);
6475 struct torture_createdel_state *state = tevent_req_data(
6476 req, struct torture_createdel_state);
6480 status = cli_ntcreate_recv(subreq, &fnum);
6481 TALLOC_FREE(subreq);
6482 if (!NT_STATUS_IS_OK(status)) {
6483 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6484 nt_errstr(status)));
6485 tevent_req_nterror(req, status);
6489 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6490 if (tevent_req_nomem(subreq, req)) {
6493 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6496 static void torture_createdel_closed(struct tevent_req *subreq)
6498 struct tevent_req *req = tevent_req_callback_data(
6499 subreq, struct tevent_req);
6502 status = cli_close_recv(subreq);
6503 if (!NT_STATUS_IS_OK(status)) {
6504 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6505 tevent_req_nterror(req, status);
6508 tevent_req_done(req);
6511 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6513 return tevent_req_simple_recv_ntstatus(req);
6516 struct torture_createdels_state {
6517 struct tevent_context *ev;
6518 struct cli_state *cli;
6519 const char *base_name;
6523 struct tevent_req **reqs;
6526 static void torture_createdels_done(struct tevent_req *subreq);
6528 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6529 struct tevent_context *ev,
6530 struct cli_state *cli,
6531 const char *base_name,
6535 struct tevent_req *req;
6536 struct torture_createdels_state *state;
6539 req = tevent_req_create(mem_ctx, &state,
6540 struct torture_createdels_state);
6546 state->base_name = talloc_strdup(state, base_name);
6547 if (tevent_req_nomem(state->base_name, req)) {
6548 return tevent_req_post(req, ev);
6550 state->num_files = MAX(num_parallel, num_files);
6552 state->received = 0;
6554 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6555 if (tevent_req_nomem(state->reqs, req)) {
6556 return tevent_req_post(req, ev);
6559 for (i=0; i<num_parallel; i++) {
6562 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6564 if (tevent_req_nomem(name, req)) {
6565 return tevent_req_post(req, ev);
6567 state->reqs[i] = torture_createdel_send(
6568 state->reqs, state->ev, state->cli, name);
6569 if (tevent_req_nomem(state->reqs[i], req)) {
6570 return tevent_req_post(req, ev);
6572 name = talloc_move(state->reqs[i], &name);
6573 tevent_req_set_callback(state->reqs[i],
6574 torture_createdels_done, req);
6580 static void torture_createdels_done(struct tevent_req *subreq)
6582 struct tevent_req *req = tevent_req_callback_data(
6583 subreq, struct tevent_req);
6584 struct torture_createdels_state *state = tevent_req_data(
6585 req, struct torture_createdels_state);
6586 size_t num_parallel = talloc_array_length(state->reqs);
6591 status = torture_createdel_recv(subreq);
6592 if (!NT_STATUS_IS_OK(status)){
6593 DEBUG(10, ("torture_createdel_recv returned %s\n",
6594 nt_errstr(status)));
6595 TALLOC_FREE(subreq);
6596 tevent_req_nterror(req, status);
6600 for (i=0; i<num_parallel; i++) {
6601 if (subreq == state->reqs[i]) {
6605 if (i == num_parallel) {
6606 DEBUG(10, ("received something we did not send\n"));
6607 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6610 TALLOC_FREE(state->reqs[i]);
6612 if (state->sent >= state->num_files) {
6613 tevent_req_done(req);
6617 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6619 if (tevent_req_nomem(name, req)) {
6622 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6624 if (tevent_req_nomem(state->reqs[i], req)) {
6627 name = talloc_move(state->reqs[i], &name);
6628 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6632 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6634 return tevent_req_simple_recv_ntstatus(req);
6637 struct swallow_notify_state {
6638 struct tevent_context *ev;
6639 struct cli_state *cli;
6641 uint32_t completion_filter;
6643 bool (*fn)(uint32_t action, const char *name, void *priv);
6647 static void swallow_notify_done(struct tevent_req *subreq);
6649 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6650 struct tevent_context *ev,
6651 struct cli_state *cli,
6653 uint32_t completion_filter,
6655 bool (*fn)(uint32_t action,
6660 struct tevent_req *req, *subreq;
6661 struct swallow_notify_state *state;
6663 req = tevent_req_create(mem_ctx, &state,
6664 struct swallow_notify_state);
6671 state->completion_filter = completion_filter;
6672 state->recursive = recursive;
6676 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6677 0xffff, state->completion_filter,
6679 if (tevent_req_nomem(subreq, req)) {
6680 return tevent_req_post(req, ev);
6682 tevent_req_set_callback(subreq, swallow_notify_done, req);
6686 static void swallow_notify_done(struct tevent_req *subreq)
6688 struct tevent_req *req = tevent_req_callback_data(
6689 subreq, struct tevent_req);
6690 struct swallow_notify_state *state = tevent_req_data(
6691 req, struct swallow_notify_state);
6693 uint32_t i, num_changes;
6694 struct notify_change *changes;
6696 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6697 TALLOC_FREE(subreq);
6698 if (!NT_STATUS_IS_OK(status)) {
6699 DEBUG(10, ("cli_notify_recv returned %s\n",
6700 nt_errstr(status)));
6701 tevent_req_nterror(req, status);
6705 for (i=0; i<num_changes; i++) {
6706 state->fn(changes[i].action, changes[i].name, state->priv);
6708 TALLOC_FREE(changes);
6710 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6711 0xffff, state->completion_filter,
6713 if (tevent_req_nomem(subreq, req)) {
6716 tevent_req_set_callback(subreq, swallow_notify_done, req);
6719 static bool print_notifies(uint32_t action, const char *name, void *priv)
6721 if (DEBUGLEVEL > 5) {
6722 d_printf("%d %s\n", (int)action, name);
6727 static void notify_bench_done(struct tevent_req *req)
6729 int *num_finished = (int *)tevent_req_callback_data_void(req);
6733 static bool run_notify_bench(int dummy)
6735 const char *dname = "\\notify-bench";
6736 struct tevent_context *ev;
6739 struct tevent_req *req1;
6740 struct tevent_req *req2 = NULL;
6741 int i, num_unc_names;
6742 int num_finished = 0;
6744 printf("starting notify-bench test\n");
6746 if (use_multishare_conn) {
6748 unc_list = file_lines_load(multishare_conn_fname,
6749 &num_unc_names, 0, NULL);
6750 if (!unc_list || num_unc_names <= 0) {
6751 d_printf("Failed to load unc names list from '%s'\n",
6752 multishare_conn_fname);
6755 TALLOC_FREE(unc_list);
6760 ev = tevent_context_init(talloc_tos());
6762 d_printf("tevent_context_init failed\n");
6766 for (i=0; i<num_unc_names; i++) {
6767 struct cli_state *cli;
6770 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6772 if (base_fname == NULL) {
6776 if (!torture_open_connection(&cli, i)) {
6780 status = cli_ntcreate(cli, dname, 0,
6781 MAXIMUM_ALLOWED_ACCESS,
6782 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6784 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6787 if (!NT_STATUS_IS_OK(status)) {
6788 d_printf("Could not create %s: %s\n", dname,
6793 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6794 FILE_NOTIFY_CHANGE_FILE_NAME |
6795 FILE_NOTIFY_CHANGE_DIR_NAME |
6796 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6797 FILE_NOTIFY_CHANGE_LAST_WRITE,
6798 false, print_notifies, NULL);
6800 d_printf("Could not create notify request\n");
6804 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6805 base_fname, 10, torture_numops);
6807 d_printf("Could not create createdels request\n");
6810 TALLOC_FREE(base_fname);
6812 tevent_req_set_callback(req2, notify_bench_done,
6816 while (num_finished < num_unc_names) {
6818 ret = tevent_loop_once(ev);
6820 d_printf("tevent_loop_once failed\n");
6825 if (!tevent_req_poll(req2, ev)) {
6826 d_printf("tevent_req_poll failed\n");
6829 status = torture_createdels_recv(req2);
6830 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6835 static bool run_mangle1(int dummy)
6837 struct cli_state *cli;
6838 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6842 time_t change_time, access_time, write_time;
6846 printf("starting mangle1 test\n");
6847 if (!torture_open_connection(&cli, 0)) {
6851 cli_sockopt(cli, sockops);
6853 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6854 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6856 if (!NT_STATUS_IS_OK(status)) {
6857 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6860 cli_close(cli, fnum);
6862 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6863 if (!NT_STATUS_IS_OK(status)) {
6864 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6868 d_printf("alt_name: %s\n", alt_name);
6870 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6871 if (!NT_STATUS_IS_OK(status)) {
6872 d_printf("cli_open(%s) failed: %s\n", alt_name,
6876 cli_close(cli, fnum);
6878 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6879 &write_time, &size, &mode);
6880 if (!NT_STATUS_IS_OK(status)) {
6881 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6889 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6891 size_t *to_pull = (size_t *)priv;
6892 size_t thistime = *to_pull;
6894 thistime = MIN(thistime, n);
6895 if (thistime == 0) {
6899 memset(buf, 0, thistime);
6900 *to_pull -= thistime;
6904 static bool run_windows_write(int dummy)
6906 struct cli_state *cli1;
6910 const char *fname = "\\writetest.txt";
6911 struct timeval start_time;
6916 printf("starting windows_write test\n");
6917 if (!torture_open_connection(&cli1, 0)) {
6921 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6922 if (!NT_STATUS_IS_OK(status)) {
6923 printf("open failed (%s)\n", nt_errstr(status));
6927 cli_sockopt(cli1, sockops);
6929 start_time = timeval_current();
6931 for (i=0; i<torture_numops; i++) {
6933 off_t start = i * torture_blocksize;
6934 size_t to_pull = torture_blocksize - 1;
6936 status = cli_writeall(cli1, fnum, 0, &c,
6937 start + torture_blocksize - 1, 1, NULL);
6938 if (!NT_STATUS_IS_OK(status)) {
6939 printf("cli_write failed: %s\n", nt_errstr(status));
6943 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6944 null_source, &to_pull);
6945 if (!NT_STATUS_IS_OK(status)) {
6946 printf("cli_push returned: %s\n", nt_errstr(status));
6951 seconds = timeval_elapsed(&start_time);
6952 kbytes = (double)torture_blocksize * torture_numops;
6955 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6956 (double)seconds, (int)(kbytes/seconds));
6960 cli_close(cli1, fnum);
6961 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6962 torture_close_connection(cli1);
6966 static bool run_cli_echo(int dummy)
6968 struct cli_state *cli;
6971 printf("starting cli_echo test\n");
6972 if (!torture_open_connection(&cli, 0)) {
6975 cli_sockopt(cli, sockops);
6977 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6979 d_printf("cli_echo returned %s\n", nt_errstr(status));
6981 torture_close_connection(cli);
6982 return NT_STATUS_IS_OK(status);
6985 static bool run_uid_regression_test(int dummy)
6987 static struct cli_state *cli;
6990 bool correct = True;
6993 printf("starting uid regression test\n");
6995 if (!torture_open_connection(&cli, 0)) {
6999 cli_sockopt(cli, sockops);
7001 /* Ok - now save then logoff our current user. */
7002 old_vuid = cli->vuid;
7004 status = cli_ulogoff(cli);
7005 if (!NT_STATUS_IS_OK(status)) {
7006 d_printf("(%s) cli_ulogoff failed: %s\n",
7007 __location__, nt_errstr(status));
7012 cli->vuid = old_vuid;
7014 /* Try an operation. */
7015 status = cli_mkdir(cli, "\\uid_reg_test");
7016 if (NT_STATUS_IS_OK(status)) {
7017 d_printf("(%s) cli_mkdir succeeded\n",
7022 /* Should be bad uid. */
7023 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7024 NT_STATUS_USER_SESSION_DELETED)) {
7030 old_cnum = cli->cnum;
7032 /* Now try a SMBtdis with the invald vuid set to zero. */
7035 /* This should succeed. */
7036 status = cli_tdis(cli);
7038 if (NT_STATUS_IS_OK(status)) {
7039 d_printf("First tdis with invalid vuid should succeed.\n");
7041 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7046 cli->vuid = old_vuid;
7047 cli->cnum = old_cnum;
7049 /* This should fail. */
7050 status = cli_tdis(cli);
7051 if (NT_STATUS_IS_OK(status)) {
7052 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7056 /* Should be bad tid. */
7057 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7058 NT_STATUS_NETWORK_NAME_DELETED)) {
7064 cli_rmdir(cli, "\\uid_reg_test");
7073 static const char *illegal_chars = "*\\/?<>|\":";
7074 static char force_shortname_chars[] = " +,.[];=\177";
7076 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7077 const char *mask, void *state)
7079 struct cli_state *pcli = (struct cli_state *)state;
7081 NTSTATUS status = NT_STATUS_OK;
7083 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7085 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7086 return NT_STATUS_OK;
7088 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7089 status = cli_rmdir(pcli, fname);
7090 if (!NT_STATUS_IS_OK(status)) {
7091 printf("del_fn: failed to rmdir %s\n,", fname );
7094 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7095 if (!NT_STATUS_IS_OK(status)) {
7096 printf("del_fn: failed to unlink %s\n,", fname );
7108 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7109 const char *name, void *state)
7111 struct sn_state *s = (struct sn_state *)state;
7115 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7116 i, finfo->name, finfo->short_name);
7119 if (strchr(force_shortname_chars, i)) {
7120 if (!finfo->short_name) {
7121 /* Shortname not created when it should be. */
7122 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7123 __location__, finfo->name, i);
7126 } else if (finfo->short_name){
7127 /* Shortname created when it should not be. */
7128 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7129 __location__, finfo->short_name, finfo->name);
7133 return NT_STATUS_OK;
7136 static bool run_shortname_test(int dummy)
7138 static struct cli_state *cli;
7139 bool correct = True;
7145 printf("starting shortname test\n");
7147 if (!torture_open_connection(&cli, 0)) {
7151 cli_sockopt(cli, sockops);
7153 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7154 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7155 cli_rmdir(cli, "\\shortname");
7157 status = cli_mkdir(cli, "\\shortname");
7158 if (!NT_STATUS_IS_OK(status)) {
7159 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7160 __location__, nt_errstr(status));
7165 strlcpy(fname, "\\shortname\\", sizeof(fname));
7166 strlcat(fname, "test .txt", sizeof(fname));
7170 for (i = 32; i < 128; i++) {
7171 uint16_t fnum = (uint16_t)-1;
7175 if (strchr(illegal_chars, i)) {
7180 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7181 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7182 if (!NT_STATUS_IS_OK(status)) {
7183 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7184 __location__, fname, nt_errstr(status));
7188 cli_close(cli, fnum);
7191 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7193 if (s.matched != 1) {
7194 d_printf("(%s) failed to list %s: %s\n",
7195 __location__, fname, cli_errstr(cli));
7200 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7201 if (!NT_STATUS_IS_OK(status)) {
7202 d_printf("(%s) failed to delete %s: %s\n",
7203 __location__, fname, nt_errstr(status));
7216 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7217 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7218 cli_rmdir(cli, "\\shortname");
7219 torture_close_connection(cli);
7223 static void pagedsearch_cb(struct tevent_req *req)
7226 struct tldap_message *msg;
7229 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7230 if (rc != TLDAP_SUCCESS) {
7231 d_printf("tldap_search_paged_recv failed: %s\n",
7232 tldap_err2string(rc));
7235 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7239 if (!tldap_entry_dn(msg, &dn)) {
7240 d_printf("tldap_entry_dn failed\n");
7243 d_printf("%s\n", dn);
7247 static bool run_tldap(int dummy)
7249 struct tldap_context *ld;
7252 struct sockaddr_storage addr;
7253 struct tevent_context *ev;
7254 struct tevent_req *req;
7258 if (!resolve_name(host, &addr, 0, false)) {
7259 d_printf("could not find host %s\n", host);
7262 status = open_socket_out(&addr, 389, 9999, &fd);
7263 if (!NT_STATUS_IS_OK(status)) {
7264 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7268 ld = tldap_context_create(talloc_tos(), fd);
7271 d_printf("tldap_context_create failed\n");
7275 rc = tldap_fetch_rootdse(ld);
7276 if (rc != TLDAP_SUCCESS) {
7277 d_printf("tldap_fetch_rootdse failed: %s\n",
7278 tldap_errstr(talloc_tos(), ld, rc));
7282 basedn = tldap_talloc_single_attribute(
7283 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7284 if (basedn == NULL) {
7285 d_printf("no defaultNamingContext\n");
7288 d_printf("defaultNamingContext: %s\n", basedn);
7290 ev = tevent_context_init(talloc_tos());
7292 d_printf("tevent_context_init failed\n");
7296 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7297 TLDAP_SCOPE_SUB, "(objectclass=*)",
7299 NULL, 0, NULL, 0, 0, 0, 0, 5);
7301 d_printf("tldap_search_paged_send failed\n");
7304 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7306 tevent_req_poll(req, ev);
7310 /* test search filters against rootDSE */
7311 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7312 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7314 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7315 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7316 talloc_tos(), NULL, NULL);
7317 if (rc != TLDAP_SUCCESS) {
7318 d_printf("tldap_search with complex filter failed: %s\n",
7319 tldap_errstr(talloc_tos(), ld, rc));
7327 /* Torture test to ensure no regression of :
7328 https://bugzilla.samba.org/show_bug.cgi?id=7084
7331 static bool run_dir_createtime(int dummy)
7333 struct cli_state *cli;
7334 const char *dname = "\\testdir";
7335 const char *fname = "\\testdir\\testfile";
7337 struct timespec create_time;
7338 struct timespec create_time1;
7342 if (!torture_open_connection(&cli, 0)) {
7346 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7347 cli_rmdir(cli, dname);
7349 status = cli_mkdir(cli, dname);
7350 if (!NT_STATUS_IS_OK(status)) {
7351 printf("mkdir failed: %s\n", nt_errstr(status));
7355 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7357 if (!NT_STATUS_IS_OK(status)) {
7358 printf("cli_qpathinfo2 returned %s\n",
7363 /* Sleep 3 seconds, then create a file. */
7366 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7368 if (!NT_STATUS_IS_OK(status)) {
7369 printf("cli_open failed: %s\n", nt_errstr(status));
7373 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7375 if (!NT_STATUS_IS_OK(status)) {
7376 printf("cli_qpathinfo2 (2) returned %s\n",
7381 if (timespec_compare(&create_time1, &create_time)) {
7382 printf("run_dir_createtime: create time was updated (error)\n");
7384 printf("run_dir_createtime: create time was not updated (correct)\n");
7390 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7391 cli_rmdir(cli, dname);
7392 if (!torture_close_connection(cli)) {
7399 static bool run_streamerror(int dummy)
7401 struct cli_state *cli;
7402 const char *dname = "\\testdir";
7403 const char *streamname =
7404 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7406 time_t change_time, access_time, write_time;
7408 uint16_t mode, fnum;
7411 if (!torture_open_connection(&cli, 0)) {
7415 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7416 cli_rmdir(cli, dname);
7418 status = cli_mkdir(cli, dname);
7419 if (!NT_STATUS_IS_OK(status)) {
7420 printf("mkdir failed: %s\n", nt_errstr(status));
7424 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7426 status = cli_nt_error(cli);
7428 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7429 printf("pathinfo returned %s, expected "
7430 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7435 status = cli_ntcreate(cli, streamname, 0x16,
7436 FILE_READ_DATA|FILE_READ_EA|
7437 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7438 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7439 FILE_OPEN, 0, 0, &fnum);
7441 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7442 printf("ntcreate returned %s, expected "
7443 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7449 cli_rmdir(cli, dname);
7453 static bool run_local_substitute(int dummy)
7457 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7458 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7459 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7460 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7461 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7462 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7463 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7464 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7466 /* Different captialization rules in sub_basic... */
7468 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7474 static bool run_local_base64(int dummy)
7479 for (i=1; i<2000; i++) {
7480 DATA_BLOB blob1, blob2;
7483 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7485 generate_random_buffer(blob1.data, blob1.length);
7487 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7489 d_fprintf(stderr, "base64_encode_data_blob failed "
7490 "for %d bytes\n", i);
7493 blob2 = base64_decode_data_blob(b64);
7496 if (data_blob_cmp(&blob1, &blob2)) {
7497 d_fprintf(stderr, "data_blob_cmp failed for %d "
7501 TALLOC_FREE(blob1.data);
7502 data_blob_free(&blob2);
7507 static bool run_local_gencache(int dummy)
7513 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7514 d_printf("%s: gencache_set() failed\n", __location__);
7518 if (!gencache_get("foo", NULL, NULL)) {
7519 d_printf("%s: gencache_get() failed\n", __location__);
7523 if (!gencache_get("foo", &val, &tm)) {
7524 d_printf("%s: gencache_get() failed\n", __location__);
7528 if (strcmp(val, "bar") != 0) {
7529 d_printf("%s: gencache_get() returned %s, expected %s\n",
7530 __location__, val, "bar");
7537 if (!gencache_del("foo")) {
7538 d_printf("%s: gencache_del() failed\n", __location__);
7541 if (gencache_del("foo")) {
7542 d_printf("%s: second gencache_del() succeeded\n",
7547 if (gencache_get("foo", &val, &tm)) {
7548 d_printf("%s: gencache_get() on deleted entry "
7549 "succeeded\n", __location__);
7553 blob = data_blob_string_const_null("bar");
7554 tm = time(NULL) + 60;
7556 if (!gencache_set_data_blob("foo", &blob, tm)) {
7557 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7561 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7562 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7566 if (strcmp((const char *)blob.data, "bar") != 0) {
7567 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7568 __location__, (const char *)blob.data, "bar");
7569 data_blob_free(&blob);
7573 data_blob_free(&blob);
7575 if (!gencache_del("foo")) {
7576 d_printf("%s: gencache_del() failed\n", __location__);
7579 if (gencache_del("foo")) {
7580 d_printf("%s: second gencache_del() succeeded\n",
7585 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7586 d_printf("%s: gencache_get_data_blob() on deleted entry "
7587 "succeeded\n", __location__);
7594 static bool rbt_testval(struct db_context *db, const char *key,
7597 struct db_record *rec;
7598 TDB_DATA data = string_tdb_data(value);
7602 rec = db->fetch_locked(db, db, string_tdb_data(key));
7604 d_fprintf(stderr, "fetch_locked failed\n");
7607 status = rec->store(rec, data, 0);
7608 if (!NT_STATUS_IS_OK(status)) {
7609 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7614 rec = db->fetch_locked(db, db, string_tdb_data(key));
7616 d_fprintf(stderr, "second fetch_locked failed\n");
7619 if ((rec->value.dsize != data.dsize)
7620 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7621 d_fprintf(stderr, "Got wrong data back\n");
7631 static bool run_local_rbtree(int dummy)
7633 struct db_context *db;
7637 db = db_open_rbt(NULL);
7640 d_fprintf(stderr, "db_open_rbt failed\n");
7644 for (i=0; i<1000; i++) {
7647 if (asprintf(&key, "key%ld", random()) == -1) {
7650 if (asprintf(&value, "value%ld", random()) == -1) {
7655 if (!rbt_testval(db, key, value)) {
7662 if (asprintf(&value, "value%ld", random()) == -1) {
7667 if (!rbt_testval(db, key, value)) {
7686 local test for character set functions
7688 This is a very simple test for the functionality in convert_string_error()
7690 static bool run_local_convert_string(int dummy)
7692 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7693 const char *test_strings[2] = { "March", "M\303\244rz" };
7697 for (i=0; i<2; i++) {
7698 const char *str = test_strings[i];
7699 int len = strlen(str);
7700 size_t converted_size;
7703 memset(dst, 'X', sizeof(dst));
7705 /* first try with real source length */
7706 ret = convert_string_error(CH_UNIX, CH_UTF8,
7711 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7715 if (converted_size != len) {
7716 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7717 str, len, (int)converted_size);
7721 if (strncmp(str, dst, converted_size) != 0) {
7722 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7726 if (strlen(str) != converted_size) {
7727 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7728 (int)strlen(str), (int)converted_size);
7732 if (dst[converted_size] != 'X') {
7733 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7737 /* now with srclen==-1, this causes the nul to be
7739 ret = convert_string_error(CH_UNIX, CH_UTF8,
7744 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7748 if (converted_size != len+1) {
7749 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7750 str, len, (int)converted_size);
7754 if (strncmp(str, dst, converted_size) != 0) {
7755 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7759 if (len+1 != converted_size) {
7760 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7761 len+1, (int)converted_size);
7765 if (dst[converted_size] != 'X') {
7766 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7773 TALLOC_FREE(tmp_ctx);
7776 TALLOC_FREE(tmp_ctx);
7781 struct talloc_dict_test {
7785 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7787 int *count = (int *)priv;
7792 static bool run_local_talloc_dict(int dummy)
7794 struct talloc_dict *dict;
7795 struct talloc_dict_test *t;
7798 dict = talloc_dict_init(talloc_tos());
7803 t = talloc(talloc_tos(), struct talloc_dict_test);
7810 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7815 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7828 static bool run_local_string_to_sid(int dummy) {
7831 if (string_to_sid(&sid, "S--1-5-32-545")) {
7832 printf("allowing S--1-5-32-545\n");
7835 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7836 printf("allowing S-1-5-32-+545\n");
7839 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")) {
7840 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7843 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7844 printf("allowing S-1-5-32-545-abc\n");
7847 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7848 printf("could not parse S-1-5-32-545\n");
7851 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7852 printf("mis-parsed S-1-5-32-545 as %s\n",
7853 sid_string_tos(&sid));
7859 static bool run_local_binary_to_sid(int dummy) {
7860 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7861 static const char good_binary_sid[] = {
7862 0x1, /* revision number */
7864 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7865 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7866 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7867 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7868 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7869 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7870 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7871 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7872 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7873 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7874 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7879 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7882 static const char long_binary_sid[] = {
7883 0x1, /* revision number */
7885 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7886 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7890 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7891 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7892 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7893 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7894 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7895 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7896 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7902 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7903 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7906 static const char long_binary_sid2[] = {
7907 0x1, /* revision number */
7909 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7910 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7914 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7915 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7916 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7917 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7918 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7919 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7920 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7938 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7939 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7940 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7941 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7944 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7947 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7950 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7956 /* Split a path name into filename and stream name components. Canonicalise
7957 * such that an implicit $DATA token is always explicit.
7959 * The "specification" of this function can be found in the
7960 * run_local_stream_name() function in torture.c, I've tried those
7961 * combinations against a W2k3 server.
7964 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7965 char **pbase, char **pstream)
7968 char *stream = NULL;
7969 char *sname; /* stream name */
7970 const char *stype; /* stream type */
7972 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7974 sname = strchr_m(fname, ':');
7976 if (lp_posix_pathnames() || (sname == NULL)) {
7977 if (pbase != NULL) {
7978 base = talloc_strdup(mem_ctx, fname);
7979 NT_STATUS_HAVE_NO_MEMORY(base);
7984 if (pbase != NULL) {
7985 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7986 NT_STATUS_HAVE_NO_MEMORY(base);
7991 stype = strchr_m(sname, ':');
7993 if (stype == NULL) {
7994 sname = talloc_strdup(mem_ctx, sname);
7998 if (strcasecmp_m(stype, ":$DATA") != 0) {
8000 * If there is an explicit stream type, so far we only
8001 * allow $DATA. Is there anything else allowed? -- vl
8003 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8005 return NT_STATUS_OBJECT_NAME_INVALID;
8007 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8011 if (sname == NULL) {
8013 return NT_STATUS_NO_MEMORY;
8016 if (sname[0] == '\0') {
8018 * no stream name, so no stream
8023 if (pstream != NULL) {
8024 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8025 if (stream == NULL) {
8028 return NT_STATUS_NO_MEMORY;
8031 * upper-case the type field
8033 strupper_m(strchr_m(stream, ':')+1);
8037 if (pbase != NULL) {
8040 if (pstream != NULL) {
8043 return NT_STATUS_OK;
8046 static bool test_stream_name(const char *fname, const char *expected_base,
8047 const char *expected_stream,
8048 NTSTATUS expected_status)
8052 char *stream = NULL;
8054 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8055 if (!NT_STATUS_EQUAL(status, expected_status)) {
8059 if (!NT_STATUS_IS_OK(status)) {
8063 if (base == NULL) goto error;
8065 if (strcmp(expected_base, base) != 0) goto error;
8067 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8068 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8070 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8074 TALLOC_FREE(stream);
8078 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8079 fname, expected_base ? expected_base : "<NULL>",
8080 expected_stream ? expected_stream : "<NULL>",
8081 nt_errstr(expected_status));
8082 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8083 base ? base : "<NULL>", stream ? stream : "<NULL>",
8086 TALLOC_FREE(stream);
8090 static bool run_local_stream_name(int dummy)
8094 ret &= test_stream_name(
8095 "bla", "bla", NULL, NT_STATUS_OK);
8096 ret &= test_stream_name(
8097 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8098 ret &= test_stream_name(
8099 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8100 ret &= test_stream_name(
8101 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8102 ret &= test_stream_name(
8103 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8104 ret &= test_stream_name(
8105 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8106 ret &= test_stream_name(
8107 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8108 ret &= test_stream_name(
8109 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8114 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8116 if (a.length != b.length) {
8117 printf("a.length=%d != b.length=%d\n",
8118 (int)a.length, (int)b.length);
8121 if (memcmp(a.data, b.data, a.length) != 0) {
8122 printf("a.data and b.data differ\n");
8128 static bool run_local_memcache(int dummy)
8130 struct memcache *cache;
8132 DATA_BLOB d1, d2, d3;
8133 DATA_BLOB v1, v2, v3;
8135 TALLOC_CTX *mem_ctx;
8137 size_t size1, size2;
8140 cache = memcache_init(NULL, 100);
8142 if (cache == NULL) {
8143 printf("memcache_init failed\n");
8147 d1 = data_blob_const("d1", 2);
8148 d2 = data_blob_const("d2", 2);
8149 d3 = data_blob_const("d3", 2);
8151 k1 = data_blob_const("d1", 2);
8152 k2 = data_blob_const("d2", 2);
8154 memcache_add(cache, STAT_CACHE, k1, d1);
8155 memcache_add(cache, GETWD_CACHE, k2, d2);
8157 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8158 printf("could not find k1\n");
8161 if (!data_blob_equal(d1, v1)) {
8165 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8166 printf("could not find k2\n");
8169 if (!data_blob_equal(d2, v2)) {
8173 memcache_add(cache, STAT_CACHE, k1, d3);
8175 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8176 printf("could not find replaced k1\n");
8179 if (!data_blob_equal(d3, v3)) {
8183 memcache_add(cache, GETWD_CACHE, k1, d1);
8185 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8186 printf("Did find k2, should have been purged\n");
8192 cache = memcache_init(NULL, 0);
8194 mem_ctx = talloc_init("foo");
8196 str1 = talloc_strdup(mem_ctx, "string1");
8197 str2 = talloc_strdup(mem_ctx, "string2");
8199 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8200 data_blob_string_const("torture"), &str1);
8201 size1 = talloc_total_size(cache);
8203 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8204 data_blob_string_const("torture"), &str2);
8205 size2 = talloc_total_size(cache);
8207 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8209 if (size2 > size1) {
8210 printf("memcache leaks memory!\n");
8220 static void wbclient_done(struct tevent_req *req)
8223 struct winbindd_response *wb_resp;
8224 int *i = (int *)tevent_req_callback_data_void(req);
8226 wbc_err = wb_trans_recv(req, req, &wb_resp);
8229 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8232 static bool run_local_wbclient(int dummy)
8234 struct event_context *ev;
8235 struct wb_context **wb_ctx;
8236 struct winbindd_request wb_req;
8237 bool result = false;
8240 BlockSignals(True, SIGPIPE);
8242 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8247 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8248 if (wb_ctx == NULL) {
8252 ZERO_STRUCT(wb_req);
8253 wb_req.cmd = WINBINDD_PING;
8255 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8257 for (i=0; i<nprocs; i++) {
8258 wb_ctx[i] = wb_context_init(ev, NULL);
8259 if (wb_ctx[i] == NULL) {
8262 for (j=0; j<torture_numops; j++) {
8263 struct tevent_req *req;
8264 req = wb_trans_send(ev, ev, wb_ctx[i],
8265 (j % 2) == 0, &wb_req);
8269 tevent_req_set_callback(req, wbclient_done, &i);
8275 while (i < nprocs * torture_numops) {
8276 event_loop_once(ev);
8285 static void getaddrinfo_finished(struct tevent_req *req)
8287 char *name = (char *)tevent_req_callback_data_void(req);
8288 struct addrinfo *ainfo;
8291 res = getaddrinfo_recv(req, &ainfo);
8293 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8296 d_printf("gai(%s) succeeded\n", name);
8297 freeaddrinfo(ainfo);
8300 static bool run_getaddrinfo_send(int dummy)
8302 TALLOC_CTX *frame = talloc_stackframe();
8303 struct fncall_context *ctx;
8304 struct tevent_context *ev;
8305 bool result = false;
8306 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8307 "www.slashdot.org", "heise.de" };
8308 struct tevent_req *reqs[4];
8311 ev = event_context_init(frame);
8316 ctx = fncall_context_init(frame, 4);
8318 for (i=0; i<ARRAY_SIZE(names); i++) {
8319 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8321 if (reqs[i] == NULL) {
8324 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8325 discard_const_p(void, names[i]));
8328 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8329 tevent_loop_once(ev);
8338 static bool dbtrans_inc(struct db_context *db)
8340 struct db_record *rec;
8345 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8347 printf(__location__ "fetch_lock failed\n");
8351 if (rec->value.dsize != sizeof(uint32_t)) {
8352 printf(__location__ "value.dsize = %d\n",
8353 (int)rec->value.dsize);
8357 val = (uint32_t *)rec->value.dptr;
8360 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8363 if (!NT_STATUS_IS_OK(status)) {
8364 printf(__location__ "store failed: %s\n",
8375 static bool run_local_dbtrans(int dummy)
8377 struct db_context *db;
8378 struct db_record *rec;
8383 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8384 O_RDWR|O_CREAT, 0600);
8386 printf("Could not open transtest.db\n");
8390 res = db->transaction_start(db);
8392 printf(__location__ "transaction_start failed\n");
8396 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8398 printf(__location__ "fetch_lock failed\n");
8402 if (rec->value.dptr == NULL) {
8404 status = rec->store(
8405 rec, make_tdb_data((uint8_t *)&initial,
8408 if (!NT_STATUS_IS_OK(status)) {
8409 printf(__location__ "store returned %s\n",
8417 res = db->transaction_commit(db);
8419 printf(__location__ "transaction_commit failed\n");
8427 res = db->transaction_start(db);
8429 printf(__location__ "transaction_start failed\n");
8433 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8434 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8438 for (i=0; i<10; i++) {
8439 if (!dbtrans_inc(db)) {
8444 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8445 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8449 if (val2 != val + 10) {
8450 printf(__location__ "val=%d, val2=%d\n",
8451 (int)val, (int)val2);
8455 printf("val2=%d\r", val2);
8457 res = db->transaction_commit(db);
8459 printf(__location__ "transaction_commit failed\n");
8469 * Just a dummy test to be run under a debugger. There's no real way
8470 * to inspect the tevent_select specific function from outside of
8474 static bool run_local_tevent_select(int dummy)
8476 struct tevent_context *ev;
8477 struct tevent_fd *fd1, *fd2;
8478 bool result = false;
8480 ev = tevent_context_init_byname(NULL, "select");
8482 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8486 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8488 d_fprintf(stderr, "tevent_add_fd failed\n");
8491 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8493 d_fprintf(stderr, "tevent_add_fd failed\n");
8498 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8500 d_fprintf(stderr, "tevent_add_fd failed\n");
8510 static double create_procs(bool (*fn)(int), bool *result)
8513 volatile pid_t *child_status;
8514 volatile bool *child_status_out;
8517 struct timeval start;
8521 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8522 if (!child_status) {
8523 printf("Failed to setup shared memory\n");
8527 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8528 if (!child_status_out) {
8529 printf("Failed to setup result status shared memory\n");
8533 for (i = 0; i < nprocs; i++) {
8534 child_status[i] = 0;
8535 child_status_out[i] = True;
8538 start = timeval_current();
8540 for (i=0;i<nprocs;i++) {
8543 pid_t mypid = getpid();
8544 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8546 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8549 if (torture_open_connection(¤t_cli, i)) break;
8551 printf("pid %d failed to start\n", (int)getpid());
8557 child_status[i] = getpid();
8559 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8561 child_status_out[i] = fn(i);
8568 for (i=0;i<nprocs;i++) {
8569 if (child_status[i]) synccount++;
8571 if (synccount == nprocs) break;
8573 } while (timeval_elapsed(&start) < 30);
8575 if (synccount != nprocs) {
8576 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8578 return timeval_elapsed(&start);
8581 /* start the client load */
8582 start = timeval_current();
8584 for (i=0;i<nprocs;i++) {
8585 child_status[i] = 0;
8588 printf("%d clients started\n", nprocs);
8590 for (i=0;i<nprocs;i++) {
8591 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8596 for (i=0;i<nprocs;i++) {
8597 if (!child_status_out[i]) {
8601 return timeval_elapsed(&start);
8604 #define FLAG_MULTIPROC 1
8611 {"FDPASS", run_fdpasstest, 0},
8612 {"LOCK1", run_locktest1, 0},
8613 {"LOCK2", run_locktest2, 0},
8614 {"LOCK3", run_locktest3, 0},
8615 {"LOCK4", run_locktest4, 0},
8616 {"LOCK5", run_locktest5, 0},
8617 {"LOCK6", run_locktest6, 0},
8618 {"LOCK7", run_locktest7, 0},
8619 {"LOCK8", run_locktest8, 0},
8620 {"LOCK9", run_locktest9, 0},
8621 {"UNLINK", run_unlinktest, 0},
8622 {"BROWSE", run_browsetest, 0},
8623 {"ATTR", run_attrtest, 0},
8624 {"TRANS2", run_trans2test, 0},
8625 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8626 {"TORTURE",run_torture, FLAG_MULTIPROC},
8627 {"RANDOMIPC", run_randomipc, 0},
8628 {"NEGNOWAIT", run_negprot_nowait, 0},
8629 {"NBENCH", run_nbench, 0},
8630 {"NBENCH2", run_nbench2, 0},
8631 {"OPLOCK1", run_oplock1, 0},
8632 {"OPLOCK2", run_oplock2, 0},
8633 {"OPLOCK4", run_oplock4, 0},
8634 {"DIR", run_dirtest, 0},
8635 {"DIR1", run_dirtest1, 0},
8636 {"DIR-CREATETIME", run_dir_createtime, 0},
8637 {"DENY1", torture_denytest1, 0},
8638 {"DENY2", torture_denytest2, 0},
8639 {"TCON", run_tcon_test, 0},
8640 {"TCONDEV", run_tcon_devtype_test, 0},
8641 {"RW1", run_readwritetest, 0},
8642 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8643 {"RW3", run_readwritelarge, 0},
8644 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8645 {"OPEN", run_opentest, 0},
8646 {"POSIX", run_simple_posix_open_test, 0},
8647 {"POSIX-APPEND", run_posix_append, 0},
8648 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8649 {"ASYNC-ECHO", run_async_echo, 0},
8650 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8651 { "SHORTNAME-TEST", run_shortname_test, 0},
8652 { "ADDRCHANGE", run_addrchange, 0},
8654 {"OPENATTR", run_openattrtest, 0},
8656 {"XCOPY", run_xcopy, 0},
8657 {"RENAME", run_rename, 0},
8658 {"DELETE", run_deletetest, 0},
8659 {"DELETE-LN", run_deletetest_ln, 0},
8660 {"PROPERTIES", run_properties, 0},
8661 {"MANGLE", torture_mangle, 0},
8662 {"MANGLE1", run_mangle1, 0},
8663 {"W2K", run_w2ktest, 0},
8664 {"TRANS2SCAN", torture_trans2_scan, 0},
8665 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8666 {"UTABLE", torture_utable, 0},
8667 {"CASETABLE", torture_casetable, 0},
8668 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8669 {"PIPE_NUMBER", run_pipe_number, 0},
8670 {"TCON2", run_tcon2_test, 0},
8671 {"IOCTL", torture_ioctl_test, 0},
8672 {"CHKPATH", torture_chkpath_test, 0},
8673 {"FDSESS", run_fdsesstest, 0},
8674 { "EATEST", run_eatest, 0},
8675 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8676 { "CHAIN1", run_chain1, 0},
8677 { "CHAIN2", run_chain2, 0},
8678 { "WINDOWS-WRITE", run_windows_write, 0},
8679 { "NTTRANS-CREATE", run_nttrans_create, 0},
8680 { "CLI_ECHO", run_cli_echo, 0},
8681 { "GETADDRINFO", run_getaddrinfo_send, 0},
8682 { "TLDAP", run_tldap },
8683 { "STREAMERROR", run_streamerror },
8684 { "NOTIFY-BENCH", run_notify_bench },
8685 { "BAD-NBT-SESSION", run_bad_nbt_session },
8686 { "SMB-ANY-CONNECT", run_smb_any_connect },
8687 { "NOTIFY-ONLINE", run_notify_online },
8688 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8689 { "LOCAL-GENCACHE", run_local_gencache, 0},
8690 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8691 { "LOCAL-BASE64", run_local_base64, 0},
8692 { "LOCAL-RBTREE", run_local_rbtree, 0},
8693 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8694 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8695 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8696 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8697 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8698 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8699 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8700 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8705 /****************************************************************************
8706 run a specified test or "ALL"
8707 ****************************************************************************/
8708 static bool run_test(const char *name)
8715 if (strequal(name,"ALL")) {
8716 for (i=0;torture_ops[i].name;i++) {
8717 run_test(torture_ops[i].name);
8722 for (i=0;torture_ops[i].name;i++) {
8723 fstr_sprintf(randomfname, "\\XX%x",
8724 (unsigned)random());
8726 if (strequal(name, torture_ops[i].name)) {
8728 printf("Running %s\n", name);
8729 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8730 t = create_procs(torture_ops[i].fn, &result);
8733 printf("TEST %s FAILED!\n", name);
8736 struct timeval start;
8737 start = timeval_current();
8738 if (!torture_ops[i].fn(0)) {
8740 printf("TEST %s FAILED!\n", name);
8742 t = timeval_elapsed(&start);
8744 printf("%s took %g secs\n\n", name, t);
8749 printf("Did not find a test named %s\n", name);
8757 static void usage(void)
8761 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8762 printf("Please use samba4 torture.\n\n");
8764 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8766 printf("\t-d debuglevel\n");
8767 printf("\t-U user%%pass\n");
8768 printf("\t-k use kerberos\n");
8769 printf("\t-N numprocs\n");
8770 printf("\t-n my_netbios_name\n");
8771 printf("\t-W workgroup\n");
8772 printf("\t-o num_operations\n");
8773 printf("\t-O socket_options\n");
8774 printf("\t-m maximum protocol\n");
8775 printf("\t-L use oplocks\n");
8776 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8777 printf("\t-A showall\n");
8778 printf("\t-p port\n");
8779 printf("\t-s seed\n");
8780 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8781 printf("\t-f filename filename to test\n");
8784 printf("tests are:");
8785 for (i=0;torture_ops[i].name;i++) {
8786 printf(" %s", torture_ops[i].name);
8790 printf("default test is ALL\n");
8795 /****************************************************************************
8797 ****************************************************************************/
8798 int main(int argc,char *argv[])
8804 bool correct = True;
8805 TALLOC_CTX *frame = talloc_stackframe();
8806 int seed = time(NULL);
8808 #ifdef HAVE_SETBUFFER
8809 setbuffer(stdout, NULL, 0);
8812 setup_logging("smbtorture", DEBUG_STDOUT);
8816 if (is_default_dyn_CONFIGFILE()) {
8817 if(getenv("SMB_CONF_PATH")) {
8818 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8821 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8828 for(p = argv[1]; *p; p++)
8832 if (strncmp(argv[1], "//", 2)) {
8836 fstrcpy(host, &argv[1][2]);
8837 p = strchr_m(&host[2],'/');
8842 fstrcpy(share, p+1);
8844 fstrcpy(myname, get_myname(talloc_tos()));
8846 fprintf(stderr, "Failed to get my hostname.\n");
8850 if (*username == 0 && getenv("LOGNAME")) {
8851 fstrcpy(username,getenv("LOGNAME"));
8857 fstrcpy(workgroup, lp_workgroup());
8859 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8863 port_to_use = atoi(optarg);
8866 seed = atoi(optarg);
8869 fstrcpy(workgroup,optarg);
8872 max_protocol = interpret_protocol(optarg, max_protocol);
8875 nprocs = atoi(optarg);
8878 torture_numops = atoi(optarg);
8881 lp_set_cmdline("log level", optarg);
8890 local_path = optarg;
8893 torture_showall = True;
8896 fstrcpy(myname, optarg);
8899 client_txt = optarg;
8906 use_kerberos = True;
8908 d_printf("No kerberos support compiled in\n");
8914 fstrcpy(username,optarg);
8915 p = strchr_m(username,'%');
8918 fstrcpy(password, p+1);
8923 fstrcpy(multishare_conn_fname, optarg);
8924 use_multishare_conn = True;
8927 torture_blocksize = atoi(optarg);
8930 test_filename = SMB_STRDUP(optarg);
8933 printf("Unknown option %c (%d)\n", (char)opt, opt);
8938 d_printf("using seed %d\n", seed);
8942 if(use_kerberos && !gotuser) gotpass = True;
8945 p = getpass("Password:");
8947 fstrcpy(password, p);
8952 printf("host=%s share=%s user=%s myname=%s\n",
8953 host, share, username, myname);
8955 if (argc == optind) {
8956 correct = run_test("ALL");
8958 for (i=optind;i<argc;i++) {
8959 if (!run_test(argv[i])) {