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 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5292 if (!NT_STATUS_IS_OK(status)) {
5293 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5297 /* Test ftruncate - set file size. */
5298 status = cli_ftruncate(cli1, fnum1, 1000);
5299 if (!NT_STATUS_IS_OK(status)) {
5300 printf("ftruncate failed (%s)\n", nt_errstr(status));
5304 /* Ensure st_size == 1000 */
5305 status = cli_posix_stat(cli1, fname, &sbuf);
5306 if (!NT_STATUS_IS_OK(status)) {
5307 printf("stat failed (%s)\n", nt_errstr(status));
5311 if (sbuf.st_ex_size != 1000) {
5312 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5316 status = cli_close(cli1, fnum1);
5317 if (!NT_STATUS_IS_OK(status)) {
5318 printf("close(2) failed (%s)\n", nt_errstr(status));
5322 /* Re-open with O_TRUNC. */
5323 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5324 if (!NT_STATUS_IS_OK(status)) {
5325 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5329 /* Ensure st_size == 0 */
5330 status = cli_posix_stat(cli1, fname, &sbuf);
5331 if (!NT_STATUS_IS_OK(status)) {
5332 printf("stat failed (%s)\n", nt_errstr(status));
5336 if (sbuf.st_ex_size != 0) {
5337 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5341 status = cli_close(cli1, fnum1);
5342 if (!NT_STATUS_IS_OK(status)) {
5343 printf("close failed (%s)\n", nt_errstr(status));
5347 status = cli_posix_unlink(cli1, fname);
5348 if (!NT_STATUS_IS_OK(status)) {
5349 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5353 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5354 if (!NT_STATUS_IS_OK(status)) {
5355 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5356 dname, nt_errstr(status));
5360 cli_close(cli1, fnum1);
5362 /* What happens when we try and POSIX open a directory for write ? */
5363 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5364 if (NT_STATUS_IS_OK(status)) {
5365 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5368 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5369 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5374 /* Create the file. */
5375 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5382 /* Write some data into it. */
5383 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5385 if (!NT_STATUS_IS_OK(status)) {
5386 printf("cli_write failed: %s\n", nt_errstr(status));
5390 cli_close(cli1, fnum1);
5392 /* Now create a hardlink. */
5393 status = cli_posix_hardlink(cli1, fname, hname);
5394 if (!NT_STATUS_IS_OK(status)) {
5395 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5399 /* Now create a symlink. */
5400 status = cli_posix_symlink(cli1, fname, sname);
5401 if (!NT_STATUS_IS_OK(status)) {
5402 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5406 /* Open the hardlink for read. */
5407 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5413 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5414 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5418 if (memcmp(buf, "TEST DATA\n", 10)) {
5419 printf("invalid data read from hardlink\n");
5423 /* Do a POSIX lock/unlock. */
5424 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5425 if (!NT_STATUS_IS_OK(status)) {
5426 printf("POSIX lock failed %s\n", nt_errstr(status));
5430 /* Punch a hole in the locked area. */
5431 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5432 if (!NT_STATUS_IS_OK(status)) {
5433 printf("POSIX unlock failed %s\n", nt_errstr(status));
5437 cli_close(cli1, fnum1);
5439 /* Open the symlink for read - this should fail. A POSIX
5440 client should not be doing opens on a symlink. */
5441 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5442 if (NT_STATUS_IS_OK(status)) {
5443 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5446 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5447 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5448 printf("POSIX open of %s should have failed "
5449 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5450 "failed with %s instead.\n",
5451 sname, nt_errstr(status));
5456 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5457 if (!NT_STATUS_IS_OK(status)) {
5458 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5462 if (strcmp(namebuf, fname) != 0) {
5463 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5464 sname, fname, namebuf);
5468 status = cli_posix_rmdir(cli1, dname);
5469 if (!NT_STATUS_IS_OK(status)) {
5470 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5474 printf("Simple POSIX open test passed\n");
5479 if (fnum1 != (uint16_t)-1) {
5480 cli_close(cli1, fnum1);
5481 fnum1 = (uint16_t)-1;
5484 cli_setatr(cli1, sname, 0, 0);
5485 cli_posix_unlink(cli1, sname);
5486 cli_setatr(cli1, hname, 0, 0);
5487 cli_posix_unlink(cli1, hname);
5488 cli_setatr(cli1, fname, 0, 0);
5489 cli_posix_unlink(cli1, fname);
5490 cli_setatr(cli1, dname, 0, 0);
5491 cli_posix_rmdir(cli1, dname);
5493 if (!torture_close_connection(cli1)) {
5501 static uint32 open_attrs_table[] = {
5502 FILE_ATTRIBUTE_NORMAL,
5503 FILE_ATTRIBUTE_ARCHIVE,
5504 FILE_ATTRIBUTE_READONLY,
5505 FILE_ATTRIBUTE_HIDDEN,
5506 FILE_ATTRIBUTE_SYSTEM,
5508 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5509 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5510 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5511 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5512 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5513 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5515 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5516 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5517 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5518 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5521 struct trunc_open_results {
5528 static struct trunc_open_results attr_results[] = {
5529 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5530 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5531 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5532 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5533 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5534 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5535 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5536 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5537 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5538 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5539 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5540 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5541 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5542 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5543 { 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 },
5544 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5545 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5546 { 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 },
5547 { 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 },
5548 { 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 },
5549 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5550 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5551 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5552 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5553 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5554 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5557 static bool run_openattrtest(int dummy)
5559 static struct cli_state *cli1;
5560 const char *fname = "\\openattr.file";
5562 bool correct = True;
5564 unsigned int i, j, k, l;
5567 printf("starting open attr test\n");
5569 if (!torture_open_connection(&cli1, 0)) {
5573 cli_sockopt(cli1, sockops);
5575 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5576 cli_setatr(cli1, fname, 0, 0);
5577 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5579 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5580 open_attrs_table[i], FILE_SHARE_NONE,
5581 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5582 if (!NT_STATUS_IS_OK(status)) {
5583 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5587 status = cli_close(cli1, fnum1);
5588 if (!NT_STATUS_IS_OK(status)) {
5589 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5593 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5594 status = cli_ntcreate(cli1, fname, 0,
5595 FILE_READ_DATA|FILE_WRITE_DATA,
5596 open_attrs_table[j],
5597 FILE_SHARE_NONE, FILE_OVERWRITE,
5599 if (!NT_STATUS_IS_OK(status)) {
5600 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5601 if (attr_results[l].num == k) {
5602 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5603 k, open_attrs_table[i],
5604 open_attrs_table[j],
5605 fname, NT_STATUS_V(status), nt_errstr(status));
5610 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5611 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5612 k, open_attrs_table[i], open_attrs_table[j],
5617 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5623 status = cli_close(cli1, fnum1);
5624 if (!NT_STATUS_IS_OK(status)) {
5625 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5629 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5630 if (!NT_STATUS_IS_OK(status)) {
5631 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5636 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5637 k, open_attrs_table[i], open_attrs_table[j], attr );
5640 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5641 if (attr_results[l].num == k) {
5642 if (attr != attr_results[l].result_attr ||
5643 open_attrs_table[i] != attr_results[l].init_attr ||
5644 open_attrs_table[j] != attr_results[l].trunc_attr) {
5645 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5646 open_attrs_table[i],
5647 open_attrs_table[j],
5649 attr_results[l].result_attr);
5659 cli_setatr(cli1, fname, 0, 0);
5660 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5662 printf("open attr test %s.\n", correct ? "passed" : "failed");
5664 if (!torture_close_connection(cli1)) {
5670 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5671 const char *name, void *state)
5673 int *matched = (int *)state;
5674 if (matched != NULL) {
5677 return NT_STATUS_OK;
5681 test directory listing speed
5683 static bool run_dirtest(int dummy)
5686 static struct cli_state *cli;
5688 struct timeval core_start;
5689 bool correct = True;
5692 printf("starting directory test\n");
5694 if (!torture_open_connection(&cli, 0)) {
5698 cli_sockopt(cli, sockops);
5701 for (i=0;i<torture_numops;i++) {
5703 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5704 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5705 fprintf(stderr,"Failed to open %s\n", fname);
5708 cli_close(cli, fnum);
5711 core_start = timeval_current();
5714 cli_list(cli, "a*.*", 0, list_fn, &matched);
5715 printf("Matched %d\n", matched);
5718 cli_list(cli, "b*.*", 0, list_fn, &matched);
5719 printf("Matched %d\n", matched);
5722 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5723 printf("Matched %d\n", matched);
5725 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5728 for (i=0;i<torture_numops;i++) {
5730 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5731 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5734 if (!torture_close_connection(cli)) {
5738 printf("finished dirtest\n");
5743 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5746 struct cli_state *pcli = (struct cli_state *)state;
5748 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5750 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5751 return NT_STATUS_OK;
5753 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5754 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5755 printf("del_fn: failed to rmdir %s\n,", fname );
5757 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5758 printf("del_fn: failed to unlink %s\n,", fname );
5760 return NT_STATUS_OK;
5765 sees what IOCTLs are supported
5767 bool torture_ioctl_test(int dummy)
5769 static struct cli_state *cli;
5770 uint16_t device, function;
5772 const char *fname = "\\ioctl.dat";
5776 if (!torture_open_connection(&cli, 0)) {
5780 printf("starting ioctl test\n");
5782 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5784 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5785 if (!NT_STATUS_IS_OK(status)) {
5786 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5790 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5791 printf("ioctl device info: %s\n", nt_errstr(status));
5793 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5794 printf("ioctl job info: %s\n", nt_errstr(status));
5796 for (device=0;device<0x100;device++) {
5797 printf("ioctl test with device = 0x%x\n", device);
5798 for (function=0;function<0x100;function++) {
5799 uint32 code = (device<<16) | function;
5801 status = cli_raw_ioctl(cli, fnum, code, &blob);
5803 if (NT_STATUS_IS_OK(status)) {
5804 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5806 data_blob_free(&blob);
5811 if (!torture_close_connection(cli)) {
5820 tries varients of chkpath
5822 bool torture_chkpath_test(int dummy)
5824 static struct cli_state *cli;
5829 if (!torture_open_connection(&cli, 0)) {
5833 printf("starting chkpath test\n");
5835 /* cleanup from an old run */
5836 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5837 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5838 cli_rmdir(cli, "\\chkpath.dir");
5840 status = cli_mkdir(cli, "\\chkpath.dir");
5841 if (!NT_STATUS_IS_OK(status)) {
5842 printf("mkdir1 failed : %s\n", nt_errstr(status));
5846 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5847 if (!NT_STATUS_IS_OK(status)) {
5848 printf("mkdir2 failed : %s\n", nt_errstr(status));
5852 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5854 if (!NT_STATUS_IS_OK(status)) {
5855 printf("open1 failed (%s)\n", nt_errstr(status));
5858 cli_close(cli, fnum);
5860 status = cli_chkpath(cli, "\\chkpath.dir");
5861 if (!NT_STATUS_IS_OK(status)) {
5862 printf("chkpath1 failed: %s\n", nt_errstr(status));
5866 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5867 if (!NT_STATUS_IS_OK(status)) {
5868 printf("chkpath2 failed: %s\n", nt_errstr(status));
5872 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5873 if (!NT_STATUS_IS_OK(status)) {
5874 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5875 NT_STATUS_NOT_A_DIRECTORY);
5877 printf("* chkpath on a file should fail\n");
5881 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5882 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5883 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5885 printf("* chkpath on a non existant file should fail\n");
5889 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5890 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5891 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5893 printf("* chkpath on a non existent component should fail\n");
5897 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5898 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5899 cli_rmdir(cli, "\\chkpath.dir");
5901 if (!torture_close_connection(cli)) {
5908 static bool run_eatest(int dummy)
5910 static struct cli_state *cli;
5911 const char *fname = "\\eatest.txt";
5912 bool correct = True;
5916 struct ea_struct *ea_list = NULL;
5917 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5920 printf("starting eatest\n");
5922 if (!torture_open_connection(&cli, 0)) {
5923 talloc_destroy(mem_ctx);
5927 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5929 status = cli_ntcreate(cli, fname, 0,
5930 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5931 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("open failed - %s\n", nt_errstr(status));
5935 talloc_destroy(mem_ctx);
5939 for (i = 0; i < 10; i++) {
5940 fstring ea_name, ea_val;
5942 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5943 memset(ea_val, (char)i+1, i+1);
5944 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5945 if (!NT_STATUS_IS_OK(status)) {
5946 printf("ea_set of name %s failed - %s\n", ea_name,
5948 talloc_destroy(mem_ctx);
5953 cli_close(cli, fnum);
5954 for (i = 0; i < 10; i++) {
5955 fstring ea_name, ea_val;
5957 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5958 memset(ea_val, (char)i+1, i+1);
5959 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5960 if (!NT_STATUS_IS_OK(status)) {
5961 printf("ea_set of name %s failed - %s\n", ea_name,
5963 talloc_destroy(mem_ctx);
5968 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5969 if (!NT_STATUS_IS_OK(status)) {
5970 printf("ea_get list failed - %s\n", nt_errstr(status));
5974 printf("num_eas = %d\n", (int)num_eas);
5976 if (num_eas != 20) {
5977 printf("Should be 20 EA's stored... failing.\n");
5981 for (i = 0; i < num_eas; i++) {
5982 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5983 dump_data(0, ea_list[i].value.data,
5984 ea_list[i].value.length);
5987 /* Setting EA's to zero length deletes them. Test this */
5988 printf("Now deleting all EA's - case indepenent....\n");
5991 cli_set_ea_path(cli, fname, "", "", 0);
5993 for (i = 0; i < 20; i++) {
5995 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5996 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5997 if (!NT_STATUS_IS_OK(status)) {
5998 printf("ea_set of name %s failed - %s\n", ea_name,
6000 talloc_destroy(mem_ctx);
6006 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6007 if (!NT_STATUS_IS_OK(status)) {
6008 printf("ea_get list failed - %s\n", nt_errstr(status));
6012 printf("num_eas = %d\n", (int)num_eas);
6013 for (i = 0; i < num_eas; i++) {
6014 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6015 dump_data(0, ea_list[i].value.data,
6016 ea_list[i].value.length);
6020 printf("deleting EA's failed.\n");
6024 /* Try and delete a non existant EA. */
6025 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6026 if (!NT_STATUS_IS_OK(status)) {
6027 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6032 talloc_destroy(mem_ctx);
6033 if (!torture_close_connection(cli)) {
6040 static bool run_dirtest1(int dummy)
6043 static struct cli_state *cli;
6046 bool correct = True;
6048 printf("starting directory test\n");
6050 if (!torture_open_connection(&cli, 0)) {
6054 cli_sockopt(cli, sockops);
6056 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6057 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6058 cli_rmdir(cli, "\\LISTDIR");
6059 cli_mkdir(cli, "\\LISTDIR");
6061 /* Create 1000 files and 1000 directories. */
6062 for (i=0;i<1000;i++) {
6064 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6065 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6066 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6067 fprintf(stderr,"Failed to open %s\n", fname);
6070 cli_close(cli, fnum);
6072 for (i=0;i<1000;i++) {
6074 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6075 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6076 fprintf(stderr,"Failed to open %s\n", fname);
6081 /* Now ensure that doing an old list sees both files and directories. */
6083 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6084 printf("num_seen = %d\n", num_seen );
6085 /* We should see 100 files + 1000 directories + . and .. */
6086 if (num_seen != 2002)
6089 /* Ensure if we have the "must have" bits we only see the
6093 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6094 printf("num_seen = %d\n", num_seen );
6095 if (num_seen != 1002)
6099 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6100 printf("num_seen = %d\n", num_seen );
6101 if (num_seen != 1000)
6104 /* Delete everything. */
6105 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6106 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6107 cli_rmdir(cli, "\\LISTDIR");
6110 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6111 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6112 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6115 if (!torture_close_connection(cli)) {
6119 printf("finished dirtest1\n");
6124 static bool run_error_map_extract(int dummy) {
6126 static struct cli_state *c_dos;
6127 static struct cli_state *c_nt;
6132 uint32 flgs2, errnum;
6139 /* NT-Error connection */
6141 if (!(c_nt = open_nbt_connection())) {
6145 c_nt->use_spnego = False;
6147 status = cli_negprot(c_nt);
6149 if (!NT_STATUS_IS_OK(status)) {
6150 printf("%s rejected the NT-error negprot (%s)\n", host,
6156 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6157 if (!NT_STATUS_IS_OK(status)) {
6158 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6162 /* DOS-Error connection */
6164 if (!(c_dos = open_nbt_connection())) {
6168 c_dos->use_spnego = False;
6169 c_dos->force_dos_errors = True;
6171 status = cli_negprot(c_dos);
6172 if (!NT_STATUS_IS_OK(status)) {
6173 printf("%s rejected the DOS-error negprot (%s)\n", host,
6175 cli_shutdown(c_dos);
6179 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6180 if (!NT_STATUS_IS_OK(status)) {
6181 printf("%s rejected the DOS-error initial session setup (%s)\n",
6182 host, nt_errstr(status));
6186 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6187 fstr_sprintf(user, "%X", error);
6189 status = cli_session_setup(c_nt, user,
6190 password, strlen(password),
6191 password, strlen(password),
6193 if (NT_STATUS_IS_OK(status)) {
6194 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6197 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6199 /* Case #1: 32-bit NT errors */
6200 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6201 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6203 printf("/** Dos error on NT connection! (%s) */\n",
6205 nt_status = NT_STATUS(0xc0000000);
6208 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6209 password, strlen(password),
6210 password, strlen(password),
6212 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6214 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6216 /* Case #1: 32-bit NT errors */
6217 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6218 printf("/** NT error on DOS connection! (%s) */\n",
6220 errnum = errclass = 0;
6222 cli_dos_error(c_dos, &errclass, &errnum);
6225 if (NT_STATUS_V(nt_status) != error) {
6226 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6227 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6228 get_nt_error_c_code(talloc_tos(), nt_status));
6231 printf("\t{%s,\t%s,\t%s},\n",
6232 smb_dos_err_class(errclass),
6233 smb_dos_err_name(errclass, errnum),
6234 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6239 static bool run_sesssetup_bench(int dummy)
6241 static struct cli_state *c;
6242 const char *fname = "\\file.dat";
6247 if (!torture_open_connection(&c, 0)) {
6251 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6252 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6253 FILE_DELETE_ON_CLOSE, 0, &fnum);
6254 if (!NT_STATUS_IS_OK(status)) {
6255 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6259 for (i=0; i<torture_numops; i++) {
6260 status = cli_session_setup(
6262 password, strlen(password),
6263 password, strlen(password),
6265 if (!NT_STATUS_IS_OK(status)) {
6266 d_printf("(%s) cli_session_setup failed: %s\n",
6267 __location__, nt_errstr(status));
6271 d_printf("\r%d ", (int)c->vuid);
6273 status = cli_ulogoff(c);
6274 if (!NT_STATUS_IS_OK(status)) {
6275 d_printf("(%s) cli_ulogoff failed: %s\n",
6276 __location__, nt_errstr(status));
6285 static bool subst_test(const char *str, const char *user, const char *domain,
6286 uid_t uid, gid_t gid, const char *expected)
6291 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6293 if (strcmp(subst, expected) != 0) {
6294 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6295 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6304 static void chain1_open_completion(struct tevent_req *req)
6308 status = cli_open_recv(req, &fnum);
6311 d_printf("cli_open_recv returned %s: %d\n",
6313 NT_STATUS_IS_OK(status) ? fnum : -1);
6316 static void chain1_write_completion(struct tevent_req *req)
6320 status = cli_write_andx_recv(req, &written);
6323 d_printf("cli_write_andx_recv returned %s: %d\n",
6325 NT_STATUS_IS_OK(status) ? (int)written : -1);
6328 static void chain1_close_completion(struct tevent_req *req)
6331 bool *done = (bool *)tevent_req_callback_data_void(req);
6333 status = cli_close_recv(req);
6338 d_printf("cli_close returned %s\n", nt_errstr(status));
6341 static bool run_chain1(int dummy)
6343 struct cli_state *cli1;
6344 struct event_context *evt = event_context_init(NULL);
6345 struct tevent_req *reqs[3], *smbreqs[3];
6347 const char *str = "foobar";
6350 printf("starting chain1 test\n");
6351 if (!torture_open_connection(&cli1, 0)) {
6355 cli_sockopt(cli1, sockops);
6357 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6358 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6359 if (reqs[0] == NULL) return false;
6360 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6363 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6364 (const uint8_t *)str, 0, strlen(str)+1,
6365 smbreqs, 1, &smbreqs[1]);
6366 if (reqs[1] == NULL) return false;
6367 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6369 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6370 if (reqs[2] == NULL) return false;
6371 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6373 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6374 if (!NT_STATUS_IS_OK(status)) {
6379 event_loop_once(evt);
6382 torture_close_connection(cli1);
6386 static void chain2_sesssetup_completion(struct tevent_req *req)
6389 status = cli_session_setup_guest_recv(req);
6390 d_printf("sesssetup returned %s\n", nt_errstr(status));
6393 static void chain2_tcon_completion(struct tevent_req *req)
6395 bool *done = (bool *)tevent_req_callback_data_void(req);
6397 status = cli_tcon_andx_recv(req);
6398 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6402 static bool run_chain2(int dummy)
6404 struct cli_state *cli1;
6405 struct event_context *evt = event_context_init(NULL);
6406 struct tevent_req *reqs[2], *smbreqs[2];
6410 printf("starting chain2 test\n");
6411 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6412 port_to_use, Undefined, 0);
6413 if (!NT_STATUS_IS_OK(status)) {
6417 cli_sockopt(cli1, sockops);
6419 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6421 if (reqs[0] == NULL) return false;
6422 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6424 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6425 "?????", NULL, 0, &smbreqs[1]);
6426 if (reqs[1] == NULL) return false;
6427 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6429 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6430 if (!NT_STATUS_IS_OK(status)) {
6435 event_loop_once(evt);
6438 torture_close_connection(cli1);
6443 struct torture_createdel_state {
6444 struct tevent_context *ev;
6445 struct cli_state *cli;
6448 static void torture_createdel_created(struct tevent_req *subreq);
6449 static void torture_createdel_closed(struct tevent_req *subreq);
6451 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6452 struct tevent_context *ev,
6453 struct cli_state *cli,
6456 struct tevent_req *req, *subreq;
6457 struct torture_createdel_state *state;
6459 req = tevent_req_create(mem_ctx, &state,
6460 struct torture_createdel_state);
6467 subreq = cli_ntcreate_send(
6468 state, ev, cli, name, 0,
6469 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6470 FILE_ATTRIBUTE_NORMAL,
6471 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6472 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6474 if (tevent_req_nomem(subreq, req)) {
6475 return tevent_req_post(req, ev);
6477 tevent_req_set_callback(subreq, torture_createdel_created, req);
6481 static void torture_createdel_created(struct tevent_req *subreq)
6483 struct tevent_req *req = tevent_req_callback_data(
6484 subreq, struct tevent_req);
6485 struct torture_createdel_state *state = tevent_req_data(
6486 req, struct torture_createdel_state);
6490 status = cli_ntcreate_recv(subreq, &fnum);
6491 TALLOC_FREE(subreq);
6492 if (!NT_STATUS_IS_OK(status)) {
6493 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6494 nt_errstr(status)));
6495 tevent_req_nterror(req, status);
6499 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6500 if (tevent_req_nomem(subreq, req)) {
6503 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6506 static void torture_createdel_closed(struct tevent_req *subreq)
6508 struct tevent_req *req = tevent_req_callback_data(
6509 subreq, struct tevent_req);
6512 status = cli_close_recv(subreq);
6513 if (!NT_STATUS_IS_OK(status)) {
6514 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6515 tevent_req_nterror(req, status);
6518 tevent_req_done(req);
6521 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6523 return tevent_req_simple_recv_ntstatus(req);
6526 struct torture_createdels_state {
6527 struct tevent_context *ev;
6528 struct cli_state *cli;
6529 const char *base_name;
6533 struct tevent_req **reqs;
6536 static void torture_createdels_done(struct tevent_req *subreq);
6538 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6539 struct tevent_context *ev,
6540 struct cli_state *cli,
6541 const char *base_name,
6545 struct tevent_req *req;
6546 struct torture_createdels_state *state;
6549 req = tevent_req_create(mem_ctx, &state,
6550 struct torture_createdels_state);
6556 state->base_name = talloc_strdup(state, base_name);
6557 if (tevent_req_nomem(state->base_name, req)) {
6558 return tevent_req_post(req, ev);
6560 state->num_files = MAX(num_parallel, num_files);
6562 state->received = 0;
6564 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6565 if (tevent_req_nomem(state->reqs, req)) {
6566 return tevent_req_post(req, ev);
6569 for (i=0; i<num_parallel; i++) {
6572 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6574 if (tevent_req_nomem(name, req)) {
6575 return tevent_req_post(req, ev);
6577 state->reqs[i] = torture_createdel_send(
6578 state->reqs, state->ev, state->cli, name);
6579 if (tevent_req_nomem(state->reqs[i], req)) {
6580 return tevent_req_post(req, ev);
6582 name = talloc_move(state->reqs[i], &name);
6583 tevent_req_set_callback(state->reqs[i],
6584 torture_createdels_done, req);
6590 static void torture_createdels_done(struct tevent_req *subreq)
6592 struct tevent_req *req = tevent_req_callback_data(
6593 subreq, struct tevent_req);
6594 struct torture_createdels_state *state = tevent_req_data(
6595 req, struct torture_createdels_state);
6596 size_t num_parallel = talloc_array_length(state->reqs);
6601 status = torture_createdel_recv(subreq);
6602 if (!NT_STATUS_IS_OK(status)){
6603 DEBUG(10, ("torture_createdel_recv returned %s\n",
6604 nt_errstr(status)));
6605 TALLOC_FREE(subreq);
6606 tevent_req_nterror(req, status);
6610 for (i=0; i<num_parallel; i++) {
6611 if (subreq == state->reqs[i]) {
6615 if (i == num_parallel) {
6616 DEBUG(10, ("received something we did not send\n"));
6617 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6620 TALLOC_FREE(state->reqs[i]);
6622 if (state->sent >= state->num_files) {
6623 tevent_req_done(req);
6627 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6629 if (tevent_req_nomem(name, req)) {
6632 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6634 if (tevent_req_nomem(state->reqs[i], req)) {
6637 name = talloc_move(state->reqs[i], &name);
6638 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6642 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6644 return tevent_req_simple_recv_ntstatus(req);
6647 struct swallow_notify_state {
6648 struct tevent_context *ev;
6649 struct cli_state *cli;
6651 uint32_t completion_filter;
6653 bool (*fn)(uint32_t action, const char *name, void *priv);
6657 static void swallow_notify_done(struct tevent_req *subreq);
6659 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6660 struct tevent_context *ev,
6661 struct cli_state *cli,
6663 uint32_t completion_filter,
6665 bool (*fn)(uint32_t action,
6670 struct tevent_req *req, *subreq;
6671 struct swallow_notify_state *state;
6673 req = tevent_req_create(mem_ctx, &state,
6674 struct swallow_notify_state);
6681 state->completion_filter = completion_filter;
6682 state->recursive = recursive;
6686 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6687 0xffff, state->completion_filter,
6689 if (tevent_req_nomem(subreq, req)) {
6690 return tevent_req_post(req, ev);
6692 tevent_req_set_callback(subreq, swallow_notify_done, req);
6696 static void swallow_notify_done(struct tevent_req *subreq)
6698 struct tevent_req *req = tevent_req_callback_data(
6699 subreq, struct tevent_req);
6700 struct swallow_notify_state *state = tevent_req_data(
6701 req, struct swallow_notify_state);
6703 uint32_t i, num_changes;
6704 struct notify_change *changes;
6706 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6707 TALLOC_FREE(subreq);
6708 if (!NT_STATUS_IS_OK(status)) {
6709 DEBUG(10, ("cli_notify_recv returned %s\n",
6710 nt_errstr(status)));
6711 tevent_req_nterror(req, status);
6715 for (i=0; i<num_changes; i++) {
6716 state->fn(changes[i].action, changes[i].name, state->priv);
6718 TALLOC_FREE(changes);
6720 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6721 0xffff, state->completion_filter,
6723 if (tevent_req_nomem(subreq, req)) {
6726 tevent_req_set_callback(subreq, swallow_notify_done, req);
6729 static bool print_notifies(uint32_t action, const char *name, void *priv)
6731 if (DEBUGLEVEL > 5) {
6732 d_printf("%d %s\n", (int)action, name);
6737 static void notify_bench_done(struct tevent_req *req)
6739 int *num_finished = (int *)tevent_req_callback_data_void(req);
6743 static bool run_notify_bench(int dummy)
6745 const char *dname = "\\notify-bench";
6746 struct tevent_context *ev;
6749 struct tevent_req *req1;
6750 struct tevent_req *req2 = NULL;
6751 int i, num_unc_names;
6752 int num_finished = 0;
6754 printf("starting notify-bench test\n");
6756 if (use_multishare_conn) {
6758 unc_list = file_lines_load(multishare_conn_fname,
6759 &num_unc_names, 0, NULL);
6760 if (!unc_list || num_unc_names <= 0) {
6761 d_printf("Failed to load unc names list from '%s'\n",
6762 multishare_conn_fname);
6765 TALLOC_FREE(unc_list);
6770 ev = tevent_context_init(talloc_tos());
6772 d_printf("tevent_context_init failed\n");
6776 for (i=0; i<num_unc_names; i++) {
6777 struct cli_state *cli;
6780 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6782 if (base_fname == NULL) {
6786 if (!torture_open_connection(&cli, i)) {
6790 status = cli_ntcreate(cli, dname, 0,
6791 MAXIMUM_ALLOWED_ACCESS,
6792 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6794 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6797 if (!NT_STATUS_IS_OK(status)) {
6798 d_printf("Could not create %s: %s\n", dname,
6803 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6804 FILE_NOTIFY_CHANGE_FILE_NAME |
6805 FILE_NOTIFY_CHANGE_DIR_NAME |
6806 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6807 FILE_NOTIFY_CHANGE_LAST_WRITE,
6808 false, print_notifies, NULL);
6810 d_printf("Could not create notify request\n");
6814 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6815 base_fname, 10, torture_numops);
6817 d_printf("Could not create createdels request\n");
6820 TALLOC_FREE(base_fname);
6822 tevent_req_set_callback(req2, notify_bench_done,
6826 while (num_finished < num_unc_names) {
6828 ret = tevent_loop_once(ev);
6830 d_printf("tevent_loop_once failed\n");
6835 if (!tevent_req_poll(req2, ev)) {
6836 d_printf("tevent_req_poll failed\n");
6839 status = torture_createdels_recv(req2);
6840 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6845 static bool run_mangle1(int dummy)
6847 struct cli_state *cli;
6848 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6852 time_t change_time, access_time, write_time;
6856 printf("starting mangle1 test\n");
6857 if (!torture_open_connection(&cli, 0)) {
6861 cli_sockopt(cli, sockops);
6863 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6864 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6866 if (!NT_STATUS_IS_OK(status)) {
6867 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6870 cli_close(cli, fnum);
6872 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6873 if (!NT_STATUS_IS_OK(status)) {
6874 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6878 d_printf("alt_name: %s\n", alt_name);
6880 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6881 if (!NT_STATUS_IS_OK(status)) {
6882 d_printf("cli_open(%s) failed: %s\n", alt_name,
6886 cli_close(cli, fnum);
6888 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6889 &write_time, &size, &mode);
6890 if (!NT_STATUS_IS_OK(status)) {
6891 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6899 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6901 size_t *to_pull = (size_t *)priv;
6902 size_t thistime = *to_pull;
6904 thistime = MIN(thistime, n);
6905 if (thistime == 0) {
6909 memset(buf, 0, thistime);
6910 *to_pull -= thistime;
6914 static bool run_windows_write(int dummy)
6916 struct cli_state *cli1;
6920 const char *fname = "\\writetest.txt";
6921 struct timeval start_time;
6926 printf("starting windows_write test\n");
6927 if (!torture_open_connection(&cli1, 0)) {
6931 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6932 if (!NT_STATUS_IS_OK(status)) {
6933 printf("open failed (%s)\n", nt_errstr(status));
6937 cli_sockopt(cli1, sockops);
6939 start_time = timeval_current();
6941 for (i=0; i<torture_numops; i++) {
6943 off_t start = i * torture_blocksize;
6944 size_t to_pull = torture_blocksize - 1;
6946 status = cli_writeall(cli1, fnum, 0, &c,
6947 start + torture_blocksize - 1, 1, NULL);
6948 if (!NT_STATUS_IS_OK(status)) {
6949 printf("cli_write failed: %s\n", nt_errstr(status));
6953 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6954 null_source, &to_pull);
6955 if (!NT_STATUS_IS_OK(status)) {
6956 printf("cli_push returned: %s\n", nt_errstr(status));
6961 seconds = timeval_elapsed(&start_time);
6962 kbytes = (double)torture_blocksize * torture_numops;
6965 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6966 (double)seconds, (int)(kbytes/seconds));
6970 cli_close(cli1, fnum);
6971 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6972 torture_close_connection(cli1);
6976 static bool run_cli_echo(int dummy)
6978 struct cli_state *cli;
6981 printf("starting cli_echo test\n");
6982 if (!torture_open_connection(&cli, 0)) {
6985 cli_sockopt(cli, sockops);
6987 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6989 d_printf("cli_echo returned %s\n", nt_errstr(status));
6991 torture_close_connection(cli);
6992 return NT_STATUS_IS_OK(status);
6995 static bool run_uid_regression_test(int dummy)
6997 static struct cli_state *cli;
7000 bool correct = True;
7003 printf("starting uid regression test\n");
7005 if (!torture_open_connection(&cli, 0)) {
7009 cli_sockopt(cli, sockops);
7011 /* Ok - now save then logoff our current user. */
7012 old_vuid = cli->vuid;
7014 status = cli_ulogoff(cli);
7015 if (!NT_STATUS_IS_OK(status)) {
7016 d_printf("(%s) cli_ulogoff failed: %s\n",
7017 __location__, nt_errstr(status));
7022 cli->vuid = old_vuid;
7024 /* Try an operation. */
7025 status = cli_mkdir(cli, "\\uid_reg_test");
7026 if (NT_STATUS_IS_OK(status)) {
7027 d_printf("(%s) cli_mkdir succeeded\n",
7032 /* Should be bad uid. */
7033 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7034 NT_STATUS_USER_SESSION_DELETED)) {
7040 old_cnum = cli->cnum;
7042 /* Now try a SMBtdis with the invald vuid set to zero. */
7045 /* This should succeed. */
7046 status = cli_tdis(cli);
7048 if (NT_STATUS_IS_OK(status)) {
7049 d_printf("First tdis with invalid vuid should succeed.\n");
7051 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7056 cli->vuid = old_vuid;
7057 cli->cnum = old_cnum;
7059 /* This should fail. */
7060 status = cli_tdis(cli);
7061 if (NT_STATUS_IS_OK(status)) {
7062 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7066 /* Should be bad tid. */
7067 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7068 NT_STATUS_NETWORK_NAME_DELETED)) {
7074 cli_rmdir(cli, "\\uid_reg_test");
7083 static const char *illegal_chars = "*\\/?<>|\":";
7084 static char force_shortname_chars[] = " +,.[];=\177";
7086 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7087 const char *mask, void *state)
7089 struct cli_state *pcli = (struct cli_state *)state;
7091 NTSTATUS status = NT_STATUS_OK;
7093 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7095 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7096 return NT_STATUS_OK;
7098 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7099 status = cli_rmdir(pcli, fname);
7100 if (!NT_STATUS_IS_OK(status)) {
7101 printf("del_fn: failed to rmdir %s\n,", fname );
7104 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7105 if (!NT_STATUS_IS_OK(status)) {
7106 printf("del_fn: failed to unlink %s\n,", fname );
7118 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7119 const char *name, void *state)
7121 struct sn_state *s = (struct sn_state *)state;
7125 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7126 i, finfo->name, finfo->short_name);
7129 if (strchr(force_shortname_chars, i)) {
7130 if (!finfo->short_name) {
7131 /* Shortname not created when it should be. */
7132 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7133 __location__, finfo->name, i);
7136 } else if (finfo->short_name){
7137 /* Shortname created when it should not be. */
7138 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7139 __location__, finfo->short_name, finfo->name);
7143 return NT_STATUS_OK;
7146 static bool run_shortname_test(int dummy)
7148 static struct cli_state *cli;
7149 bool correct = True;
7155 printf("starting shortname test\n");
7157 if (!torture_open_connection(&cli, 0)) {
7161 cli_sockopt(cli, sockops);
7163 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7164 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7165 cli_rmdir(cli, "\\shortname");
7167 status = cli_mkdir(cli, "\\shortname");
7168 if (!NT_STATUS_IS_OK(status)) {
7169 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7170 __location__, nt_errstr(status));
7175 strlcpy(fname, "\\shortname\\", sizeof(fname));
7176 strlcat(fname, "test .txt", sizeof(fname));
7180 for (i = 32; i < 128; i++) {
7181 uint16_t fnum = (uint16_t)-1;
7185 if (strchr(illegal_chars, i)) {
7190 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7191 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7192 if (!NT_STATUS_IS_OK(status)) {
7193 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7194 __location__, fname, nt_errstr(status));
7198 cli_close(cli, fnum);
7201 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7203 if (s.matched != 1) {
7204 d_printf("(%s) failed to list %s: %s\n",
7205 __location__, fname, cli_errstr(cli));
7210 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7211 if (!NT_STATUS_IS_OK(status)) {
7212 d_printf("(%s) failed to delete %s: %s\n",
7213 __location__, fname, nt_errstr(status));
7226 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7227 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7228 cli_rmdir(cli, "\\shortname");
7229 torture_close_connection(cli);
7233 static void pagedsearch_cb(struct tevent_req *req)
7236 struct tldap_message *msg;
7239 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7240 if (rc != TLDAP_SUCCESS) {
7241 d_printf("tldap_search_paged_recv failed: %s\n",
7242 tldap_err2string(rc));
7245 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7249 if (!tldap_entry_dn(msg, &dn)) {
7250 d_printf("tldap_entry_dn failed\n");
7253 d_printf("%s\n", dn);
7257 static bool run_tldap(int dummy)
7259 struct tldap_context *ld;
7262 struct sockaddr_storage addr;
7263 struct tevent_context *ev;
7264 struct tevent_req *req;
7268 if (!resolve_name(host, &addr, 0, false)) {
7269 d_printf("could not find host %s\n", host);
7272 status = open_socket_out(&addr, 389, 9999, &fd);
7273 if (!NT_STATUS_IS_OK(status)) {
7274 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7278 ld = tldap_context_create(talloc_tos(), fd);
7281 d_printf("tldap_context_create failed\n");
7285 rc = tldap_fetch_rootdse(ld);
7286 if (rc != TLDAP_SUCCESS) {
7287 d_printf("tldap_fetch_rootdse failed: %s\n",
7288 tldap_errstr(talloc_tos(), ld, rc));
7292 basedn = tldap_talloc_single_attribute(
7293 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7294 if (basedn == NULL) {
7295 d_printf("no defaultNamingContext\n");
7298 d_printf("defaultNamingContext: %s\n", basedn);
7300 ev = tevent_context_init(talloc_tos());
7302 d_printf("tevent_context_init failed\n");
7306 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7307 TLDAP_SCOPE_SUB, "(objectclass=*)",
7309 NULL, 0, NULL, 0, 0, 0, 0, 5);
7311 d_printf("tldap_search_paged_send failed\n");
7314 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7316 tevent_req_poll(req, ev);
7320 /* test search filters against rootDSE */
7321 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7322 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7324 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7325 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7326 talloc_tos(), NULL, NULL);
7327 if (rc != TLDAP_SUCCESS) {
7328 d_printf("tldap_search with complex filter failed: %s\n",
7329 tldap_errstr(talloc_tos(), ld, rc));
7337 /* Torture test to ensure no regression of :
7338 https://bugzilla.samba.org/show_bug.cgi?id=7084
7341 static bool run_dir_createtime(int dummy)
7343 struct cli_state *cli;
7344 const char *dname = "\\testdir";
7345 const char *fname = "\\testdir\\testfile";
7347 struct timespec create_time;
7348 struct timespec create_time1;
7352 if (!torture_open_connection(&cli, 0)) {
7356 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7357 cli_rmdir(cli, dname);
7359 status = cli_mkdir(cli, dname);
7360 if (!NT_STATUS_IS_OK(status)) {
7361 printf("mkdir failed: %s\n", nt_errstr(status));
7365 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7367 if (!NT_STATUS_IS_OK(status)) {
7368 printf("cli_qpathinfo2 returned %s\n",
7373 /* Sleep 3 seconds, then create a file. */
7376 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7378 if (!NT_STATUS_IS_OK(status)) {
7379 printf("cli_open failed: %s\n", nt_errstr(status));
7383 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7385 if (!NT_STATUS_IS_OK(status)) {
7386 printf("cli_qpathinfo2 (2) returned %s\n",
7391 if (timespec_compare(&create_time1, &create_time)) {
7392 printf("run_dir_createtime: create time was updated (error)\n");
7394 printf("run_dir_createtime: create time was not updated (correct)\n");
7400 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7401 cli_rmdir(cli, dname);
7402 if (!torture_close_connection(cli)) {
7409 static bool run_streamerror(int dummy)
7411 struct cli_state *cli;
7412 const char *dname = "\\testdir";
7413 const char *streamname =
7414 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7416 time_t change_time, access_time, write_time;
7418 uint16_t mode, fnum;
7421 if (!torture_open_connection(&cli, 0)) {
7425 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7426 cli_rmdir(cli, dname);
7428 status = cli_mkdir(cli, dname);
7429 if (!NT_STATUS_IS_OK(status)) {
7430 printf("mkdir failed: %s\n", nt_errstr(status));
7434 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7436 status = cli_nt_error(cli);
7438 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7439 printf("pathinfo returned %s, expected "
7440 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7445 status = cli_ntcreate(cli, streamname, 0x16,
7446 FILE_READ_DATA|FILE_READ_EA|
7447 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7448 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7449 FILE_OPEN, 0, 0, &fnum);
7451 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7452 printf("ntcreate returned %s, expected "
7453 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7459 cli_rmdir(cli, dname);
7463 static bool run_local_substitute(int dummy)
7467 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7468 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7469 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7470 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7471 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7472 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7473 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7474 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7476 /* Different captialization rules in sub_basic... */
7478 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7484 static bool run_local_base64(int dummy)
7489 for (i=1; i<2000; i++) {
7490 DATA_BLOB blob1, blob2;
7493 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7495 generate_random_buffer(blob1.data, blob1.length);
7497 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7499 d_fprintf(stderr, "base64_encode_data_blob failed "
7500 "for %d bytes\n", i);
7503 blob2 = base64_decode_data_blob(b64);
7506 if (data_blob_cmp(&blob1, &blob2)) {
7507 d_fprintf(stderr, "data_blob_cmp failed for %d "
7511 TALLOC_FREE(blob1.data);
7512 data_blob_free(&blob2);
7517 static bool run_local_gencache(int dummy)
7523 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7524 d_printf("%s: gencache_set() failed\n", __location__);
7528 if (!gencache_get("foo", NULL, NULL)) {
7529 d_printf("%s: gencache_get() failed\n", __location__);
7533 if (!gencache_get("foo", &val, &tm)) {
7534 d_printf("%s: gencache_get() failed\n", __location__);
7538 if (strcmp(val, "bar") != 0) {
7539 d_printf("%s: gencache_get() returned %s, expected %s\n",
7540 __location__, val, "bar");
7547 if (!gencache_del("foo")) {
7548 d_printf("%s: gencache_del() failed\n", __location__);
7551 if (gencache_del("foo")) {
7552 d_printf("%s: second gencache_del() succeeded\n",
7557 if (gencache_get("foo", &val, &tm)) {
7558 d_printf("%s: gencache_get() on deleted entry "
7559 "succeeded\n", __location__);
7563 blob = data_blob_string_const_null("bar");
7564 tm = time(NULL) + 60;
7566 if (!gencache_set_data_blob("foo", &blob, tm)) {
7567 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7571 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7572 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7576 if (strcmp((const char *)blob.data, "bar") != 0) {
7577 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7578 __location__, (const char *)blob.data, "bar");
7579 data_blob_free(&blob);
7583 data_blob_free(&blob);
7585 if (!gencache_del("foo")) {
7586 d_printf("%s: gencache_del() failed\n", __location__);
7589 if (gencache_del("foo")) {
7590 d_printf("%s: second gencache_del() succeeded\n",
7595 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7596 d_printf("%s: gencache_get_data_blob() on deleted entry "
7597 "succeeded\n", __location__);
7604 static bool rbt_testval(struct db_context *db, const char *key,
7607 struct db_record *rec;
7608 TDB_DATA data = string_tdb_data(value);
7612 rec = db->fetch_locked(db, db, string_tdb_data(key));
7614 d_fprintf(stderr, "fetch_locked failed\n");
7617 status = rec->store(rec, data, 0);
7618 if (!NT_STATUS_IS_OK(status)) {
7619 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7624 rec = db->fetch_locked(db, db, string_tdb_data(key));
7626 d_fprintf(stderr, "second fetch_locked failed\n");
7629 if ((rec->value.dsize != data.dsize)
7630 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7631 d_fprintf(stderr, "Got wrong data back\n");
7641 static bool run_local_rbtree(int dummy)
7643 struct db_context *db;
7647 db = db_open_rbt(NULL);
7650 d_fprintf(stderr, "db_open_rbt failed\n");
7654 for (i=0; i<1000; i++) {
7657 if (asprintf(&key, "key%ld", random()) == -1) {
7660 if (asprintf(&value, "value%ld", random()) == -1) {
7665 if (!rbt_testval(db, key, value)) {
7672 if (asprintf(&value, "value%ld", random()) == -1) {
7677 if (!rbt_testval(db, key, value)) {
7696 local test for character set functions
7698 This is a very simple test for the functionality in convert_string_error()
7700 static bool run_local_convert_string(int dummy)
7702 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7703 const char *test_strings[2] = { "March", "M\303\244rz" };
7707 for (i=0; i<2; i++) {
7708 const char *str = test_strings[i];
7709 int len = strlen(str);
7710 size_t converted_size;
7713 memset(dst, 'X', sizeof(dst));
7715 /* first try with real source length */
7716 ret = convert_string_error(CH_UNIX, CH_UTF8,
7721 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7725 if (converted_size != len) {
7726 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7727 str, len, (int)converted_size);
7731 if (strncmp(str, dst, converted_size) != 0) {
7732 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7736 if (strlen(str) != converted_size) {
7737 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7738 (int)strlen(str), (int)converted_size);
7742 if (dst[converted_size] != 'X') {
7743 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7747 /* now with srclen==-1, this causes the nul to be
7749 ret = convert_string_error(CH_UNIX, CH_UTF8,
7754 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7758 if (converted_size != len+1) {
7759 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7760 str, len, (int)converted_size);
7764 if (strncmp(str, dst, converted_size) != 0) {
7765 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7769 if (len+1 != converted_size) {
7770 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7771 len+1, (int)converted_size);
7775 if (dst[converted_size] != 'X') {
7776 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7783 TALLOC_FREE(tmp_ctx);
7786 TALLOC_FREE(tmp_ctx);
7791 struct talloc_dict_test {
7795 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7797 int *count = (int *)priv;
7802 static bool run_local_talloc_dict(int dummy)
7804 struct talloc_dict *dict;
7805 struct talloc_dict_test *t;
7808 dict = talloc_dict_init(talloc_tos());
7813 t = talloc(talloc_tos(), struct talloc_dict_test);
7820 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7825 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7838 static bool run_local_string_to_sid(int dummy) {
7841 if (string_to_sid(&sid, "S--1-5-32-545")) {
7842 printf("allowing S--1-5-32-545\n");
7845 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7846 printf("allowing S-1-5-32-+545\n");
7849 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")) {
7850 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7853 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7854 printf("allowing S-1-5-32-545-abc\n");
7857 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7858 printf("could not parse S-1-5-32-545\n");
7861 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7862 printf("mis-parsed S-1-5-32-545 as %s\n",
7863 sid_string_tos(&sid));
7869 static bool run_local_binary_to_sid(int dummy) {
7870 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7871 static const char good_binary_sid[] = {
7872 0x1, /* revision number */
7874 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7875 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7879 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7880 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7881 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7882 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7883 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7884 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7885 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7886 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7892 static const char long_binary_sid[] = {
7893 0x1, /* revision number */
7895 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7896 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7902 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7903 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7904 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7905 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7906 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7907 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7908 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7909 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7910 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7916 static const char long_binary_sid2[] = {
7917 0x1, /* revision number */
7919 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7920 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7938 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7939 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7940 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7941 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7942 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7943 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7944 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7945 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7946 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7947 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7948 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7949 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7950 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7951 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7954 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7957 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7960 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7966 /* Split a path name into filename and stream name components. Canonicalise
7967 * such that an implicit $DATA token is always explicit.
7969 * The "specification" of this function can be found in the
7970 * run_local_stream_name() function in torture.c, I've tried those
7971 * combinations against a W2k3 server.
7974 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7975 char **pbase, char **pstream)
7978 char *stream = NULL;
7979 char *sname; /* stream name */
7980 const char *stype; /* stream type */
7982 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7984 sname = strchr_m(fname, ':');
7986 if (lp_posix_pathnames() || (sname == NULL)) {
7987 if (pbase != NULL) {
7988 base = talloc_strdup(mem_ctx, fname);
7989 NT_STATUS_HAVE_NO_MEMORY(base);
7994 if (pbase != NULL) {
7995 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7996 NT_STATUS_HAVE_NO_MEMORY(base);
8001 stype = strchr_m(sname, ':');
8003 if (stype == NULL) {
8004 sname = talloc_strdup(mem_ctx, sname);
8008 if (strcasecmp_m(stype, ":$DATA") != 0) {
8010 * If there is an explicit stream type, so far we only
8011 * allow $DATA. Is there anything else allowed? -- vl
8013 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8015 return NT_STATUS_OBJECT_NAME_INVALID;
8017 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8021 if (sname == NULL) {
8023 return NT_STATUS_NO_MEMORY;
8026 if (sname[0] == '\0') {
8028 * no stream name, so no stream
8033 if (pstream != NULL) {
8034 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8035 if (stream == NULL) {
8038 return NT_STATUS_NO_MEMORY;
8041 * upper-case the type field
8043 strupper_m(strchr_m(stream, ':')+1);
8047 if (pbase != NULL) {
8050 if (pstream != NULL) {
8053 return NT_STATUS_OK;
8056 static bool test_stream_name(const char *fname, const char *expected_base,
8057 const char *expected_stream,
8058 NTSTATUS expected_status)
8062 char *stream = NULL;
8064 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8065 if (!NT_STATUS_EQUAL(status, expected_status)) {
8069 if (!NT_STATUS_IS_OK(status)) {
8073 if (base == NULL) goto error;
8075 if (strcmp(expected_base, base) != 0) goto error;
8077 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8078 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8080 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8084 TALLOC_FREE(stream);
8088 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8089 fname, expected_base ? expected_base : "<NULL>",
8090 expected_stream ? expected_stream : "<NULL>",
8091 nt_errstr(expected_status));
8092 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8093 base ? base : "<NULL>", stream ? stream : "<NULL>",
8096 TALLOC_FREE(stream);
8100 static bool run_local_stream_name(int dummy)
8104 ret &= test_stream_name(
8105 "bla", "bla", NULL, NT_STATUS_OK);
8106 ret &= test_stream_name(
8107 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8108 ret &= test_stream_name(
8109 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8110 ret &= test_stream_name(
8111 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8112 ret &= test_stream_name(
8113 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8114 ret &= test_stream_name(
8115 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8116 ret &= test_stream_name(
8117 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8118 ret &= test_stream_name(
8119 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8124 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8126 if (a.length != b.length) {
8127 printf("a.length=%d != b.length=%d\n",
8128 (int)a.length, (int)b.length);
8131 if (memcmp(a.data, b.data, a.length) != 0) {
8132 printf("a.data and b.data differ\n");
8138 static bool run_local_memcache(int dummy)
8140 struct memcache *cache;
8142 DATA_BLOB d1, d2, d3;
8143 DATA_BLOB v1, v2, v3;
8145 TALLOC_CTX *mem_ctx;
8147 size_t size1, size2;
8150 cache = memcache_init(NULL, 100);
8152 if (cache == NULL) {
8153 printf("memcache_init failed\n");
8157 d1 = data_blob_const("d1", 2);
8158 d2 = data_blob_const("d2", 2);
8159 d3 = data_blob_const("d3", 2);
8161 k1 = data_blob_const("d1", 2);
8162 k2 = data_blob_const("d2", 2);
8164 memcache_add(cache, STAT_CACHE, k1, d1);
8165 memcache_add(cache, GETWD_CACHE, k2, d2);
8167 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8168 printf("could not find k1\n");
8171 if (!data_blob_equal(d1, v1)) {
8175 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8176 printf("could not find k2\n");
8179 if (!data_blob_equal(d2, v2)) {
8183 memcache_add(cache, STAT_CACHE, k1, d3);
8185 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8186 printf("could not find replaced k1\n");
8189 if (!data_blob_equal(d3, v3)) {
8193 memcache_add(cache, GETWD_CACHE, k1, d1);
8195 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8196 printf("Did find k2, should have been purged\n");
8202 cache = memcache_init(NULL, 0);
8204 mem_ctx = talloc_init("foo");
8206 str1 = talloc_strdup(mem_ctx, "string1");
8207 str2 = talloc_strdup(mem_ctx, "string2");
8209 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8210 data_blob_string_const("torture"), &str1);
8211 size1 = talloc_total_size(cache);
8213 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8214 data_blob_string_const("torture"), &str2);
8215 size2 = talloc_total_size(cache);
8217 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8219 if (size2 > size1) {
8220 printf("memcache leaks memory!\n");
8230 static void wbclient_done(struct tevent_req *req)
8233 struct winbindd_response *wb_resp;
8234 int *i = (int *)tevent_req_callback_data_void(req);
8236 wbc_err = wb_trans_recv(req, req, &wb_resp);
8239 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8242 static bool run_local_wbclient(int dummy)
8244 struct event_context *ev;
8245 struct wb_context **wb_ctx;
8246 struct winbindd_request wb_req;
8247 bool result = false;
8250 BlockSignals(True, SIGPIPE);
8252 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8257 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8258 if (wb_ctx == NULL) {
8262 ZERO_STRUCT(wb_req);
8263 wb_req.cmd = WINBINDD_PING;
8265 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8267 for (i=0; i<nprocs; i++) {
8268 wb_ctx[i] = wb_context_init(ev, NULL);
8269 if (wb_ctx[i] == NULL) {
8272 for (j=0; j<torture_numops; j++) {
8273 struct tevent_req *req;
8274 req = wb_trans_send(ev, ev, wb_ctx[i],
8275 (j % 2) == 0, &wb_req);
8279 tevent_req_set_callback(req, wbclient_done, &i);
8285 while (i < nprocs * torture_numops) {
8286 event_loop_once(ev);
8295 static void getaddrinfo_finished(struct tevent_req *req)
8297 char *name = (char *)tevent_req_callback_data_void(req);
8298 struct addrinfo *ainfo;
8301 res = getaddrinfo_recv(req, &ainfo);
8303 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8306 d_printf("gai(%s) succeeded\n", name);
8307 freeaddrinfo(ainfo);
8310 static bool run_getaddrinfo_send(int dummy)
8312 TALLOC_CTX *frame = talloc_stackframe();
8313 struct fncall_context *ctx;
8314 struct tevent_context *ev;
8315 bool result = false;
8316 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8317 "www.slashdot.org", "heise.de" };
8318 struct tevent_req *reqs[4];
8321 ev = event_context_init(frame);
8326 ctx = fncall_context_init(frame, 4);
8328 for (i=0; i<ARRAY_SIZE(names); i++) {
8329 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8331 if (reqs[i] == NULL) {
8334 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8335 discard_const_p(void, names[i]));
8338 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8339 tevent_loop_once(ev);
8348 static bool dbtrans_inc(struct db_context *db)
8350 struct db_record *rec;
8355 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8357 printf(__location__ "fetch_lock failed\n");
8361 if (rec->value.dsize != sizeof(uint32_t)) {
8362 printf(__location__ "value.dsize = %d\n",
8363 (int)rec->value.dsize);
8367 val = (uint32_t *)rec->value.dptr;
8370 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8373 if (!NT_STATUS_IS_OK(status)) {
8374 printf(__location__ "store failed: %s\n",
8385 static bool run_local_dbtrans(int dummy)
8387 struct db_context *db;
8388 struct db_record *rec;
8393 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8394 O_RDWR|O_CREAT, 0600);
8396 printf("Could not open transtest.db\n");
8400 res = db->transaction_start(db);
8402 printf(__location__ "transaction_start failed\n");
8406 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8408 printf(__location__ "fetch_lock failed\n");
8412 if (rec->value.dptr == NULL) {
8414 status = rec->store(
8415 rec, make_tdb_data((uint8_t *)&initial,
8418 if (!NT_STATUS_IS_OK(status)) {
8419 printf(__location__ "store returned %s\n",
8427 res = db->transaction_commit(db);
8429 printf(__location__ "transaction_commit failed\n");
8437 res = db->transaction_start(db);
8439 printf(__location__ "transaction_start failed\n");
8443 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8444 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8448 for (i=0; i<10; i++) {
8449 if (!dbtrans_inc(db)) {
8454 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8455 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8459 if (val2 != val + 10) {
8460 printf(__location__ "val=%d, val2=%d\n",
8461 (int)val, (int)val2);
8465 printf("val2=%d\r", val2);
8467 res = db->transaction_commit(db);
8469 printf(__location__ "transaction_commit failed\n");
8479 * Just a dummy test to be run under a debugger. There's no real way
8480 * to inspect the tevent_select specific function from outside of
8484 static bool run_local_tevent_select(int dummy)
8486 struct tevent_context *ev;
8487 struct tevent_fd *fd1, *fd2;
8488 bool result = false;
8490 ev = tevent_context_init_byname(NULL, "select");
8492 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8496 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8498 d_fprintf(stderr, "tevent_add_fd failed\n");
8501 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8503 d_fprintf(stderr, "tevent_add_fd failed\n");
8508 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8510 d_fprintf(stderr, "tevent_add_fd failed\n");
8520 static double create_procs(bool (*fn)(int), bool *result)
8523 volatile pid_t *child_status;
8524 volatile bool *child_status_out;
8527 struct timeval start;
8531 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8532 if (!child_status) {
8533 printf("Failed to setup shared memory\n");
8537 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8538 if (!child_status_out) {
8539 printf("Failed to setup result status shared memory\n");
8543 for (i = 0; i < nprocs; i++) {
8544 child_status[i] = 0;
8545 child_status_out[i] = True;
8548 start = timeval_current();
8550 for (i=0;i<nprocs;i++) {
8553 pid_t mypid = getpid();
8554 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8556 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8559 if (torture_open_connection(¤t_cli, i)) break;
8561 printf("pid %d failed to start\n", (int)getpid());
8567 child_status[i] = getpid();
8569 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8571 child_status_out[i] = fn(i);
8578 for (i=0;i<nprocs;i++) {
8579 if (child_status[i]) synccount++;
8581 if (synccount == nprocs) break;
8583 } while (timeval_elapsed(&start) < 30);
8585 if (synccount != nprocs) {
8586 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8588 return timeval_elapsed(&start);
8591 /* start the client load */
8592 start = timeval_current();
8594 for (i=0;i<nprocs;i++) {
8595 child_status[i] = 0;
8598 printf("%d clients started\n", nprocs);
8600 for (i=0;i<nprocs;i++) {
8601 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8606 for (i=0;i<nprocs;i++) {
8607 if (!child_status_out[i]) {
8611 return timeval_elapsed(&start);
8614 #define FLAG_MULTIPROC 1
8621 {"FDPASS", run_fdpasstest, 0},
8622 {"LOCK1", run_locktest1, 0},
8623 {"LOCK2", run_locktest2, 0},
8624 {"LOCK3", run_locktest3, 0},
8625 {"LOCK4", run_locktest4, 0},
8626 {"LOCK5", run_locktest5, 0},
8627 {"LOCK6", run_locktest6, 0},
8628 {"LOCK7", run_locktest7, 0},
8629 {"LOCK8", run_locktest8, 0},
8630 {"LOCK9", run_locktest9, 0},
8631 {"UNLINK", run_unlinktest, 0},
8632 {"BROWSE", run_browsetest, 0},
8633 {"ATTR", run_attrtest, 0},
8634 {"TRANS2", run_trans2test, 0},
8635 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8636 {"TORTURE",run_torture, FLAG_MULTIPROC},
8637 {"RANDOMIPC", run_randomipc, 0},
8638 {"NEGNOWAIT", run_negprot_nowait, 0},
8639 {"NBENCH", run_nbench, 0},
8640 {"NBENCH2", run_nbench2, 0},
8641 {"OPLOCK1", run_oplock1, 0},
8642 {"OPLOCK2", run_oplock2, 0},
8643 {"OPLOCK4", run_oplock4, 0},
8644 {"DIR", run_dirtest, 0},
8645 {"DIR1", run_dirtest1, 0},
8646 {"DIR-CREATETIME", run_dir_createtime, 0},
8647 {"DENY1", torture_denytest1, 0},
8648 {"DENY2", torture_denytest2, 0},
8649 {"TCON", run_tcon_test, 0},
8650 {"TCONDEV", run_tcon_devtype_test, 0},
8651 {"RW1", run_readwritetest, 0},
8652 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8653 {"RW3", run_readwritelarge, 0},
8654 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8655 {"OPEN", run_opentest, 0},
8656 {"POSIX", run_simple_posix_open_test, 0},
8657 {"POSIX-APPEND", run_posix_append, 0},
8658 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8659 {"ASYNC-ECHO", run_async_echo, 0},
8660 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8661 { "SHORTNAME-TEST", run_shortname_test, 0},
8662 { "ADDRCHANGE", run_addrchange, 0},
8664 {"OPENATTR", run_openattrtest, 0},
8666 {"XCOPY", run_xcopy, 0},
8667 {"RENAME", run_rename, 0},
8668 {"DELETE", run_deletetest, 0},
8669 {"DELETE-LN", run_deletetest_ln, 0},
8670 {"PROPERTIES", run_properties, 0},
8671 {"MANGLE", torture_mangle, 0},
8672 {"MANGLE1", run_mangle1, 0},
8673 {"W2K", run_w2ktest, 0},
8674 {"TRANS2SCAN", torture_trans2_scan, 0},
8675 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8676 {"UTABLE", torture_utable, 0},
8677 {"CASETABLE", torture_casetable, 0},
8678 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8679 {"PIPE_NUMBER", run_pipe_number, 0},
8680 {"TCON2", run_tcon2_test, 0},
8681 {"IOCTL", torture_ioctl_test, 0},
8682 {"CHKPATH", torture_chkpath_test, 0},
8683 {"FDSESS", run_fdsesstest, 0},
8684 { "EATEST", run_eatest, 0},
8685 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8686 { "CHAIN1", run_chain1, 0},
8687 { "CHAIN2", run_chain2, 0},
8688 { "WINDOWS-WRITE", run_windows_write, 0},
8689 { "NTTRANS-CREATE", run_nttrans_create, 0},
8690 { "CLI_ECHO", run_cli_echo, 0},
8691 { "GETADDRINFO", run_getaddrinfo_send, 0},
8692 { "TLDAP", run_tldap },
8693 { "STREAMERROR", run_streamerror },
8694 { "NOTIFY-BENCH", run_notify_bench },
8695 { "BAD-NBT-SESSION", run_bad_nbt_session },
8696 { "SMB-ANY-CONNECT", run_smb_any_connect },
8697 { "NOTIFY-ONLINE", run_notify_online },
8698 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8699 { "LOCAL-GENCACHE", run_local_gencache, 0},
8700 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8701 { "LOCAL-BASE64", run_local_base64, 0},
8702 { "LOCAL-RBTREE", run_local_rbtree, 0},
8703 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8704 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8705 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8706 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8707 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8708 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8709 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8710 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8715 /****************************************************************************
8716 run a specified test or "ALL"
8717 ****************************************************************************/
8718 static bool run_test(const char *name)
8725 if (strequal(name,"ALL")) {
8726 for (i=0;torture_ops[i].name;i++) {
8727 run_test(torture_ops[i].name);
8732 for (i=0;torture_ops[i].name;i++) {
8733 fstr_sprintf(randomfname, "\\XX%x",
8734 (unsigned)random());
8736 if (strequal(name, torture_ops[i].name)) {
8738 printf("Running %s\n", name);
8739 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8740 t = create_procs(torture_ops[i].fn, &result);
8743 printf("TEST %s FAILED!\n", name);
8746 struct timeval start;
8747 start = timeval_current();
8748 if (!torture_ops[i].fn(0)) {
8750 printf("TEST %s FAILED!\n", name);
8752 t = timeval_elapsed(&start);
8754 printf("%s took %g secs\n\n", name, t);
8759 printf("Did not find a test named %s\n", name);
8767 static void usage(void)
8771 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8772 printf("Please use samba4 torture.\n\n");
8774 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8776 printf("\t-d debuglevel\n");
8777 printf("\t-U user%%pass\n");
8778 printf("\t-k use kerberos\n");
8779 printf("\t-N numprocs\n");
8780 printf("\t-n my_netbios_name\n");
8781 printf("\t-W workgroup\n");
8782 printf("\t-o num_operations\n");
8783 printf("\t-O socket_options\n");
8784 printf("\t-m maximum protocol\n");
8785 printf("\t-L use oplocks\n");
8786 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8787 printf("\t-A showall\n");
8788 printf("\t-p port\n");
8789 printf("\t-s seed\n");
8790 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8791 printf("\t-f filename filename to test\n");
8794 printf("tests are:");
8795 for (i=0;torture_ops[i].name;i++) {
8796 printf(" %s", torture_ops[i].name);
8800 printf("default test is ALL\n");
8805 /****************************************************************************
8807 ****************************************************************************/
8808 int main(int argc,char *argv[])
8814 bool correct = True;
8815 TALLOC_CTX *frame = talloc_stackframe();
8816 int seed = time(NULL);
8818 #ifdef HAVE_SETBUFFER
8819 setbuffer(stdout, NULL, 0);
8822 setup_logging("smbtorture", DEBUG_STDOUT);
8826 if (is_default_dyn_CONFIGFILE()) {
8827 if(getenv("SMB_CONF_PATH")) {
8828 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8831 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8838 for(p = argv[1]; *p; p++)
8842 if (strncmp(argv[1], "//", 2)) {
8846 fstrcpy(host, &argv[1][2]);
8847 p = strchr_m(&host[2],'/');
8852 fstrcpy(share, p+1);
8854 fstrcpy(myname, get_myname(talloc_tos()));
8856 fprintf(stderr, "Failed to get my hostname.\n");
8860 if (*username == 0 && getenv("LOGNAME")) {
8861 fstrcpy(username,getenv("LOGNAME"));
8867 fstrcpy(workgroup, lp_workgroup());
8869 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8873 port_to_use = atoi(optarg);
8876 seed = atoi(optarg);
8879 fstrcpy(workgroup,optarg);
8882 max_protocol = interpret_protocol(optarg, max_protocol);
8885 nprocs = atoi(optarg);
8888 torture_numops = atoi(optarg);
8891 lp_set_cmdline("log level", optarg);
8900 local_path = optarg;
8903 torture_showall = True;
8906 fstrcpy(myname, optarg);
8909 client_txt = optarg;
8916 use_kerberos = True;
8918 d_printf("No kerberos support compiled in\n");
8924 fstrcpy(username,optarg);
8925 p = strchr_m(username,'%');
8928 fstrcpy(password, p+1);
8933 fstrcpy(multishare_conn_fname, optarg);
8934 use_multishare_conn = True;
8937 torture_blocksize = atoi(optarg);
8940 test_filename = SMB_STRDUP(optarg);
8943 printf("Unknown option %c (%d)\n", (char)opt, opt);
8948 d_printf("using seed %d\n", seed);
8952 if(use_kerberos && !gotuser) gotpass = True;
8955 p = getpass("Password:");
8957 fstrcpy(password, p);
8962 printf("host=%s share=%s user=%s myname=%s\n",
8963 host, share, username, myname);
8965 if (argc == optind) {
8966 correct = run_test("ALL");
8968 for (i=optind;i<argc;i++) {
8969 if (!run_test(argv[i])) {