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 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2791 printf("error: server allowed unlink on an open file\n");
2794 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2795 NT_STATUS_SHARING_VIOLATION);
2798 cli_close(cli, fnum);
2799 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2801 if (!torture_close_connection(cli)) {
2805 printf("unlink test finished\n");
2812 test how many open files this server supports on the one socket
2814 static bool run_maxfidtest(int dummy)
2816 struct cli_state *cli;
2818 uint16_t fnums[0x11000];
2821 bool correct = True;
2827 printf("failed to connect\n");
2831 cli_sockopt(cli, sockops);
2833 for (i=0; i<0x11000; i++) {
2834 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2835 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2837 if (!NT_STATUS_IS_OK(status)) {
2838 printf("open of %s failed (%s)\n",
2839 fname, nt_errstr(status));
2840 printf("maximum fnum is %d\n", i);
2848 printf("cleaning up\n");
2850 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2851 cli_close(cli, fnums[i]);
2853 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2854 if (!NT_STATUS_IS_OK(status)) {
2855 printf("unlink of %s failed (%s)\n",
2856 fname, nt_errstr(status));
2863 printf("maxfid test finished\n");
2864 if (!torture_close_connection(cli)) {
2870 /* generate a random buffer */
2871 static void rand_buf(char *buf, int len)
2874 *buf = (char)sys_random();
2879 /* send smb negprot commands, not reading the response */
2880 static bool run_negprot_nowait(int dummy)
2882 struct tevent_context *ev;
2884 struct cli_state *cli;
2885 bool correct = True;
2887 printf("starting negprot nowait test\n");
2889 ev = tevent_context_init(talloc_tos());
2894 if (!(cli = open_nbt_connection())) {
2899 for (i=0;i<50000;i++) {
2900 struct tevent_req *req;
2902 req = cli_negprot_send(ev, ev, cli);
2907 if (!tevent_req_poll(req, ev)) {
2908 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2916 if (torture_close_connection(cli)) {
2920 printf("finished negprot nowait test\n");
2925 /* send smb negprot commands, not reading the response */
2926 static bool run_bad_nbt_session(int dummy)
2928 struct nmb_name called, calling;
2929 struct sockaddr_storage ss;
2934 printf("starting bad nbt session test\n");
2936 make_nmb_name(&calling, myname, 0x0);
2937 make_nmb_name(&called , host, 0x20);
2939 if (!resolve_name(host, &ss, 0x20, true)) {
2940 d_fprintf(stderr, "Could not resolve name %s\n", host);
2944 status = open_socket_out(&ss, 139, 10000, &fd);
2945 if (!NT_STATUS_IS_OK(status)) {
2946 d_fprintf(stderr, "open_socket_out failed: %s\n",
2951 ret = cli_bad_session_request(fd, &calling, &called);
2954 d_fprintf(stderr, "open_socket_out failed: %s\n",
2959 printf("finished bad nbt session test\n");
2963 /* send random IPC commands */
2964 static bool run_randomipc(int dummy)
2966 char *rparam = NULL;
2968 unsigned int rdrcnt,rprcnt;
2970 int api, param_len, i;
2971 struct cli_state *cli;
2972 bool correct = True;
2975 printf("starting random ipc test\n");
2977 if (!torture_open_connection(&cli, 0)) {
2981 for (i=0;i<count;i++) {
2982 api = sys_random() % 500;
2983 param_len = (sys_random() % 64);
2985 rand_buf(param, param_len);
2990 param, param_len, 8,
2991 NULL, 0, BUFFER_SIZE,
2995 printf("%d/%d\r", i,count);
2998 printf("%d/%d\n", i, count);
3000 if (!torture_close_connection(cli)) {
3004 printf("finished random ipc test\n");
3011 static void browse_callback(const char *sname, uint32 stype,
3012 const char *comment, void *state)
3014 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3020 This test checks the browse list code
3023 static bool run_browsetest(int dummy)
3025 static struct cli_state *cli;
3026 bool correct = True;
3028 printf("starting browse test\n");
3030 if (!torture_open_connection(&cli, 0)) {
3034 printf("domain list:\n");
3035 cli_NetServerEnum(cli, cli->server_domain,
3036 SV_TYPE_DOMAIN_ENUM,
3037 browse_callback, NULL);
3039 printf("machine list:\n");
3040 cli_NetServerEnum(cli, cli->server_domain,
3042 browse_callback, NULL);
3044 if (!torture_close_connection(cli)) {
3048 printf("browse test finished\n");
3056 This checks how the getatr calls works
3058 static bool run_attrtest(int dummy)
3060 struct cli_state *cli;
3063 const char *fname = "\\attrib123456789.tst";
3064 bool correct = True;
3067 printf("starting attrib test\n");
3069 if (!torture_open_connection(&cli, 0)) {
3073 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3074 cli_open(cli, fname,
3075 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3076 cli_close(cli, fnum);
3078 status = cli_getatr(cli, fname, NULL, NULL, &t);
3079 if (!NT_STATUS_IS_OK(status)) {
3080 printf("getatr failed (%s)\n", nt_errstr(status));
3084 if (abs(t - time(NULL)) > 60*60*24*10) {
3085 printf("ERROR: SMBgetatr bug. time is %s",
3091 t2 = t-60*60*24; /* 1 day ago */
3093 status = cli_setatr(cli, fname, 0, t2);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 printf("setatr failed (%s)\n", nt_errstr(status));
3099 status = cli_getatr(cli, fname, NULL, NULL, &t);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("getatr failed (%s)\n", nt_errstr(status));
3106 printf("ERROR: getatr/setatr bug. times are\n%s",
3108 printf("%s", ctime(&t2));
3112 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3114 if (!torture_close_connection(cli)) {
3118 printf("attrib test finished\n");
3125 This checks a couple of trans2 calls
3127 static bool run_trans2test(int dummy)
3129 struct cli_state *cli;
3132 time_t c_time, a_time, m_time;
3133 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3134 const char *fname = "\\trans2.tst";
3135 const char *dname = "\\trans2";
3136 const char *fname2 = "\\trans2\\trans2.tst";
3138 bool correct = True;
3142 printf("starting trans2 test\n");
3144 if (!torture_open_connection(&cli, 0)) {
3148 status = cli_get_fs_attr_info(cli, &fs_attr);
3149 if (!NT_STATUS_IS_OK(status)) {
3150 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3155 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3156 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3157 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3158 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3159 if (!NT_STATUS_IS_OK(status)) {
3160 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3164 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3165 if (!NT_STATUS_IS_OK(status)) {
3166 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3170 if (strcmp(pname, fname)) {
3171 printf("qfilename gave different name? [%s] [%s]\n",
3176 cli_close(cli, fnum);
3180 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3181 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3183 if (!NT_STATUS_IS_OK(status)) {
3184 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3187 cli_close(cli, fnum);
3189 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3191 if (!NT_STATUS_IS_OK(status)) {
3192 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3195 if (c_time != m_time) {
3196 printf("create time=%s", ctime(&c_time));
3197 printf("modify time=%s", ctime(&m_time));
3198 printf("This system appears to have sticky create times\n");
3200 if (a_time % (60*60) == 0) {
3201 printf("access time=%s", ctime(&a_time));
3202 printf("This system appears to set a midnight access time\n");
3206 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3207 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3213 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3214 cli_open(cli, fname,
3215 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3216 cli_close(cli, fnum);
3217 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3218 &m_time_ts, &size, NULL, NULL);
3219 if (!NT_STATUS_IS_OK(status)) {
3220 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3223 if (w_time_ts.tv_sec < 60*60*24*2) {
3224 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3225 printf("This system appears to set a initial 0 write time\n");
3230 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3233 /* check if the server updates the directory modification time
3234 when creating a new file */
3235 status = cli_mkdir(cli, dname);
3236 if (!NT_STATUS_IS_OK(status)) {
3237 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3241 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3242 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3243 if (!NT_STATUS_IS_OK(status)) {
3244 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3248 cli_open(cli, fname2,
3249 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3250 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3251 cli_close(cli, fnum);
3252 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3253 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3258 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3260 printf("This system does not update directory modification times\n");
3264 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3265 cli_rmdir(cli, dname);
3267 if (!torture_close_connection(cli)) {
3271 printf("trans2 test finished\n");
3277 This checks new W2K calls.
3280 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3282 uint8_t *buf = NULL;
3286 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3287 pcli->max_xmit, NULL, &buf, &len);
3288 if (!NT_STATUS_IS_OK(status)) {
3289 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3292 printf("qfileinfo: level %d, len = %u\n", level, len);
3293 dump_data(0, (uint8 *)buf, len);
3300 static bool run_w2ktest(int dummy)
3302 struct cli_state *cli;
3304 const char *fname = "\\w2ktest\\w2k.tst";
3306 bool correct = True;
3308 printf("starting w2k test\n");
3310 if (!torture_open_connection(&cli, 0)) {
3314 cli_open(cli, fname,
3315 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3317 for (level = 1004; level < 1040; level++) {
3318 new_trans(cli, fnum, level);
3321 cli_close(cli, fnum);
3323 if (!torture_close_connection(cli)) {
3327 printf("w2k test finished\n");
3334 this is a harness for some oplock tests
3336 static bool run_oplock1(int dummy)
3338 struct cli_state *cli1;
3339 const char *fname = "\\lockt1.lck";
3341 bool correct = True;
3344 printf("starting oplock test 1\n");
3346 if (!torture_open_connection(&cli1, 0)) {
3350 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3352 cli_sockopt(cli1, sockops);
3354 cli1->use_oplocks = True;
3356 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3358 if (!NT_STATUS_IS_OK(status)) {
3359 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3363 cli1->use_oplocks = False;
3365 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3366 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3368 status = cli_close(cli1, fnum1);
3369 if (!NT_STATUS_IS_OK(status)) {
3370 printf("close2 failed (%s)\n", nt_errstr(status));
3374 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3375 if (!NT_STATUS_IS_OK(status)) {
3376 printf("unlink failed (%s)\n", nt_errstr(status));
3380 if (!torture_close_connection(cli1)) {
3384 printf("finished oplock test 1\n");
3389 static bool run_oplock2(int dummy)
3391 struct cli_state *cli1, *cli2;
3392 const char *fname = "\\lockt2.lck";
3393 uint16_t fnum1, fnum2;
3394 int saved_use_oplocks = use_oplocks;
3396 bool correct = True;
3397 volatile bool *shared_correct;
3400 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3401 *shared_correct = True;
3403 use_level_II_oplocks = True;
3406 printf("starting oplock test 2\n");
3408 if (!torture_open_connection(&cli1, 0)) {
3409 use_level_II_oplocks = False;
3410 use_oplocks = saved_use_oplocks;
3414 cli1->use_oplocks = True;
3415 cli1->use_level_II_oplocks = True;
3417 if (!torture_open_connection(&cli2, 1)) {
3418 use_level_II_oplocks = False;
3419 use_oplocks = saved_use_oplocks;
3423 cli2->use_oplocks = True;
3424 cli2->use_level_II_oplocks = True;
3426 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3428 cli_sockopt(cli1, sockops);
3429 cli_sockopt(cli2, sockops);
3431 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3433 if (!NT_STATUS_IS_OK(status)) {
3434 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3438 /* Don't need the globals any more. */
3439 use_level_II_oplocks = False;
3440 use_oplocks = saved_use_oplocks;
3444 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3445 if (!NT_STATUS_IS_OK(status)) {
3446 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3447 *shared_correct = False;
3453 status = cli_close(cli2, fnum2);
3454 if (!NT_STATUS_IS_OK(status)) {
3455 printf("close2 failed (%s)\n", nt_errstr(status));
3456 *shared_correct = False;
3464 /* Ensure cli1 processes the break. Empty file should always return 0
3467 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3468 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3472 /* Should now be at level II. */
3473 /* Test if sending a write locks causes a break to none. */
3475 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3476 printf("lock failed (%s)\n", cli_errstr(cli1));
3480 cli_unlock(cli1, fnum1, 0, 4);
3484 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3485 printf("lock failed (%s)\n", cli_errstr(cli1));
3489 cli_unlock(cli1, fnum1, 0, 4);
3493 cli_read(cli1, fnum1, buf, 0, 4);
3495 status = cli_close(cli1, fnum1);
3496 if (!NT_STATUS_IS_OK(status)) {
3497 printf("close1 failed (%s)\n", nt_errstr(status));
3503 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3504 if (!NT_STATUS_IS_OK(status)) {
3505 printf("unlink failed (%s)\n", nt_errstr(status));
3509 if (!torture_close_connection(cli1)) {
3513 if (!*shared_correct) {
3517 printf("finished oplock test 2\n");
3522 struct oplock4_state {
3523 struct tevent_context *ev;
3524 struct cli_state *cli;
3529 static void oplock4_got_break(struct tevent_req *req);
3530 static void oplock4_got_open(struct tevent_req *req);
3532 static bool run_oplock4(int dummy)
3534 struct tevent_context *ev;
3535 struct cli_state *cli1, *cli2;
3536 struct tevent_req *oplock_req, *open_req;
3537 const char *fname = "\\lockt4.lck";
3538 const char *fname_ln = "\\lockt4_ln.lck";
3539 uint16_t fnum1, fnum2;
3540 int saved_use_oplocks = use_oplocks;
3542 bool correct = true;
3546 struct oplock4_state *state;
3548 printf("starting oplock test 4\n");
3550 if (!torture_open_connection(&cli1, 0)) {
3551 use_level_II_oplocks = false;
3552 use_oplocks = saved_use_oplocks;
3556 if (!torture_open_connection(&cli2, 1)) {
3557 use_level_II_oplocks = false;
3558 use_oplocks = saved_use_oplocks;
3562 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3563 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3565 cli_sockopt(cli1, sockops);
3566 cli_sockopt(cli2, sockops);
3568 /* Create the file. */
3569 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3571 if (!NT_STATUS_IS_OK(status)) {
3572 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3576 status = cli_close(cli1, fnum1);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 printf("close1 failed (%s)\n", nt_errstr(status));
3582 /* Now create a hardlink. */
3583 status = cli_nt_hardlink(cli1, fname, fname_ln);
3584 if (!NT_STATUS_IS_OK(status)) {
3585 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3589 /* Prove that opening hardlinks cause deny modes to conflict. */
3590 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3596 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3597 if (NT_STATUS_IS_OK(status)) {
3598 printf("open of %s succeeded - should fail with sharing violation.\n",
3603 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3604 printf("open of %s should fail with sharing violation. Got %s\n",
3605 fname_ln, nt_errstr(status));
3609 status = cli_close(cli1, fnum1);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("close1 failed (%s)\n", nt_errstr(status));
3615 cli1->use_oplocks = true;
3616 cli1->use_level_II_oplocks = true;
3618 cli2->use_oplocks = true;
3619 cli2->use_level_II_oplocks = true;
3621 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3622 if (!NT_STATUS_IS_OK(status)) {
3623 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3627 ev = tevent_context_init(talloc_tos());
3629 printf("tevent_req_create failed\n");
3633 state = talloc(ev, struct oplock4_state);
3634 if (state == NULL) {
3635 printf("talloc failed\n");
3640 state->got_break = &got_break;
3641 state->fnum2 = &fnum2;
3643 oplock_req = cli_smb_oplock_break_waiter_send(
3644 talloc_tos(), ev, cli1);
3645 if (oplock_req == NULL) {
3646 printf("cli_smb_oplock_break_waiter_send failed\n");
3649 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3651 open_req = cli_open_send(
3652 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3653 if (oplock_req == NULL) {
3654 printf("cli_open_send failed\n");
3657 tevent_req_set_callback(open_req, oplock4_got_open, state);
3662 while (!got_break || fnum2 == 0xffff) {
3664 ret = tevent_loop_once(ev);
3666 printf("tevent_loop_once failed: %s\n",
3672 status = cli_close(cli2, fnum2);
3673 if (!NT_STATUS_IS_OK(status)) {
3674 printf("close2 failed (%s)\n", nt_errstr(status));
3678 status = cli_close(cli1, fnum1);
3679 if (!NT_STATUS_IS_OK(status)) {
3680 printf("close1 failed (%s)\n", nt_errstr(status));
3684 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3685 if (!NT_STATUS_IS_OK(status)) {
3686 printf("unlink failed (%s)\n", nt_errstr(status));
3690 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3691 if (!NT_STATUS_IS_OK(status)) {
3692 printf("unlink failed (%s)\n", nt_errstr(status));
3696 if (!torture_close_connection(cli1)) {
3704 printf("finished oplock test 4\n");
3709 static void oplock4_got_break(struct tevent_req *req)
3711 struct oplock4_state *state = tevent_req_callback_data(
3712 req, struct oplock4_state);
3717 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3719 if (!NT_STATUS_IS_OK(status)) {
3720 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3724 *state->got_break = true;
3726 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3729 printf("cli_oplock_ack_send failed\n");
3734 static void oplock4_got_open(struct tevent_req *req)
3736 struct oplock4_state *state = tevent_req_callback_data(
3737 req, struct oplock4_state);
3740 status = cli_open_recv(req, state->fnum2);
3741 if (!NT_STATUS_IS_OK(status)) {
3742 printf("cli_open_recv returned %s\n", nt_errstr(status));
3743 *state->fnum2 = 0xffff;
3748 Test delete on close semantics.
3750 static bool run_deletetest(int dummy)
3752 struct cli_state *cli1 = NULL;
3753 struct cli_state *cli2 = NULL;
3754 const char *fname = "\\delete.file";
3755 uint16_t fnum1 = (uint16_t)-1;
3756 uint16_t fnum2 = (uint16_t)-1;
3757 bool correct = True;
3760 printf("starting delete test\n");
3762 if (!torture_open_connection(&cli1, 0)) {
3766 cli_sockopt(cli1, sockops);
3768 /* Test 1 - this should delete the file on close. */
3770 cli_setatr(cli1, fname, 0, 0);
3771 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3773 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3774 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3775 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3776 if (!NT_STATUS_IS_OK(status)) {
3777 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3782 status = cli_close(cli1, fnum1);
3783 if (!NT_STATUS_IS_OK(status)) {
3784 printf("[1] close failed (%s)\n", nt_errstr(status));
3789 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3790 printf("[1] open of %s succeeded (should fail)\n", fname);
3795 printf("first delete on close test succeeded.\n");
3797 /* Test 2 - this should delete the file on close. */
3799 cli_setatr(cli1, fname, 0, 0);
3800 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3802 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3803 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3804 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3805 if (!NT_STATUS_IS_OK(status)) {
3806 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3811 status = cli_nt_delete_on_close(cli1, fnum1, true);
3812 if (!NT_STATUS_IS_OK(status)) {
3813 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3818 status = cli_close(cli1, fnum1);
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("[2] close failed (%s)\n", nt_errstr(status));
3825 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3826 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3827 status = cli_close(cli1, fnum1);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 printf("[2] close failed (%s)\n", nt_errstr(status));
3833 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3835 printf("second delete on close test succeeded.\n");
3838 cli_setatr(cli1, fname, 0, 0);
3839 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3841 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3842 FILE_ATTRIBUTE_NORMAL,
3843 FILE_SHARE_READ|FILE_SHARE_WRITE,
3844 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3845 if (!NT_STATUS_IS_OK(status)) {
3846 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3851 /* This should fail with a sharing violation - open for delete is only compatible
3852 with SHARE_DELETE. */
3854 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3855 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3856 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3861 /* This should succeed. */
3862 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3863 FILE_ATTRIBUTE_NORMAL,
3864 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3865 FILE_OPEN, 0, 0, &fnum2);
3866 if (!NT_STATUS_IS_OK(status)) {
3867 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3872 status = cli_nt_delete_on_close(cli1, fnum1, true);
3873 if (!NT_STATUS_IS_OK(status)) {
3874 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3879 status = cli_close(cli1, fnum1);
3880 if (!NT_STATUS_IS_OK(status)) {
3881 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3886 status = cli_close(cli1, fnum2);
3887 if (!NT_STATUS_IS_OK(status)) {
3888 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3893 /* This should fail - file should no longer be there. */
3895 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3896 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3897 status = cli_close(cli1, fnum1);
3898 if (!NT_STATUS_IS_OK(status)) {
3899 printf("[3] close failed (%s)\n", nt_errstr(status));
3901 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3905 printf("third delete on close test succeeded.\n");
3908 cli_setatr(cli1, fname, 0, 0);
3909 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3911 status = cli_ntcreate(cli1, fname, 0,
3912 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3913 FILE_ATTRIBUTE_NORMAL,
3914 FILE_SHARE_READ|FILE_SHARE_WRITE,
3915 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3922 /* This should succeed. */
3923 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3924 FILE_ATTRIBUTE_NORMAL,
3925 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3926 FILE_OPEN, 0, 0, &fnum2);
3927 if (!NT_STATUS_IS_OK(status)) {
3928 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3933 status = cli_close(cli1, fnum2);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3940 status = cli_nt_delete_on_close(cli1, fnum1, true);
3941 if (!NT_STATUS_IS_OK(status)) {
3942 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3947 /* This should fail - no more opens once delete on close set. */
3948 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3950 FILE_OPEN, 0, 0, &fnum2))) {
3951 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3955 printf("fourth delete on close test succeeded.\n");
3957 status = cli_close(cli1, fnum1);
3958 if (!NT_STATUS_IS_OK(status)) {
3959 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3965 cli_setatr(cli1, fname, 0, 0);
3966 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3968 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3975 /* This should fail - only allowed on NT opens with DELETE access. */
3977 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3978 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3983 status = cli_close(cli1, fnum1);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3990 printf("fifth delete on close test succeeded.\n");
3993 cli_setatr(cli1, fname, 0, 0);
3994 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3996 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3997 FILE_ATTRIBUTE_NORMAL,
3998 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3999 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4000 if (!NT_STATUS_IS_OK(status)) {
4001 printf("[6] open of %s failed (%s)\n", fname,
4007 /* This should fail - only allowed on NT opens with DELETE access. */
4009 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4010 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4015 status = cli_close(cli1, fnum1);
4016 if (!NT_STATUS_IS_OK(status)) {
4017 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4022 printf("sixth delete on close test succeeded.\n");
4025 cli_setatr(cli1, fname, 0, 0);
4026 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4028 status = cli_ntcreate(cli1, fname, 0,
4029 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4030 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4038 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4039 printf("[7] setting delete_on_close on file failed !\n");
4044 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4045 printf("[7] unsetting delete_on_close on file failed !\n");
4050 status = cli_close(cli1, fnum1);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4057 /* This next open should succeed - we reset the flag. */
4058 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4059 if (!NT_STATUS_IS_OK(status)) {
4060 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4065 status = cli_close(cli1, fnum1);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4072 printf("seventh delete on close test succeeded.\n");
4075 cli_setatr(cli1, fname, 0, 0);
4076 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4078 if (!torture_open_connection(&cli2, 1)) {
4079 printf("[8] failed to open second connection.\n");
4084 cli_sockopt(cli1, sockops);
4086 status = cli_ntcreate(cli1, fname, 0,
4087 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4088 FILE_ATTRIBUTE_NORMAL,
4089 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4090 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4091 if (!NT_STATUS_IS_OK(status)) {
4092 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4097 status = cli_ntcreate(cli2, fname, 0,
4098 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4099 FILE_ATTRIBUTE_NORMAL,
4100 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4101 FILE_OPEN, 0, 0, &fnum2);
4102 if (!NT_STATUS_IS_OK(status)) {
4103 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4108 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4109 printf("[8] setting delete_on_close on file failed !\n");
4114 status = cli_close(cli1, fnum1);
4115 if (!NT_STATUS_IS_OK(status)) {
4116 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4121 status = cli_close(cli2, fnum2);
4122 if (!NT_STATUS_IS_OK(status)) {
4123 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4128 /* This should fail.. */
4129 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4130 if (NT_STATUS_IS_OK(status)) {
4131 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4135 printf("eighth delete on close test succeeded.\n");
4137 /* This should fail - we need to set DELETE_ACCESS. */
4138 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4139 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4140 printf("[9] open of %s succeeded should have failed!\n", fname);
4145 printf("ninth delete on close test succeeded.\n");
4147 status = cli_ntcreate(cli1, fname, 0,
4148 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4149 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4150 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4152 if (!NT_STATUS_IS_OK(status)) {
4153 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4158 /* This should delete the file. */
4159 status = cli_close(cli1, fnum1);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 printf("[10] close failed (%s)\n", nt_errstr(status));
4166 /* This should fail.. */
4167 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4168 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4172 printf("tenth delete on close test succeeded.\n");
4174 cli_setatr(cli1, fname, 0, 0);
4175 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4177 /* What error do we get when attempting to open a read-only file with
4180 /* Create a readonly file. */
4181 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4182 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4183 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4184 if (!NT_STATUS_IS_OK(status)) {
4185 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4190 status = cli_close(cli1, fnum1);
4191 if (!NT_STATUS_IS_OK(status)) {
4192 printf("[11] close failed (%s)\n", nt_errstr(status));
4197 /* Now try open for delete access. */
4198 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4199 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4200 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4201 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4202 cli_close(cli1, fnum1);
4206 NTSTATUS nterr = cli_nt_error(cli1);
4207 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4208 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4212 printf("eleventh delete on close test succeeded.\n");
4216 printf("finished delete test\n");
4219 /* FIXME: This will crash if we aborted before cli2 got
4220 * intialized, because these functions don't handle
4221 * uninitialized connections. */
4223 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4224 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4225 cli_setatr(cli1, fname, 0, 0);
4226 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4228 if (cli1 && !torture_close_connection(cli1)) {
4231 if (cli2 && !torture_close_connection(cli2)) {
4237 static bool run_deletetest_ln(int dummy)
4239 struct cli_state *cli;
4240 const char *fname = "\\delete1";
4241 const char *fname_ln = "\\delete1_ln";
4245 bool correct = true;
4248 printf("starting deletetest-ln\n");
4250 if (!torture_open_connection(&cli, 0)) {
4254 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4255 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4257 cli_sockopt(cli, sockops);
4259 /* Create the file. */
4260 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4261 if (!NT_STATUS_IS_OK(status)) {
4262 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4266 status = cli_close(cli, fnum);
4267 if (!NT_STATUS_IS_OK(status)) {
4268 printf("close1 failed (%s)\n", nt_errstr(status));
4272 /* Now create a hardlink. */
4273 status = cli_nt_hardlink(cli, fname, fname_ln);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4279 /* Open the original file. */
4280 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4281 FILE_ATTRIBUTE_NORMAL,
4282 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4283 FILE_OPEN_IF, 0, 0, &fnum);
4284 if (!NT_STATUS_IS_OK(status)) {
4285 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4289 /* Unlink the hard link path. */
4290 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4291 FILE_ATTRIBUTE_NORMAL,
4292 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4293 FILE_OPEN_IF, 0, 0, &fnum1);
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4298 status = cli_nt_delete_on_close(cli, fnum1, true);
4299 if (!NT_STATUS_IS_OK(status)) {
4300 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4301 __location__, fname_ln, nt_errstr(status));
4305 status = cli_close(cli, fnum1);
4306 if (!NT_STATUS_IS_OK(status)) {
4307 printf("close %s failed (%s)\n",
4308 fname_ln, nt_errstr(status));
4312 status = cli_close(cli, fnum);
4313 if (!NT_STATUS_IS_OK(status)) {
4314 printf("close %s failed (%s)\n",
4315 fname, nt_errstr(status));
4319 /* Ensure the original file is still there. */
4320 status = cli_getatr(cli, fname, NULL, NULL, &t);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("%s getatr on file %s failed (%s)\n",
4329 /* Ensure the link path is gone. */
4330 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4331 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4332 printf("%s, getatr for file %s returned wrong error code %s "
4333 "- should have been deleted\n",
4335 fname_ln, nt_errstr(status));
4339 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4340 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4342 if (!torture_close_connection(cli)) {
4346 printf("finished deletetest-ln\n");
4352 print out server properties
4354 static bool run_properties(int dummy)
4356 struct cli_state *cli;
4357 bool correct = True;
4359 printf("starting properties test\n");
4363 if (!torture_open_connection(&cli, 0)) {
4367 cli_sockopt(cli, sockops);
4369 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4371 if (!torture_close_connection(cli)) {
4380 /* FIRST_DESIRED_ACCESS 0xf019f */
4381 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4382 FILE_READ_EA| /* 0xf */ \
4383 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4384 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4385 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4386 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4387 /* SECOND_DESIRED_ACCESS 0xe0080 */
4388 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4389 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4390 WRITE_OWNER_ACCESS /* 0xe0000 */
4393 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4394 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4396 WRITE_OWNER_ACCESS /* */
4400 Test ntcreate calls made by xcopy
4402 static bool run_xcopy(int dummy)
4404 static struct cli_state *cli1;
4405 const char *fname = "\\test.txt";
4406 bool correct = True;
4407 uint16_t fnum1, fnum2;
4410 printf("starting xcopy test\n");
4412 if (!torture_open_connection(&cli1, 0)) {
4416 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4417 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4418 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4419 if (!NT_STATUS_IS_OK(status)) {
4420 printf("First open failed - %s\n", nt_errstr(status));
4424 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4425 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4426 FILE_OPEN, 0x200000, 0, &fnum2);
4427 if (!NT_STATUS_IS_OK(status)) {
4428 printf("second open failed - %s\n", nt_errstr(status));
4432 if (!torture_close_connection(cli1)) {
4440 Test rename on files open with share delete and no share delete.
4442 static bool run_rename(int dummy)
4444 static struct cli_state *cli1;
4445 const char *fname = "\\test.txt";
4446 const char *fname1 = "\\test1.txt";
4447 bool correct = True;
4452 printf("starting rename test\n");
4454 if (!torture_open_connection(&cli1, 0)) {
4458 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4459 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4461 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4462 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4463 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4464 if (!NT_STATUS_IS_OK(status)) {
4465 printf("First open failed - %s\n", nt_errstr(status));
4469 status = cli_rename(cli1, fname, fname1);
4470 if (!NT_STATUS_IS_OK(status)) {
4471 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4473 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4477 status = cli_close(cli1, fnum1);
4478 if (!NT_STATUS_IS_OK(status)) {
4479 printf("close - 1 failed (%s)\n", nt_errstr(status));
4483 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4484 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4485 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4487 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4489 FILE_SHARE_DELETE|FILE_SHARE_READ,
4491 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4492 if (!NT_STATUS_IS_OK(status)) {
4493 printf("Second open failed - %s\n", nt_errstr(status));
4497 status = cli_rename(cli1, fname, fname1);
4498 if (!NT_STATUS_IS_OK(status)) {
4499 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4502 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4505 status = cli_close(cli1, fnum1);
4506 if (!NT_STATUS_IS_OK(status)) {
4507 printf("close - 2 failed (%s)\n", nt_errstr(status));
4511 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4512 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4514 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4515 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4516 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4517 if (!NT_STATUS_IS_OK(status)) {
4518 printf("Third open failed - %s\n", nt_errstr(status));
4527 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4528 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4529 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4532 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4533 printf("[8] setting delete_on_close on file failed !\n");
4537 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4538 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4544 status = cli_rename(cli1, fname, fname1);
4545 if (!NT_STATUS_IS_OK(status)) {
4546 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4549 printf("Third rename succeeded (SHARE_NONE)\n");
4552 status = cli_close(cli1, fnum1);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 printf("close - 3 failed (%s)\n", nt_errstr(status));
4558 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4559 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4563 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4564 FILE_ATTRIBUTE_NORMAL,
4565 FILE_SHARE_READ | FILE_SHARE_WRITE,
4566 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4567 if (!NT_STATUS_IS_OK(status)) {
4568 printf("Fourth open failed - %s\n", nt_errstr(status));
4572 status = cli_rename(cli1, fname, fname1);
4573 if (!NT_STATUS_IS_OK(status)) {
4574 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4576 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4580 status = cli_close(cli1, fnum1);
4581 if (!NT_STATUS_IS_OK(status)) {
4582 printf("close - 4 failed (%s)\n", nt_errstr(status));
4586 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4587 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4591 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4592 FILE_ATTRIBUTE_NORMAL,
4593 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4594 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("Fifth open failed - %s\n", nt_errstr(status));
4600 status = cli_rename(cli1, fname, fname1);
4601 if (!NT_STATUS_IS_OK(status)) {
4602 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4605 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4609 * Now check if the first name still exists ...
4612 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4613 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4614 printf("Opening original file after rename of open file fails: %s\n",
4618 printf("Opening original file after rename of open file works ...\n");
4619 (void)cli_close(cli1, fnum2);
4623 status = cli_close(cli1, fnum1);
4624 if (!NT_STATUS_IS_OK(status)) {
4625 printf("close - 5 failed (%s)\n", nt_errstr(status));
4629 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4630 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4631 if (!NT_STATUS_IS_OK(status)) {
4632 printf("getatr on file %s failed - %s ! \n",
4633 fname1, nt_errstr(status));
4636 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4637 printf("Renamed file %s has wrong attr 0x%x "
4638 "(should be 0x%x)\n",
4641 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4644 printf("Renamed file %s has archive bit set\n", fname1);
4648 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4649 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4651 if (!torture_close_connection(cli1)) {
4658 static bool run_pipe_number(int dummy)
4660 struct cli_state *cli1;
4661 const char *pipe_name = "\\SPOOLSS";
4666 printf("starting pipenumber test\n");
4667 if (!torture_open_connection(&cli1, 0)) {
4671 cli_sockopt(cli1, sockops);
4673 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4674 FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_READ|FILE_SHARE_WRITE,
4676 FILE_OPEN_IF, 0, 0, &fnum);
4677 if (!NT_STATUS_IS_OK(status)) {
4678 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4682 printf("\r%6d", num_pipes);
4685 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4686 torture_close_connection(cli1);
4691 Test open mode returns on read-only files.
4693 static bool run_opentest(int dummy)
4695 static struct cli_state *cli1;
4696 static struct cli_state *cli2;
4697 const char *fname = "\\readonly.file";
4698 uint16_t fnum1, fnum2;
4701 bool correct = True;
4705 printf("starting open test\n");
4707 if (!torture_open_connection(&cli1, 0)) {
4711 cli_setatr(cli1, fname, 0, 0);
4712 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4714 cli_sockopt(cli1, sockops);
4716 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4717 if (!NT_STATUS_IS_OK(status)) {
4718 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4722 status = cli_close(cli1, fnum1);
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("close2 failed (%s)\n", nt_errstr(status));
4728 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4729 if (!NT_STATUS_IS_OK(status)) {
4730 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4734 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4735 if (!NT_STATUS_IS_OK(status)) {
4736 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4740 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4741 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4743 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4744 NT_STATUS_ACCESS_DENIED)) {
4745 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4748 printf("finished open test 1\n");
4750 cli_close(cli1, fnum1);
4752 /* Now try not readonly and ensure ERRbadshare is returned. */
4754 cli_setatr(cli1, fname, 0, 0);
4756 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4757 if (!NT_STATUS_IS_OK(status)) {
4758 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4762 /* This will fail - but the error should be ERRshare. */
4763 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4765 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4766 NT_STATUS_SHARING_VIOLATION)) {
4767 printf("correct error code ERRDOS/ERRbadshare returned\n");
4770 status = cli_close(cli1, fnum1);
4771 if (!NT_STATUS_IS_OK(status)) {
4772 printf("close2 failed (%s)\n", nt_errstr(status));
4776 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4778 printf("finished open test 2\n");
4780 /* Test truncate open disposition on file opened for read. */
4781 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4782 if (!NT_STATUS_IS_OK(status)) {
4783 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4787 /* write 20 bytes. */
4789 memset(buf, '\0', 20);
4791 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4792 if (!NT_STATUS_IS_OK(status)) {
4793 printf("write failed (%s)\n", nt_errstr(status));
4797 status = cli_close(cli1, fnum1);
4798 if (!NT_STATUS_IS_OK(status)) {
4799 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4803 /* Ensure size == 20. */
4804 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4805 if (!NT_STATUS_IS_OK(status)) {
4806 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4811 printf("(3) file size != 20\n");
4815 /* Now test if we can truncate a file opened for readonly. */
4816 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4817 if (!NT_STATUS_IS_OK(status)) {
4818 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4822 status = cli_close(cli1, fnum1);
4823 if (!NT_STATUS_IS_OK(status)) {
4824 printf("close2 failed (%s)\n", nt_errstr(status));
4828 /* Ensure size == 0. */
4829 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4830 if (!NT_STATUS_IS_OK(status)) {
4831 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4836 printf("(3) file size != 0\n");
4839 printf("finished open test 3\n");
4841 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4843 printf("Do ctemp tests\n");
4844 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4845 if (!NT_STATUS_IS_OK(status)) {
4846 printf("ctemp failed (%s)\n", nt_errstr(status));
4850 printf("ctemp gave path %s\n", tmp_path);
4851 status = cli_close(cli1, fnum1);
4852 if (!NT_STATUS_IS_OK(status)) {
4853 printf("close of temp failed (%s)\n", nt_errstr(status));
4856 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4861 /* Test the non-io opens... */
4863 if (!torture_open_connection(&cli2, 1)) {
4867 cli_setatr(cli2, fname, 0, 0);
4868 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4870 cli_sockopt(cli2, sockops);
4872 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4873 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4874 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4875 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4881 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4882 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4883 FILE_OPEN_IF, 0, 0, &fnum2);
4884 if (!NT_STATUS_IS_OK(status)) {
4885 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4889 status = cli_close(cli1, fnum1);
4890 if (!NT_STATUS_IS_OK(status)) {
4891 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4895 status = cli_close(cli2, fnum2);
4896 if (!NT_STATUS_IS_OK(status)) {
4897 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4901 printf("non-io open test #1 passed.\n");
4903 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4905 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4907 status = cli_ntcreate(cli1, fname, 0,
4908 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4909 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4910 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4916 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4917 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4918 FILE_OPEN_IF, 0, 0, &fnum2);
4919 if (!NT_STATUS_IS_OK(status)) {
4920 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4924 status = cli_close(cli1, fnum1);
4925 if (!NT_STATUS_IS_OK(status)) {
4926 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4930 status = cli_close(cli2, fnum2);
4931 if (!NT_STATUS_IS_OK(status)) {
4932 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4936 printf("non-io open test #2 passed.\n");
4938 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4940 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4942 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4943 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4944 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4950 status = cli_ntcreate(cli2, fname, 0,
4951 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4952 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4953 FILE_OPEN_IF, 0, 0, &fnum2);
4954 if (!NT_STATUS_IS_OK(status)) {
4955 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4959 status = cli_close(cli1, fnum1);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4965 status = cli_close(cli2, fnum2);
4966 if (!NT_STATUS_IS_OK(status)) {
4967 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4971 printf("non-io open test #3 passed.\n");
4973 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4975 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4977 status = cli_ntcreate(cli1, fname, 0,
4978 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4979 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4980 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4981 if (!NT_STATUS_IS_OK(status)) {
4982 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4986 status = cli_ntcreate(cli2, fname, 0,
4987 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4988 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4989 FILE_OPEN_IF, 0, 0, &fnum2);
4990 if (NT_STATUS_IS_OK(status)) {
4991 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4995 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4997 status = cli_close(cli1, fnum1);
4998 if (!NT_STATUS_IS_OK(status)) {
4999 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5003 printf("non-io open test #4 passed.\n");
5005 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5007 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5009 status = cli_ntcreate(cli1, fname, 0,
5010 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5011 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5012 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5018 status = cli_ntcreate(cli2, fname, 0,
5019 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5020 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5021 FILE_OPEN_IF, 0, 0, &fnum2);
5022 if (!NT_STATUS_IS_OK(status)) {
5023 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5027 status = cli_close(cli1, fnum1);
5028 if (!NT_STATUS_IS_OK(status)) {
5029 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5033 status = cli_close(cli2, fnum2);
5034 if (!NT_STATUS_IS_OK(status)) {
5035 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5039 printf("non-io open test #5 passed.\n");
5041 printf("TEST #6 testing 1 non-io open, one io open\n");
5043 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5045 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5046 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5047 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5048 if (!NT_STATUS_IS_OK(status)) {
5049 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5053 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5054 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5055 FILE_OPEN_IF, 0, 0, &fnum2);
5056 if (!NT_STATUS_IS_OK(status)) {
5057 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5061 status = cli_close(cli1, fnum1);
5062 if (!NT_STATUS_IS_OK(status)) {
5063 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5067 status = cli_close(cli2, fnum2);
5068 if (!NT_STATUS_IS_OK(status)) {
5069 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5073 printf("non-io open test #6 passed.\n");
5075 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5077 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5079 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5080 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5081 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5082 if (!NT_STATUS_IS_OK(status)) {
5083 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5087 status = cli_ntcreate(cli2, fname, 0,
5088 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5089 FILE_ATTRIBUTE_NORMAL,
5090 FILE_SHARE_READ|FILE_SHARE_DELETE,
5091 FILE_OPEN_IF, 0, 0, &fnum2);
5092 if (NT_STATUS_IS_OK(status)) {
5093 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5097 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5099 status = cli_close(cli1, fnum1);
5100 if (!NT_STATUS_IS_OK(status)) {
5101 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5105 printf("non-io open test #7 passed.\n");
5107 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5109 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5110 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5111 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5112 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5113 if (!NT_STATUS_IS_OK(status)) {
5114 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5119 /* Write to ensure we have to update the file time. */
5120 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5122 if (!NT_STATUS_IS_OK(status)) {
5123 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5128 status = cli_close(cli1, fnum1);
5129 if (!NT_STATUS_IS_OK(status)) {
5130 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5136 if (!torture_close_connection(cli1)) {
5139 if (!torture_close_connection(cli2)) {
5146 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5148 uint16 major, minor;
5149 uint32 caplow, caphigh;
5152 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5153 printf("Server doesn't support UNIX CIFS extensions.\n");
5154 return NT_STATUS_NOT_SUPPORTED;
5157 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5159 if (!NT_STATUS_IS_OK(status)) {
5160 printf("Server didn't return UNIX CIFS extensions: %s\n",
5165 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5167 if (!NT_STATUS_IS_OK(status)) {
5168 printf("Server doesn't support setting UNIX CIFS extensions: "
5169 "%s.\n", nt_errstr(status));
5173 return NT_STATUS_OK;
5177 Test POSIX open /mkdir calls.
5179 static bool run_simple_posix_open_test(int dummy)
5181 static struct cli_state *cli1;
5182 const char *fname = "posix:file";
5183 const char *hname = "posix:hlink";
5184 const char *sname = "posix:symlink";
5185 const char *dname = "posix:dir";
5188 uint16_t fnum1 = (uint16_t)-1;
5189 SMB_STRUCT_STAT sbuf;
5190 bool correct = false;
5193 printf("Starting simple POSIX open test\n");
5195 if (!torture_open_connection(&cli1, 0)) {
5199 cli_sockopt(cli1, sockops);
5201 status = torture_setup_unix_extensions(cli1);
5202 if (!NT_STATUS_IS_OK(status)) {
5206 cli_setatr(cli1, fname, 0, 0);
5207 cli_posix_unlink(cli1, fname);
5208 cli_setatr(cli1, dname, 0, 0);
5209 cli_posix_rmdir(cli1, dname);
5210 cli_setatr(cli1, hname, 0, 0);
5211 cli_posix_unlink(cli1, hname);
5212 cli_setatr(cli1, sname, 0, 0);
5213 cli_posix_unlink(cli1, sname);
5215 /* Create a directory. */
5216 status = cli_posix_mkdir(cli1, dname, 0777);
5217 if (!NT_STATUS_IS_OK(status)) {
5218 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5222 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5224 if (!NT_STATUS_IS_OK(status)) {
5225 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5229 /* Test ftruncate - set file size. */
5230 status = cli_ftruncate(cli1, fnum1, 1000);
5231 if (!NT_STATUS_IS_OK(status)) {
5232 printf("ftruncate failed (%s)\n", nt_errstr(status));
5236 /* Ensure st_size == 1000 */
5237 status = cli_posix_stat(cli1, fname, &sbuf);
5238 if (!NT_STATUS_IS_OK(status)) {
5239 printf("stat failed (%s)\n", nt_errstr(status));
5243 if (sbuf.st_ex_size != 1000) {
5244 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5248 /* Test ftruncate - set file size back to zero. */
5249 status = cli_ftruncate(cli1, fnum1, 0);
5250 if (!NT_STATUS_IS_OK(status)) {
5251 printf("ftruncate failed (%s)\n", nt_errstr(status));
5255 status = cli_close(cli1, fnum1);
5256 if (!NT_STATUS_IS_OK(status)) {
5257 printf("close failed (%s)\n", nt_errstr(status));
5261 /* Now open the file again for read only. */
5262 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5263 if (!NT_STATUS_IS_OK(status)) {
5264 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5268 /* Now unlink while open. */
5269 status = cli_posix_unlink(cli1, fname);
5270 if (!NT_STATUS_IS_OK(status)) {
5271 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5275 status = cli_close(cli1, fnum1);
5276 if (!NT_STATUS_IS_OK(status)) {
5277 printf("close(2) failed (%s)\n", nt_errstr(status));
5281 /* Ensure the file has gone. */
5282 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5283 if (NT_STATUS_IS_OK(status)) {
5284 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5288 /* Create again to test open with O_TRUNC. */
5289 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5290 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5294 /* Test ftruncate - set file size. */
5295 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5296 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5300 /* Ensure st_size == 1000 */
5301 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5302 printf("stat failed (%s)\n", cli_errstr(cli1));
5306 if (sbuf.st_ex_size != 1000) {
5307 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5311 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5312 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5316 /* Re-open with O_TRUNC. */
5317 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5318 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5322 /* Ensure st_size == 0 */
5323 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5324 printf("stat failed (%s)\n", cli_errstr(cli1));
5328 if (sbuf.st_ex_size != 0) {
5329 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5333 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5334 printf("close failed (%s)\n", cli_errstr(cli1));
5338 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5339 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5343 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5344 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5345 dname, cli_errstr(cli1));
5349 cli_close(cli1, fnum1);
5351 /* What happens when we try and POSIX open a directory for write ? */
5352 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5353 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5356 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5357 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5362 /* Create the file. */
5363 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5365 if (!NT_STATUS_IS_OK(status)) {
5366 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5370 /* Write some data into it. */
5371 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5373 if (!NT_STATUS_IS_OK(status)) {
5374 printf("cli_write failed: %s\n", nt_errstr(status));
5378 cli_close(cli1, fnum1);
5380 /* Now create a hardlink. */
5381 status = cli_posix_hardlink(cli1, fname, hname);
5382 if (!NT_STATUS_IS_OK(status)) {
5383 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5387 /* Now create a symlink. */
5388 status = cli_posix_symlink(cli1, fname, sname);
5389 if (!NT_STATUS_IS_OK(status)) {
5390 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5394 /* Open the hardlink for read. */
5395 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5396 if (!NT_STATUS_IS_OK(status)) {
5397 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5401 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5402 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5406 if (memcmp(buf, "TEST DATA\n", 10)) {
5407 printf("invalid data read from hardlink\n");
5411 /* Do a POSIX lock/unlock. */
5412 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5413 if (!NT_STATUS_IS_OK(status)) {
5414 printf("POSIX lock failed %s\n", nt_errstr(status));
5418 /* Punch a hole in the locked area. */
5419 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5420 if (!NT_STATUS_IS_OK(status)) {
5421 printf("POSIX unlock failed %s\n", nt_errstr(status));
5425 cli_close(cli1, fnum1);
5427 /* Open the symlink for read - this should fail. A POSIX
5428 client should not be doing opens on a symlink. */
5429 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5430 if (NT_STATUS_IS_OK(status)) {
5431 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5434 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5435 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5436 printf("POSIX open of %s should have failed "
5437 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5438 "failed with %s instead.\n",
5439 sname, nt_errstr(status));
5444 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5450 if (strcmp(namebuf, fname) != 0) {
5451 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5452 sname, fname, namebuf);
5456 status = cli_posix_rmdir(cli1, dname);
5457 if (!NT_STATUS_IS_OK(status)) {
5458 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5462 printf("Simple POSIX open test passed\n");
5467 if (fnum1 != (uint16_t)-1) {
5468 cli_close(cli1, fnum1);
5469 fnum1 = (uint16_t)-1;
5472 cli_setatr(cli1, sname, 0, 0);
5473 cli_posix_unlink(cli1, sname);
5474 cli_setatr(cli1, hname, 0, 0);
5475 cli_posix_unlink(cli1, hname);
5476 cli_setatr(cli1, fname, 0, 0);
5477 cli_posix_unlink(cli1, fname);
5478 cli_setatr(cli1, dname, 0, 0);
5479 cli_posix_rmdir(cli1, dname);
5481 if (!torture_close_connection(cli1)) {
5489 static uint32 open_attrs_table[] = {
5490 FILE_ATTRIBUTE_NORMAL,
5491 FILE_ATTRIBUTE_ARCHIVE,
5492 FILE_ATTRIBUTE_READONLY,
5493 FILE_ATTRIBUTE_HIDDEN,
5494 FILE_ATTRIBUTE_SYSTEM,
5496 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5497 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5498 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5499 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5500 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5501 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5503 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5504 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5505 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5506 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5509 struct trunc_open_results {
5516 static struct trunc_open_results attr_results[] = {
5517 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5518 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5519 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5520 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5521 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5522 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5523 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5524 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5525 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5526 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5527 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5528 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5529 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5530 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5531 { 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 },
5532 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5533 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5534 { 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 },
5535 { 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 },
5536 { 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 },
5537 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5538 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5539 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5540 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5541 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5542 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5545 static bool run_openattrtest(int dummy)
5547 static struct cli_state *cli1;
5548 const char *fname = "\\openattr.file";
5550 bool correct = True;
5552 unsigned int i, j, k, l;
5555 printf("starting open attr test\n");
5557 if (!torture_open_connection(&cli1, 0)) {
5561 cli_sockopt(cli1, sockops);
5563 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5564 cli_setatr(cli1, fname, 0, 0);
5565 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5567 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5568 open_attrs_table[i], FILE_SHARE_NONE,
5569 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5570 if (!NT_STATUS_IS_OK(status)) {
5571 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5575 status = cli_close(cli1, fnum1);
5576 if (!NT_STATUS_IS_OK(status)) {
5577 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5581 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5582 status = cli_ntcreate(cli1, fname, 0,
5583 FILE_READ_DATA|FILE_WRITE_DATA,
5584 open_attrs_table[j],
5585 FILE_SHARE_NONE, FILE_OVERWRITE,
5587 if (!NT_STATUS_IS_OK(status)) {
5588 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5589 if (attr_results[l].num == k) {
5590 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5591 k, open_attrs_table[i],
5592 open_attrs_table[j],
5593 fname, NT_STATUS_V(status), nt_errstr(status));
5598 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5599 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5600 k, open_attrs_table[i], open_attrs_table[j],
5605 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5611 status = cli_close(cli1, fnum1);
5612 if (!NT_STATUS_IS_OK(status)) {
5613 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5617 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5618 if (!NT_STATUS_IS_OK(status)) {
5619 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5624 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5625 k, open_attrs_table[i], open_attrs_table[j], attr );
5628 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5629 if (attr_results[l].num == k) {
5630 if (attr != attr_results[l].result_attr ||
5631 open_attrs_table[i] != attr_results[l].init_attr ||
5632 open_attrs_table[j] != attr_results[l].trunc_attr) {
5633 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5634 open_attrs_table[i],
5635 open_attrs_table[j],
5637 attr_results[l].result_attr);
5647 cli_setatr(cli1, fname, 0, 0);
5648 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5650 printf("open attr test %s.\n", correct ? "passed" : "failed");
5652 if (!torture_close_connection(cli1)) {
5658 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5659 const char *name, void *state)
5661 int *matched = (int *)state;
5662 if (matched != NULL) {
5665 return NT_STATUS_OK;
5669 test directory listing speed
5671 static bool run_dirtest(int dummy)
5674 static struct cli_state *cli;
5676 struct timeval core_start;
5677 bool correct = True;
5680 printf("starting directory test\n");
5682 if (!torture_open_connection(&cli, 0)) {
5686 cli_sockopt(cli, sockops);
5689 for (i=0;i<torture_numops;i++) {
5691 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5692 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5693 fprintf(stderr,"Failed to open %s\n", fname);
5696 cli_close(cli, fnum);
5699 core_start = timeval_current();
5702 cli_list(cli, "a*.*", 0, list_fn, &matched);
5703 printf("Matched %d\n", matched);
5706 cli_list(cli, "b*.*", 0, list_fn, &matched);
5707 printf("Matched %d\n", matched);
5710 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5711 printf("Matched %d\n", matched);
5713 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5716 for (i=0;i<torture_numops;i++) {
5718 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5719 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5722 if (!torture_close_connection(cli)) {
5726 printf("finished dirtest\n");
5731 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5734 struct cli_state *pcli = (struct cli_state *)state;
5736 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5738 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5739 return NT_STATUS_OK;
5741 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5742 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5743 printf("del_fn: failed to rmdir %s\n,", fname );
5745 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5746 printf("del_fn: failed to unlink %s\n,", fname );
5748 return NT_STATUS_OK;
5753 sees what IOCTLs are supported
5755 bool torture_ioctl_test(int dummy)
5757 static struct cli_state *cli;
5758 uint16_t device, function;
5760 const char *fname = "\\ioctl.dat";
5764 if (!torture_open_connection(&cli, 0)) {
5768 printf("starting ioctl test\n");
5770 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5772 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5773 if (!NT_STATUS_IS_OK(status)) {
5774 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5778 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5779 printf("ioctl device info: %s\n", nt_errstr(status));
5781 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5782 printf("ioctl job info: %s\n", nt_errstr(status));
5784 for (device=0;device<0x100;device++) {
5785 printf("ioctl test with device = 0x%x\n", device);
5786 for (function=0;function<0x100;function++) {
5787 uint32 code = (device<<16) | function;
5789 status = cli_raw_ioctl(cli, fnum, code, &blob);
5791 if (NT_STATUS_IS_OK(status)) {
5792 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5794 data_blob_free(&blob);
5799 if (!torture_close_connection(cli)) {
5808 tries varients of chkpath
5810 bool torture_chkpath_test(int dummy)
5812 static struct cli_state *cli;
5817 if (!torture_open_connection(&cli, 0)) {
5821 printf("starting chkpath test\n");
5823 /* cleanup from an old run */
5824 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5825 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5826 cli_rmdir(cli, "\\chkpath.dir");
5828 status = cli_mkdir(cli, "\\chkpath.dir");
5829 if (!NT_STATUS_IS_OK(status)) {
5830 printf("mkdir1 failed : %s\n", nt_errstr(status));
5834 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5835 if (!NT_STATUS_IS_OK(status)) {
5836 printf("mkdir2 failed : %s\n", nt_errstr(status));
5840 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5842 if (!NT_STATUS_IS_OK(status)) {
5843 printf("open1 failed (%s)\n", nt_errstr(status));
5846 cli_close(cli, fnum);
5848 status = cli_chkpath(cli, "\\chkpath.dir");
5849 if (!NT_STATUS_IS_OK(status)) {
5850 printf("chkpath1 failed: %s\n", nt_errstr(status));
5854 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5855 if (!NT_STATUS_IS_OK(status)) {
5856 printf("chkpath2 failed: %s\n", nt_errstr(status));
5860 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5861 if (!NT_STATUS_IS_OK(status)) {
5862 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5863 NT_STATUS_NOT_A_DIRECTORY);
5865 printf("* chkpath on a file should fail\n");
5869 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5870 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5871 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5873 printf("* chkpath on a non existant file should fail\n");
5877 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5878 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5879 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5881 printf("* chkpath on a non existent component should fail\n");
5885 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5886 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5887 cli_rmdir(cli, "\\chkpath.dir");
5889 if (!torture_close_connection(cli)) {
5896 static bool run_eatest(int dummy)
5898 static struct cli_state *cli;
5899 const char *fname = "\\eatest.txt";
5900 bool correct = True;
5904 struct ea_struct *ea_list = NULL;
5905 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5908 printf("starting eatest\n");
5910 if (!torture_open_connection(&cli, 0)) {
5911 talloc_destroy(mem_ctx);
5915 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5917 status = cli_ntcreate(cli, fname, 0,
5918 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5919 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5921 if (!NT_STATUS_IS_OK(status)) {
5922 printf("open failed - %s\n", nt_errstr(status));
5923 talloc_destroy(mem_ctx);
5927 for (i = 0; i < 10; i++) {
5928 fstring ea_name, ea_val;
5930 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5931 memset(ea_val, (char)i+1, i+1);
5932 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("ea_set of name %s failed - %s\n", ea_name,
5936 talloc_destroy(mem_ctx);
5941 cli_close(cli, fnum);
5942 for (i = 0; i < 10; i++) {
5943 fstring ea_name, ea_val;
5945 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5946 memset(ea_val, (char)i+1, i+1);
5947 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5948 if (!NT_STATUS_IS_OK(status)) {
5949 printf("ea_set of name %s failed - %s\n", ea_name,
5951 talloc_destroy(mem_ctx);
5956 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5957 if (!NT_STATUS_IS_OK(status)) {
5958 printf("ea_get list failed - %s\n", nt_errstr(status));
5962 printf("num_eas = %d\n", (int)num_eas);
5964 if (num_eas != 20) {
5965 printf("Should be 20 EA's stored... failing.\n");
5969 for (i = 0; i < num_eas; i++) {
5970 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5971 dump_data(0, ea_list[i].value.data,
5972 ea_list[i].value.length);
5975 /* Setting EA's to zero length deletes them. Test this */
5976 printf("Now deleting all EA's - case indepenent....\n");
5979 cli_set_ea_path(cli, fname, "", "", 0);
5981 for (i = 0; i < 20; i++) {
5983 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5984 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5985 if (!NT_STATUS_IS_OK(status)) {
5986 printf("ea_set of name %s failed - %s\n", ea_name,
5988 talloc_destroy(mem_ctx);
5994 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5995 if (!NT_STATUS_IS_OK(status)) {
5996 printf("ea_get list failed - %s\n", nt_errstr(status));
6000 printf("num_eas = %d\n", (int)num_eas);
6001 for (i = 0; i < num_eas; i++) {
6002 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6003 dump_data(0, ea_list[i].value.data,
6004 ea_list[i].value.length);
6008 printf("deleting EA's failed.\n");
6012 /* Try and delete a non existant EA. */
6013 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6014 if (!NT_STATUS_IS_OK(status)) {
6015 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6020 talloc_destroy(mem_ctx);
6021 if (!torture_close_connection(cli)) {
6028 static bool run_dirtest1(int dummy)
6031 static struct cli_state *cli;
6034 bool correct = True;
6036 printf("starting directory test\n");
6038 if (!torture_open_connection(&cli, 0)) {
6042 cli_sockopt(cli, sockops);
6044 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6045 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6046 cli_rmdir(cli, "\\LISTDIR");
6047 cli_mkdir(cli, "\\LISTDIR");
6049 /* Create 1000 files and 1000 directories. */
6050 for (i=0;i<1000;i++) {
6052 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6053 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6054 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6055 fprintf(stderr,"Failed to open %s\n", fname);
6058 cli_close(cli, fnum);
6060 for (i=0;i<1000;i++) {
6062 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6063 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6064 fprintf(stderr,"Failed to open %s\n", fname);
6069 /* Now ensure that doing an old list sees both files and directories. */
6071 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6072 printf("num_seen = %d\n", num_seen );
6073 /* We should see 100 files + 1000 directories + . and .. */
6074 if (num_seen != 2002)
6077 /* Ensure if we have the "must have" bits we only see the
6081 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6082 printf("num_seen = %d\n", num_seen );
6083 if (num_seen != 1002)
6087 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6088 printf("num_seen = %d\n", num_seen );
6089 if (num_seen != 1000)
6092 /* Delete everything. */
6093 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6094 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6095 cli_rmdir(cli, "\\LISTDIR");
6098 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6099 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6100 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6103 if (!torture_close_connection(cli)) {
6107 printf("finished dirtest1\n");
6112 static bool run_error_map_extract(int dummy) {
6114 static struct cli_state *c_dos;
6115 static struct cli_state *c_nt;
6120 uint32 flgs2, errnum;
6127 /* NT-Error connection */
6129 if (!(c_nt = open_nbt_connection())) {
6133 c_nt->use_spnego = False;
6135 status = cli_negprot(c_nt);
6137 if (!NT_STATUS_IS_OK(status)) {
6138 printf("%s rejected the NT-error negprot (%s)\n", host,
6144 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6145 if (!NT_STATUS_IS_OK(status)) {
6146 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6150 /* DOS-Error connection */
6152 if (!(c_dos = open_nbt_connection())) {
6156 c_dos->use_spnego = False;
6157 c_dos->force_dos_errors = True;
6159 status = cli_negprot(c_dos);
6160 if (!NT_STATUS_IS_OK(status)) {
6161 printf("%s rejected the DOS-error negprot (%s)\n", host,
6163 cli_shutdown(c_dos);
6167 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6168 if (!NT_STATUS_IS_OK(status)) {
6169 printf("%s rejected the DOS-error initial session setup (%s)\n",
6170 host, nt_errstr(status));
6174 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6175 fstr_sprintf(user, "%X", error);
6177 status = cli_session_setup(c_nt, user,
6178 password, strlen(password),
6179 password, strlen(password),
6181 if (NT_STATUS_IS_OK(status)) {
6182 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6185 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6187 /* Case #1: 32-bit NT errors */
6188 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6189 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6191 printf("/** Dos error on NT connection! (%s) */\n",
6193 nt_status = NT_STATUS(0xc0000000);
6196 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6197 password, strlen(password),
6198 password, strlen(password),
6200 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6202 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6204 /* Case #1: 32-bit NT errors */
6205 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6206 printf("/** NT error on DOS connection! (%s) */\n",
6208 errnum = errclass = 0;
6210 cli_dos_error(c_dos, &errclass, &errnum);
6213 if (NT_STATUS_V(nt_status) != error) {
6214 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6215 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6216 get_nt_error_c_code(talloc_tos(), nt_status));
6219 printf("\t{%s,\t%s,\t%s},\n",
6220 smb_dos_err_class(errclass),
6221 smb_dos_err_name(errclass, errnum),
6222 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6227 static bool run_sesssetup_bench(int dummy)
6229 static struct cli_state *c;
6230 const char *fname = "\\file.dat";
6235 if (!torture_open_connection(&c, 0)) {
6239 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6240 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6241 FILE_DELETE_ON_CLOSE, 0, &fnum);
6242 if (!NT_STATUS_IS_OK(status)) {
6243 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6247 for (i=0; i<torture_numops; i++) {
6248 status = cli_session_setup(
6250 password, strlen(password),
6251 password, strlen(password),
6253 if (!NT_STATUS_IS_OK(status)) {
6254 d_printf("(%s) cli_session_setup failed: %s\n",
6255 __location__, nt_errstr(status));
6259 d_printf("\r%d ", (int)c->vuid);
6261 status = cli_ulogoff(c);
6262 if (!NT_STATUS_IS_OK(status)) {
6263 d_printf("(%s) cli_ulogoff failed: %s\n",
6264 __location__, nt_errstr(status));
6273 static bool subst_test(const char *str, const char *user, const char *domain,
6274 uid_t uid, gid_t gid, const char *expected)
6279 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6281 if (strcmp(subst, expected) != 0) {
6282 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6283 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6292 static void chain1_open_completion(struct tevent_req *req)
6296 status = cli_open_recv(req, &fnum);
6299 d_printf("cli_open_recv returned %s: %d\n",
6301 NT_STATUS_IS_OK(status) ? fnum : -1);
6304 static void chain1_write_completion(struct tevent_req *req)
6308 status = cli_write_andx_recv(req, &written);
6311 d_printf("cli_write_andx_recv returned %s: %d\n",
6313 NT_STATUS_IS_OK(status) ? (int)written : -1);
6316 static void chain1_close_completion(struct tevent_req *req)
6319 bool *done = (bool *)tevent_req_callback_data_void(req);
6321 status = cli_close_recv(req);
6326 d_printf("cli_close returned %s\n", nt_errstr(status));
6329 static bool run_chain1(int dummy)
6331 struct cli_state *cli1;
6332 struct event_context *evt = event_context_init(NULL);
6333 struct tevent_req *reqs[3], *smbreqs[3];
6335 const char *str = "foobar";
6338 printf("starting chain1 test\n");
6339 if (!torture_open_connection(&cli1, 0)) {
6343 cli_sockopt(cli1, sockops);
6345 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6346 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6347 if (reqs[0] == NULL) return false;
6348 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6351 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6352 (const uint8_t *)str, 0, strlen(str)+1,
6353 smbreqs, 1, &smbreqs[1]);
6354 if (reqs[1] == NULL) return false;
6355 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6357 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6358 if (reqs[2] == NULL) return false;
6359 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6361 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6362 if (!NT_STATUS_IS_OK(status)) {
6367 event_loop_once(evt);
6370 torture_close_connection(cli1);
6374 static void chain2_sesssetup_completion(struct tevent_req *req)
6377 status = cli_session_setup_guest_recv(req);
6378 d_printf("sesssetup returned %s\n", nt_errstr(status));
6381 static void chain2_tcon_completion(struct tevent_req *req)
6383 bool *done = (bool *)tevent_req_callback_data_void(req);
6385 status = cli_tcon_andx_recv(req);
6386 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6390 static bool run_chain2(int dummy)
6392 struct cli_state *cli1;
6393 struct event_context *evt = event_context_init(NULL);
6394 struct tevent_req *reqs[2], *smbreqs[2];
6398 printf("starting chain2 test\n");
6399 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6400 port_to_use, Undefined, 0);
6401 if (!NT_STATUS_IS_OK(status)) {
6405 cli_sockopt(cli1, sockops);
6407 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6409 if (reqs[0] == NULL) return false;
6410 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6412 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6413 "?????", NULL, 0, &smbreqs[1]);
6414 if (reqs[1] == NULL) return false;
6415 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6417 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6418 if (!NT_STATUS_IS_OK(status)) {
6423 event_loop_once(evt);
6426 torture_close_connection(cli1);
6431 struct torture_createdel_state {
6432 struct tevent_context *ev;
6433 struct cli_state *cli;
6436 static void torture_createdel_created(struct tevent_req *subreq);
6437 static void torture_createdel_closed(struct tevent_req *subreq);
6439 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6440 struct tevent_context *ev,
6441 struct cli_state *cli,
6444 struct tevent_req *req, *subreq;
6445 struct torture_createdel_state *state;
6447 req = tevent_req_create(mem_ctx, &state,
6448 struct torture_createdel_state);
6455 subreq = cli_ntcreate_send(
6456 state, ev, cli, name, 0,
6457 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6458 FILE_ATTRIBUTE_NORMAL,
6459 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6460 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6462 if (tevent_req_nomem(subreq, req)) {
6463 return tevent_req_post(req, ev);
6465 tevent_req_set_callback(subreq, torture_createdel_created, req);
6469 static void torture_createdel_created(struct tevent_req *subreq)
6471 struct tevent_req *req = tevent_req_callback_data(
6472 subreq, struct tevent_req);
6473 struct torture_createdel_state *state = tevent_req_data(
6474 req, struct torture_createdel_state);
6478 status = cli_ntcreate_recv(subreq, &fnum);
6479 TALLOC_FREE(subreq);
6480 if (!NT_STATUS_IS_OK(status)) {
6481 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6482 nt_errstr(status)));
6483 tevent_req_nterror(req, status);
6487 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6488 if (tevent_req_nomem(subreq, req)) {
6491 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6494 static void torture_createdel_closed(struct tevent_req *subreq)
6496 struct tevent_req *req = tevent_req_callback_data(
6497 subreq, struct tevent_req);
6500 status = cli_close_recv(subreq);
6501 if (!NT_STATUS_IS_OK(status)) {
6502 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6503 tevent_req_nterror(req, status);
6506 tevent_req_done(req);
6509 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6511 return tevent_req_simple_recv_ntstatus(req);
6514 struct torture_createdels_state {
6515 struct tevent_context *ev;
6516 struct cli_state *cli;
6517 const char *base_name;
6521 struct tevent_req **reqs;
6524 static void torture_createdels_done(struct tevent_req *subreq);
6526 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6527 struct tevent_context *ev,
6528 struct cli_state *cli,
6529 const char *base_name,
6533 struct tevent_req *req;
6534 struct torture_createdels_state *state;
6537 req = tevent_req_create(mem_ctx, &state,
6538 struct torture_createdels_state);
6544 state->base_name = talloc_strdup(state, base_name);
6545 if (tevent_req_nomem(state->base_name, req)) {
6546 return tevent_req_post(req, ev);
6548 state->num_files = MAX(num_parallel, num_files);
6550 state->received = 0;
6552 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6553 if (tevent_req_nomem(state->reqs, req)) {
6554 return tevent_req_post(req, ev);
6557 for (i=0; i<num_parallel; i++) {
6560 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6562 if (tevent_req_nomem(name, req)) {
6563 return tevent_req_post(req, ev);
6565 state->reqs[i] = torture_createdel_send(
6566 state->reqs, state->ev, state->cli, name);
6567 if (tevent_req_nomem(state->reqs[i], req)) {
6568 return tevent_req_post(req, ev);
6570 name = talloc_move(state->reqs[i], &name);
6571 tevent_req_set_callback(state->reqs[i],
6572 torture_createdels_done, req);
6578 static void torture_createdels_done(struct tevent_req *subreq)
6580 struct tevent_req *req = tevent_req_callback_data(
6581 subreq, struct tevent_req);
6582 struct torture_createdels_state *state = tevent_req_data(
6583 req, struct torture_createdels_state);
6584 size_t num_parallel = talloc_array_length(state->reqs);
6589 status = torture_createdel_recv(subreq);
6590 if (!NT_STATUS_IS_OK(status)){
6591 DEBUG(10, ("torture_createdel_recv returned %s\n",
6592 nt_errstr(status)));
6593 TALLOC_FREE(subreq);
6594 tevent_req_nterror(req, status);
6598 for (i=0; i<num_parallel; i++) {
6599 if (subreq == state->reqs[i]) {
6603 if (i == num_parallel) {
6604 DEBUG(10, ("received something we did not send\n"));
6605 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6608 TALLOC_FREE(state->reqs[i]);
6610 if (state->sent >= state->num_files) {
6611 tevent_req_done(req);
6615 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6617 if (tevent_req_nomem(name, req)) {
6620 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6622 if (tevent_req_nomem(state->reqs[i], req)) {
6625 name = talloc_move(state->reqs[i], &name);
6626 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6630 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6632 return tevent_req_simple_recv_ntstatus(req);
6635 struct swallow_notify_state {
6636 struct tevent_context *ev;
6637 struct cli_state *cli;
6639 uint32_t completion_filter;
6641 bool (*fn)(uint32_t action, const char *name, void *priv);
6645 static void swallow_notify_done(struct tevent_req *subreq);
6647 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6648 struct tevent_context *ev,
6649 struct cli_state *cli,
6651 uint32_t completion_filter,
6653 bool (*fn)(uint32_t action,
6658 struct tevent_req *req, *subreq;
6659 struct swallow_notify_state *state;
6661 req = tevent_req_create(mem_ctx, &state,
6662 struct swallow_notify_state);
6669 state->completion_filter = completion_filter;
6670 state->recursive = recursive;
6674 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6675 0xffff, state->completion_filter,
6677 if (tevent_req_nomem(subreq, req)) {
6678 return tevent_req_post(req, ev);
6680 tevent_req_set_callback(subreq, swallow_notify_done, req);
6684 static void swallow_notify_done(struct tevent_req *subreq)
6686 struct tevent_req *req = tevent_req_callback_data(
6687 subreq, struct tevent_req);
6688 struct swallow_notify_state *state = tevent_req_data(
6689 req, struct swallow_notify_state);
6691 uint32_t i, num_changes;
6692 struct notify_change *changes;
6694 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6695 TALLOC_FREE(subreq);
6696 if (!NT_STATUS_IS_OK(status)) {
6697 DEBUG(10, ("cli_notify_recv returned %s\n",
6698 nt_errstr(status)));
6699 tevent_req_nterror(req, status);
6703 for (i=0; i<num_changes; i++) {
6704 state->fn(changes[i].action, changes[i].name, state->priv);
6706 TALLOC_FREE(changes);
6708 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6709 0xffff, state->completion_filter,
6711 if (tevent_req_nomem(subreq, req)) {
6714 tevent_req_set_callback(subreq, swallow_notify_done, req);
6717 static bool print_notifies(uint32_t action, const char *name, void *priv)
6719 if (DEBUGLEVEL > 5) {
6720 d_printf("%d %s\n", (int)action, name);
6725 static void notify_bench_done(struct tevent_req *req)
6727 int *num_finished = (int *)tevent_req_callback_data_void(req);
6731 static bool run_notify_bench(int dummy)
6733 const char *dname = "\\notify-bench";
6734 struct tevent_context *ev;
6737 struct tevent_req *req1;
6738 struct tevent_req *req2 = NULL;
6739 int i, num_unc_names;
6740 int num_finished = 0;
6742 printf("starting notify-bench test\n");
6744 if (use_multishare_conn) {
6746 unc_list = file_lines_load(multishare_conn_fname,
6747 &num_unc_names, 0, NULL);
6748 if (!unc_list || num_unc_names <= 0) {
6749 d_printf("Failed to load unc names list from '%s'\n",
6750 multishare_conn_fname);
6753 TALLOC_FREE(unc_list);
6758 ev = tevent_context_init(talloc_tos());
6760 d_printf("tevent_context_init failed\n");
6764 for (i=0; i<num_unc_names; i++) {
6765 struct cli_state *cli;
6768 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6770 if (base_fname == NULL) {
6774 if (!torture_open_connection(&cli, i)) {
6778 status = cli_ntcreate(cli, dname, 0,
6779 MAXIMUM_ALLOWED_ACCESS,
6780 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6782 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6785 if (!NT_STATUS_IS_OK(status)) {
6786 d_printf("Could not create %s: %s\n", dname,
6791 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6792 FILE_NOTIFY_CHANGE_FILE_NAME |
6793 FILE_NOTIFY_CHANGE_DIR_NAME |
6794 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6795 FILE_NOTIFY_CHANGE_LAST_WRITE,
6796 false, print_notifies, NULL);
6798 d_printf("Could not create notify request\n");
6802 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6803 base_fname, 10, torture_numops);
6805 d_printf("Could not create createdels request\n");
6808 TALLOC_FREE(base_fname);
6810 tevent_req_set_callback(req2, notify_bench_done,
6814 while (num_finished < num_unc_names) {
6816 ret = tevent_loop_once(ev);
6818 d_printf("tevent_loop_once failed\n");
6823 if (!tevent_req_poll(req2, ev)) {
6824 d_printf("tevent_req_poll failed\n");
6827 status = torture_createdels_recv(req2);
6828 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6833 static bool run_mangle1(int dummy)
6835 struct cli_state *cli;
6836 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6840 time_t change_time, access_time, write_time;
6844 printf("starting mangle1 test\n");
6845 if (!torture_open_connection(&cli, 0)) {
6849 cli_sockopt(cli, sockops);
6851 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6852 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6854 if (!NT_STATUS_IS_OK(status)) {
6855 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6858 cli_close(cli, fnum);
6860 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6861 if (!NT_STATUS_IS_OK(status)) {
6862 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6866 d_printf("alt_name: %s\n", alt_name);
6868 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6869 if (!NT_STATUS_IS_OK(status)) {
6870 d_printf("cli_open(%s) failed: %s\n", alt_name,
6874 cli_close(cli, fnum);
6876 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6877 &write_time, &size, &mode);
6878 if (!NT_STATUS_IS_OK(status)) {
6879 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6887 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6889 size_t *to_pull = (size_t *)priv;
6890 size_t thistime = *to_pull;
6892 thistime = MIN(thistime, n);
6893 if (thistime == 0) {
6897 memset(buf, 0, thistime);
6898 *to_pull -= thistime;
6902 static bool run_windows_write(int dummy)
6904 struct cli_state *cli1;
6908 const char *fname = "\\writetest.txt";
6909 struct timeval start_time;
6914 printf("starting windows_write test\n");
6915 if (!torture_open_connection(&cli1, 0)) {
6919 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6920 if (!NT_STATUS_IS_OK(status)) {
6921 printf("open failed (%s)\n", nt_errstr(status));
6925 cli_sockopt(cli1, sockops);
6927 start_time = timeval_current();
6929 for (i=0; i<torture_numops; i++) {
6931 off_t start = i * torture_blocksize;
6932 size_t to_pull = torture_blocksize - 1;
6934 status = cli_writeall(cli1, fnum, 0, &c,
6935 start + torture_blocksize - 1, 1, NULL);
6936 if (!NT_STATUS_IS_OK(status)) {
6937 printf("cli_write failed: %s\n", nt_errstr(status));
6941 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6942 null_source, &to_pull);
6943 if (!NT_STATUS_IS_OK(status)) {
6944 printf("cli_push returned: %s\n", nt_errstr(status));
6949 seconds = timeval_elapsed(&start_time);
6950 kbytes = (double)torture_blocksize * torture_numops;
6953 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6954 (double)seconds, (int)(kbytes/seconds));
6958 cli_close(cli1, fnum);
6959 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6960 torture_close_connection(cli1);
6964 static bool run_cli_echo(int dummy)
6966 struct cli_state *cli;
6969 printf("starting cli_echo test\n");
6970 if (!torture_open_connection(&cli, 0)) {
6973 cli_sockopt(cli, sockops);
6975 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6977 d_printf("cli_echo returned %s\n", nt_errstr(status));
6979 torture_close_connection(cli);
6980 return NT_STATUS_IS_OK(status);
6983 static bool run_uid_regression_test(int dummy)
6985 static struct cli_state *cli;
6988 bool correct = True;
6991 printf("starting uid regression test\n");
6993 if (!torture_open_connection(&cli, 0)) {
6997 cli_sockopt(cli, sockops);
6999 /* Ok - now save then logoff our current user. */
7000 old_vuid = cli->vuid;
7002 status = cli_ulogoff(cli);
7003 if (!NT_STATUS_IS_OK(status)) {
7004 d_printf("(%s) cli_ulogoff failed: %s\n",
7005 __location__, nt_errstr(status));
7010 cli->vuid = old_vuid;
7012 /* Try an operation. */
7013 status = cli_mkdir(cli, "\\uid_reg_test");
7014 if (NT_STATUS_IS_OK(status)) {
7015 d_printf("(%s) cli_mkdir succeeded\n",
7020 /* Should be bad uid. */
7021 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7022 NT_STATUS_USER_SESSION_DELETED)) {
7028 old_cnum = cli->cnum;
7030 /* Now try a SMBtdis with the invald vuid set to zero. */
7033 /* This should succeed. */
7034 status = cli_tdis(cli);
7036 if (NT_STATUS_IS_OK(status)) {
7037 d_printf("First tdis with invalid vuid should succeed.\n");
7039 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7044 cli->vuid = old_vuid;
7045 cli->cnum = old_cnum;
7047 /* This should fail. */
7048 status = cli_tdis(cli);
7049 if (NT_STATUS_IS_OK(status)) {
7050 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7054 /* Should be bad tid. */
7055 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7056 NT_STATUS_NETWORK_NAME_DELETED)) {
7062 cli_rmdir(cli, "\\uid_reg_test");
7071 static const char *illegal_chars = "*\\/?<>|\":";
7072 static char force_shortname_chars[] = " +,.[];=\177";
7074 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7075 const char *mask, void *state)
7077 struct cli_state *pcli = (struct cli_state *)state;
7079 NTSTATUS status = NT_STATUS_OK;
7081 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7083 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7084 return NT_STATUS_OK;
7086 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7087 status = cli_rmdir(pcli, fname);
7088 if (!NT_STATUS_IS_OK(status)) {
7089 printf("del_fn: failed to rmdir %s\n,", fname );
7092 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7093 if (!NT_STATUS_IS_OK(status)) {
7094 printf("del_fn: failed to unlink %s\n,", fname );
7106 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7107 const char *name, void *state)
7109 struct sn_state *s = (struct sn_state *)state;
7113 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7114 i, finfo->name, finfo->short_name);
7117 if (strchr(force_shortname_chars, i)) {
7118 if (!finfo->short_name) {
7119 /* Shortname not created when it should be. */
7120 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7121 __location__, finfo->name, i);
7124 } else if (finfo->short_name){
7125 /* Shortname created when it should not be. */
7126 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7127 __location__, finfo->short_name, finfo->name);
7131 return NT_STATUS_OK;
7134 static bool run_shortname_test(int dummy)
7136 static struct cli_state *cli;
7137 bool correct = True;
7143 printf("starting shortname test\n");
7145 if (!torture_open_connection(&cli, 0)) {
7149 cli_sockopt(cli, sockops);
7151 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7152 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7153 cli_rmdir(cli, "\\shortname");
7155 status = cli_mkdir(cli, "\\shortname");
7156 if (!NT_STATUS_IS_OK(status)) {
7157 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7158 __location__, nt_errstr(status));
7163 strlcpy(fname, "\\shortname\\", sizeof(fname));
7164 strlcat(fname, "test .txt", sizeof(fname));
7168 for (i = 32; i < 128; i++) {
7169 uint16_t fnum = (uint16_t)-1;
7173 if (strchr(illegal_chars, i)) {
7178 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7179 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7180 if (!NT_STATUS_IS_OK(status)) {
7181 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7182 __location__, fname, nt_errstr(status));
7186 cli_close(cli, fnum);
7189 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7191 if (s.matched != 1) {
7192 d_printf("(%s) failed to list %s: %s\n",
7193 __location__, fname, cli_errstr(cli));
7198 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7199 if (!NT_STATUS_IS_OK(status)) {
7200 d_printf("(%s) failed to delete %s: %s\n",
7201 __location__, fname, nt_errstr(status));
7214 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7215 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7216 cli_rmdir(cli, "\\shortname");
7217 torture_close_connection(cli);
7221 static void pagedsearch_cb(struct tevent_req *req)
7224 struct tldap_message *msg;
7227 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7228 if (rc != TLDAP_SUCCESS) {
7229 d_printf("tldap_search_paged_recv failed: %s\n",
7230 tldap_err2string(rc));
7233 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7237 if (!tldap_entry_dn(msg, &dn)) {
7238 d_printf("tldap_entry_dn failed\n");
7241 d_printf("%s\n", dn);
7245 static bool run_tldap(int dummy)
7247 struct tldap_context *ld;
7250 struct sockaddr_storage addr;
7251 struct tevent_context *ev;
7252 struct tevent_req *req;
7256 if (!resolve_name(host, &addr, 0, false)) {
7257 d_printf("could not find host %s\n", host);
7260 status = open_socket_out(&addr, 389, 9999, &fd);
7261 if (!NT_STATUS_IS_OK(status)) {
7262 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7266 ld = tldap_context_create(talloc_tos(), fd);
7269 d_printf("tldap_context_create failed\n");
7273 rc = tldap_fetch_rootdse(ld);
7274 if (rc != TLDAP_SUCCESS) {
7275 d_printf("tldap_fetch_rootdse failed: %s\n",
7276 tldap_errstr(talloc_tos(), ld, rc));
7280 basedn = tldap_talloc_single_attribute(
7281 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7282 if (basedn == NULL) {
7283 d_printf("no defaultNamingContext\n");
7286 d_printf("defaultNamingContext: %s\n", basedn);
7288 ev = tevent_context_init(talloc_tos());
7290 d_printf("tevent_context_init failed\n");
7294 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7295 TLDAP_SCOPE_SUB, "(objectclass=*)",
7297 NULL, 0, NULL, 0, 0, 0, 0, 5);
7299 d_printf("tldap_search_paged_send failed\n");
7302 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7304 tevent_req_poll(req, ev);
7308 /* test search filters against rootDSE */
7309 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7310 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7312 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7313 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7314 talloc_tos(), NULL, NULL);
7315 if (rc != TLDAP_SUCCESS) {
7316 d_printf("tldap_search with complex filter failed: %s\n",
7317 tldap_errstr(talloc_tos(), ld, rc));
7325 /* Torture test to ensure no regression of :
7326 https://bugzilla.samba.org/show_bug.cgi?id=7084
7329 static bool run_dir_createtime(int dummy)
7331 struct cli_state *cli;
7332 const char *dname = "\\testdir";
7333 const char *fname = "\\testdir\\testfile";
7335 struct timespec create_time;
7336 struct timespec create_time1;
7340 if (!torture_open_connection(&cli, 0)) {
7344 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7345 cli_rmdir(cli, dname);
7347 status = cli_mkdir(cli, dname);
7348 if (!NT_STATUS_IS_OK(status)) {
7349 printf("mkdir failed: %s\n", nt_errstr(status));
7353 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7355 if (!NT_STATUS_IS_OK(status)) {
7356 printf("cli_qpathinfo2 returned %s\n",
7361 /* Sleep 3 seconds, then create a file. */
7364 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7366 if (!NT_STATUS_IS_OK(status)) {
7367 printf("cli_open failed: %s\n", nt_errstr(status));
7371 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7373 if (!NT_STATUS_IS_OK(status)) {
7374 printf("cli_qpathinfo2 (2) returned %s\n",
7379 if (timespec_compare(&create_time1, &create_time)) {
7380 printf("run_dir_createtime: create time was updated (error)\n");
7382 printf("run_dir_createtime: create time was not updated (correct)\n");
7388 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7389 cli_rmdir(cli, dname);
7390 if (!torture_close_connection(cli)) {
7397 static bool run_streamerror(int dummy)
7399 struct cli_state *cli;
7400 const char *dname = "\\testdir";
7401 const char *streamname =
7402 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7404 time_t change_time, access_time, write_time;
7406 uint16_t mode, fnum;
7409 if (!torture_open_connection(&cli, 0)) {
7413 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7414 cli_rmdir(cli, dname);
7416 status = cli_mkdir(cli, dname);
7417 if (!NT_STATUS_IS_OK(status)) {
7418 printf("mkdir failed: %s\n", nt_errstr(status));
7422 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7424 status = cli_nt_error(cli);
7426 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7427 printf("pathinfo returned %s, expected "
7428 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7433 status = cli_ntcreate(cli, streamname, 0x16,
7434 FILE_READ_DATA|FILE_READ_EA|
7435 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7436 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7437 FILE_OPEN, 0, 0, &fnum);
7439 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7440 printf("ntcreate returned %s, expected "
7441 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7447 cli_rmdir(cli, dname);
7451 static bool run_local_substitute(int dummy)
7455 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7456 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7457 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7458 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7459 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7460 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7461 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7462 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7464 /* Different captialization rules in sub_basic... */
7466 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7472 static bool run_local_base64(int dummy)
7477 for (i=1; i<2000; i++) {
7478 DATA_BLOB blob1, blob2;
7481 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7483 generate_random_buffer(blob1.data, blob1.length);
7485 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7487 d_fprintf(stderr, "base64_encode_data_blob failed "
7488 "for %d bytes\n", i);
7491 blob2 = base64_decode_data_blob(b64);
7494 if (data_blob_cmp(&blob1, &blob2)) {
7495 d_fprintf(stderr, "data_blob_cmp failed for %d "
7499 TALLOC_FREE(blob1.data);
7500 data_blob_free(&blob2);
7505 static bool run_local_gencache(int dummy)
7511 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7512 d_printf("%s: gencache_set() failed\n", __location__);
7516 if (!gencache_get("foo", NULL, NULL)) {
7517 d_printf("%s: gencache_get() failed\n", __location__);
7521 if (!gencache_get("foo", &val, &tm)) {
7522 d_printf("%s: gencache_get() failed\n", __location__);
7526 if (strcmp(val, "bar") != 0) {
7527 d_printf("%s: gencache_get() returned %s, expected %s\n",
7528 __location__, val, "bar");
7535 if (!gencache_del("foo")) {
7536 d_printf("%s: gencache_del() failed\n", __location__);
7539 if (gencache_del("foo")) {
7540 d_printf("%s: second gencache_del() succeeded\n",
7545 if (gencache_get("foo", &val, &tm)) {
7546 d_printf("%s: gencache_get() on deleted entry "
7547 "succeeded\n", __location__);
7551 blob = data_blob_string_const_null("bar");
7552 tm = time(NULL) + 60;
7554 if (!gencache_set_data_blob("foo", &blob, tm)) {
7555 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7559 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7560 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7564 if (strcmp((const char *)blob.data, "bar") != 0) {
7565 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7566 __location__, (const char *)blob.data, "bar");
7567 data_blob_free(&blob);
7571 data_blob_free(&blob);
7573 if (!gencache_del("foo")) {
7574 d_printf("%s: gencache_del() failed\n", __location__);
7577 if (gencache_del("foo")) {
7578 d_printf("%s: second gencache_del() succeeded\n",
7583 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7584 d_printf("%s: gencache_get_data_blob() on deleted entry "
7585 "succeeded\n", __location__);
7592 static bool rbt_testval(struct db_context *db, const char *key,
7595 struct db_record *rec;
7596 TDB_DATA data = string_tdb_data(value);
7600 rec = db->fetch_locked(db, db, string_tdb_data(key));
7602 d_fprintf(stderr, "fetch_locked failed\n");
7605 status = rec->store(rec, data, 0);
7606 if (!NT_STATUS_IS_OK(status)) {
7607 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7612 rec = db->fetch_locked(db, db, string_tdb_data(key));
7614 d_fprintf(stderr, "second fetch_locked failed\n");
7617 if ((rec->value.dsize != data.dsize)
7618 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7619 d_fprintf(stderr, "Got wrong data back\n");
7629 static bool run_local_rbtree(int dummy)
7631 struct db_context *db;
7635 db = db_open_rbt(NULL);
7638 d_fprintf(stderr, "db_open_rbt failed\n");
7642 for (i=0; i<1000; i++) {
7645 if (asprintf(&key, "key%ld", random()) == -1) {
7648 if (asprintf(&value, "value%ld", random()) == -1) {
7653 if (!rbt_testval(db, key, value)) {
7660 if (asprintf(&value, "value%ld", random()) == -1) {
7665 if (!rbt_testval(db, key, value)) {
7684 local test for character set functions
7686 This is a very simple test for the functionality in convert_string_error()
7688 static bool run_local_convert_string(int dummy)
7690 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7691 const char *test_strings[2] = { "March", "M\303\244rz" };
7695 for (i=0; i<2; i++) {
7696 const char *str = test_strings[i];
7697 int len = strlen(str);
7698 size_t converted_size;
7701 memset(dst, 'X', sizeof(dst));
7703 /* first try with real source length */
7704 ret = convert_string_error(CH_UNIX, CH_UTF8,
7709 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7713 if (converted_size != len) {
7714 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7715 str, len, (int)converted_size);
7719 if (strncmp(str, dst, converted_size) != 0) {
7720 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7724 if (strlen(str) != converted_size) {
7725 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7726 (int)strlen(str), (int)converted_size);
7730 if (dst[converted_size] != 'X') {
7731 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7735 /* now with srclen==-1, this causes the nul to be
7737 ret = convert_string_error(CH_UNIX, CH_UTF8,
7742 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7746 if (converted_size != len+1) {
7747 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7748 str, len, (int)converted_size);
7752 if (strncmp(str, dst, converted_size) != 0) {
7753 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7757 if (len+1 != converted_size) {
7758 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7759 len+1, (int)converted_size);
7763 if (dst[converted_size] != 'X') {
7764 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7771 TALLOC_FREE(tmp_ctx);
7774 TALLOC_FREE(tmp_ctx);
7779 struct talloc_dict_test {
7783 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7785 int *count = (int *)priv;
7790 static bool run_local_talloc_dict(int dummy)
7792 struct talloc_dict *dict;
7793 struct talloc_dict_test *t;
7796 dict = talloc_dict_init(talloc_tos());
7801 t = talloc(talloc_tos(), struct talloc_dict_test);
7808 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7813 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7826 static bool run_local_string_to_sid(int dummy) {
7829 if (string_to_sid(&sid, "S--1-5-32-545")) {
7830 printf("allowing S--1-5-32-545\n");
7833 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7834 printf("allowing S-1-5-32-+545\n");
7837 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")) {
7838 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7841 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7842 printf("allowing S-1-5-32-545-abc\n");
7845 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7846 printf("could not parse S-1-5-32-545\n");
7849 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7850 printf("mis-parsed S-1-5-32-545 as %s\n",
7851 sid_string_tos(&sid));
7857 static bool run_local_binary_to_sid(int dummy) {
7858 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7859 static const char good_binary_sid[] = {
7860 0x1, /* revision number */
7862 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7863 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7864 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7865 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7866 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7867 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7868 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7869 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7870 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7871 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7872 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7873 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7874 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7880 static const char long_binary_sid[] = {
7881 0x1, /* revision number */
7883 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7884 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7885 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7886 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7890 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7891 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7892 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7893 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7894 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7895 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7896 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7904 static const char long_binary_sid2[] = {
7905 0x1, /* revision number */
7907 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7908 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7909 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7910 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7914 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7915 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7916 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7917 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7918 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7919 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7920 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7938 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7939 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7942 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7945 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7948 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7954 /* Split a path name into filename and stream name components. Canonicalise
7955 * such that an implicit $DATA token is always explicit.
7957 * The "specification" of this function can be found in the
7958 * run_local_stream_name() function in torture.c, I've tried those
7959 * combinations against a W2k3 server.
7962 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7963 char **pbase, char **pstream)
7966 char *stream = NULL;
7967 char *sname; /* stream name */
7968 const char *stype; /* stream type */
7970 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7972 sname = strchr_m(fname, ':');
7974 if (lp_posix_pathnames() || (sname == NULL)) {
7975 if (pbase != NULL) {
7976 base = talloc_strdup(mem_ctx, fname);
7977 NT_STATUS_HAVE_NO_MEMORY(base);
7982 if (pbase != NULL) {
7983 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7984 NT_STATUS_HAVE_NO_MEMORY(base);
7989 stype = strchr_m(sname, ':');
7991 if (stype == NULL) {
7992 sname = talloc_strdup(mem_ctx, sname);
7996 if (strcasecmp_m(stype, ":$DATA") != 0) {
7998 * If there is an explicit stream type, so far we only
7999 * allow $DATA. Is there anything else allowed? -- vl
8001 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8003 return NT_STATUS_OBJECT_NAME_INVALID;
8005 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8009 if (sname == NULL) {
8011 return NT_STATUS_NO_MEMORY;
8014 if (sname[0] == '\0') {
8016 * no stream name, so no stream
8021 if (pstream != NULL) {
8022 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8023 if (stream == NULL) {
8026 return NT_STATUS_NO_MEMORY;
8029 * upper-case the type field
8031 strupper_m(strchr_m(stream, ':')+1);
8035 if (pbase != NULL) {
8038 if (pstream != NULL) {
8041 return NT_STATUS_OK;
8044 static bool test_stream_name(const char *fname, const char *expected_base,
8045 const char *expected_stream,
8046 NTSTATUS expected_status)
8050 char *stream = NULL;
8052 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8053 if (!NT_STATUS_EQUAL(status, expected_status)) {
8057 if (!NT_STATUS_IS_OK(status)) {
8061 if (base == NULL) goto error;
8063 if (strcmp(expected_base, base) != 0) goto error;
8065 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8066 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8068 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8072 TALLOC_FREE(stream);
8076 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8077 fname, expected_base ? expected_base : "<NULL>",
8078 expected_stream ? expected_stream : "<NULL>",
8079 nt_errstr(expected_status));
8080 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8081 base ? base : "<NULL>", stream ? stream : "<NULL>",
8084 TALLOC_FREE(stream);
8088 static bool run_local_stream_name(int dummy)
8092 ret &= test_stream_name(
8093 "bla", "bla", NULL, NT_STATUS_OK);
8094 ret &= test_stream_name(
8095 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8096 ret &= test_stream_name(
8097 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8098 ret &= test_stream_name(
8099 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8100 ret &= test_stream_name(
8101 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8102 ret &= test_stream_name(
8103 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8104 ret &= test_stream_name(
8105 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8106 ret &= test_stream_name(
8107 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8112 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8114 if (a.length != b.length) {
8115 printf("a.length=%d != b.length=%d\n",
8116 (int)a.length, (int)b.length);
8119 if (memcmp(a.data, b.data, a.length) != 0) {
8120 printf("a.data and b.data differ\n");
8126 static bool run_local_memcache(int dummy)
8128 struct memcache *cache;
8130 DATA_BLOB d1, d2, d3;
8131 DATA_BLOB v1, v2, v3;
8133 TALLOC_CTX *mem_ctx;
8135 size_t size1, size2;
8138 cache = memcache_init(NULL, 100);
8140 if (cache == NULL) {
8141 printf("memcache_init failed\n");
8145 d1 = data_blob_const("d1", 2);
8146 d2 = data_blob_const("d2", 2);
8147 d3 = data_blob_const("d3", 2);
8149 k1 = data_blob_const("d1", 2);
8150 k2 = data_blob_const("d2", 2);
8152 memcache_add(cache, STAT_CACHE, k1, d1);
8153 memcache_add(cache, GETWD_CACHE, k2, d2);
8155 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8156 printf("could not find k1\n");
8159 if (!data_blob_equal(d1, v1)) {
8163 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8164 printf("could not find k2\n");
8167 if (!data_blob_equal(d2, v2)) {
8171 memcache_add(cache, STAT_CACHE, k1, d3);
8173 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8174 printf("could not find replaced k1\n");
8177 if (!data_blob_equal(d3, v3)) {
8181 memcache_add(cache, GETWD_CACHE, k1, d1);
8183 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8184 printf("Did find k2, should have been purged\n");
8190 cache = memcache_init(NULL, 0);
8192 mem_ctx = talloc_init("foo");
8194 str1 = talloc_strdup(mem_ctx, "string1");
8195 str2 = talloc_strdup(mem_ctx, "string2");
8197 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8198 data_blob_string_const("torture"), &str1);
8199 size1 = talloc_total_size(cache);
8201 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8202 data_blob_string_const("torture"), &str2);
8203 size2 = talloc_total_size(cache);
8205 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8207 if (size2 > size1) {
8208 printf("memcache leaks memory!\n");
8218 static void wbclient_done(struct tevent_req *req)
8221 struct winbindd_response *wb_resp;
8222 int *i = (int *)tevent_req_callback_data_void(req);
8224 wbc_err = wb_trans_recv(req, req, &wb_resp);
8227 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8230 static bool run_local_wbclient(int dummy)
8232 struct event_context *ev;
8233 struct wb_context **wb_ctx;
8234 struct winbindd_request wb_req;
8235 bool result = false;
8238 BlockSignals(True, SIGPIPE);
8240 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8245 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8246 if (wb_ctx == NULL) {
8250 ZERO_STRUCT(wb_req);
8251 wb_req.cmd = WINBINDD_PING;
8253 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8255 for (i=0; i<nprocs; i++) {
8256 wb_ctx[i] = wb_context_init(ev, NULL);
8257 if (wb_ctx[i] == NULL) {
8260 for (j=0; j<torture_numops; j++) {
8261 struct tevent_req *req;
8262 req = wb_trans_send(ev, ev, wb_ctx[i],
8263 (j % 2) == 0, &wb_req);
8267 tevent_req_set_callback(req, wbclient_done, &i);
8273 while (i < nprocs * torture_numops) {
8274 event_loop_once(ev);
8283 static void getaddrinfo_finished(struct tevent_req *req)
8285 char *name = (char *)tevent_req_callback_data_void(req);
8286 struct addrinfo *ainfo;
8289 res = getaddrinfo_recv(req, &ainfo);
8291 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8294 d_printf("gai(%s) succeeded\n", name);
8295 freeaddrinfo(ainfo);
8298 static bool run_getaddrinfo_send(int dummy)
8300 TALLOC_CTX *frame = talloc_stackframe();
8301 struct fncall_context *ctx;
8302 struct tevent_context *ev;
8303 bool result = false;
8304 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8305 "www.slashdot.org", "heise.de" };
8306 struct tevent_req *reqs[4];
8309 ev = event_context_init(frame);
8314 ctx = fncall_context_init(frame, 4);
8316 for (i=0; i<ARRAY_SIZE(names); i++) {
8317 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8319 if (reqs[i] == NULL) {
8322 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8323 discard_const_p(void, names[i]));
8326 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8327 tevent_loop_once(ev);
8336 static bool dbtrans_inc(struct db_context *db)
8338 struct db_record *rec;
8343 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8345 printf(__location__ "fetch_lock failed\n");
8349 if (rec->value.dsize != sizeof(uint32_t)) {
8350 printf(__location__ "value.dsize = %d\n",
8351 (int)rec->value.dsize);
8355 val = (uint32_t *)rec->value.dptr;
8358 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8361 if (!NT_STATUS_IS_OK(status)) {
8362 printf(__location__ "store failed: %s\n",
8373 static bool run_local_dbtrans(int dummy)
8375 struct db_context *db;
8376 struct db_record *rec;
8381 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8382 O_RDWR|O_CREAT, 0600);
8384 printf("Could not open transtest.db\n");
8388 res = db->transaction_start(db);
8390 printf(__location__ "transaction_start failed\n");
8394 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8396 printf(__location__ "fetch_lock failed\n");
8400 if (rec->value.dptr == NULL) {
8402 status = rec->store(
8403 rec, make_tdb_data((uint8_t *)&initial,
8406 if (!NT_STATUS_IS_OK(status)) {
8407 printf(__location__ "store returned %s\n",
8415 res = db->transaction_commit(db);
8417 printf(__location__ "transaction_commit failed\n");
8425 res = db->transaction_start(db);
8427 printf(__location__ "transaction_start failed\n");
8431 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8432 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8436 for (i=0; i<10; i++) {
8437 if (!dbtrans_inc(db)) {
8442 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8443 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8447 if (val2 != val + 10) {
8448 printf(__location__ "val=%d, val2=%d\n",
8449 (int)val, (int)val2);
8453 printf("val2=%d\r", val2);
8455 res = db->transaction_commit(db);
8457 printf(__location__ "transaction_commit failed\n");
8467 * Just a dummy test to be run under a debugger. There's no real way
8468 * to inspect the tevent_select specific function from outside of
8472 static bool run_local_tevent_select(int dummy)
8474 struct tevent_context *ev;
8475 struct tevent_fd *fd1, *fd2;
8476 bool result = false;
8478 ev = tevent_context_init_byname(NULL, "select");
8480 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8484 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8486 d_fprintf(stderr, "tevent_add_fd failed\n");
8489 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8491 d_fprintf(stderr, "tevent_add_fd failed\n");
8496 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8498 d_fprintf(stderr, "tevent_add_fd failed\n");
8508 static double create_procs(bool (*fn)(int), bool *result)
8511 volatile pid_t *child_status;
8512 volatile bool *child_status_out;
8515 struct timeval start;
8519 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8520 if (!child_status) {
8521 printf("Failed to setup shared memory\n");
8525 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8526 if (!child_status_out) {
8527 printf("Failed to setup result status shared memory\n");
8531 for (i = 0; i < nprocs; i++) {
8532 child_status[i] = 0;
8533 child_status_out[i] = True;
8536 start = timeval_current();
8538 for (i=0;i<nprocs;i++) {
8541 pid_t mypid = getpid();
8542 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8544 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8547 if (torture_open_connection(¤t_cli, i)) break;
8549 printf("pid %d failed to start\n", (int)getpid());
8555 child_status[i] = getpid();
8557 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8559 child_status_out[i] = fn(i);
8566 for (i=0;i<nprocs;i++) {
8567 if (child_status[i]) synccount++;
8569 if (synccount == nprocs) break;
8571 } while (timeval_elapsed(&start) < 30);
8573 if (synccount != nprocs) {
8574 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8576 return timeval_elapsed(&start);
8579 /* start the client load */
8580 start = timeval_current();
8582 for (i=0;i<nprocs;i++) {
8583 child_status[i] = 0;
8586 printf("%d clients started\n", nprocs);
8588 for (i=0;i<nprocs;i++) {
8589 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8594 for (i=0;i<nprocs;i++) {
8595 if (!child_status_out[i]) {
8599 return timeval_elapsed(&start);
8602 #define FLAG_MULTIPROC 1
8609 {"FDPASS", run_fdpasstest, 0},
8610 {"LOCK1", run_locktest1, 0},
8611 {"LOCK2", run_locktest2, 0},
8612 {"LOCK3", run_locktest3, 0},
8613 {"LOCK4", run_locktest4, 0},
8614 {"LOCK5", run_locktest5, 0},
8615 {"LOCK6", run_locktest6, 0},
8616 {"LOCK7", run_locktest7, 0},
8617 {"LOCK8", run_locktest8, 0},
8618 {"LOCK9", run_locktest9, 0},
8619 {"UNLINK", run_unlinktest, 0},
8620 {"BROWSE", run_browsetest, 0},
8621 {"ATTR", run_attrtest, 0},
8622 {"TRANS2", run_trans2test, 0},
8623 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8624 {"TORTURE",run_torture, FLAG_MULTIPROC},
8625 {"RANDOMIPC", run_randomipc, 0},
8626 {"NEGNOWAIT", run_negprot_nowait, 0},
8627 {"NBENCH", run_nbench, 0},
8628 {"NBENCH2", run_nbench2, 0},
8629 {"OPLOCK1", run_oplock1, 0},
8630 {"OPLOCK2", run_oplock2, 0},
8631 {"OPLOCK4", run_oplock4, 0},
8632 {"DIR", run_dirtest, 0},
8633 {"DIR1", run_dirtest1, 0},
8634 {"DIR-CREATETIME", run_dir_createtime, 0},
8635 {"DENY1", torture_denytest1, 0},
8636 {"DENY2", torture_denytest2, 0},
8637 {"TCON", run_tcon_test, 0},
8638 {"TCONDEV", run_tcon_devtype_test, 0},
8639 {"RW1", run_readwritetest, 0},
8640 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8641 {"RW3", run_readwritelarge, 0},
8642 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8643 {"OPEN", run_opentest, 0},
8644 {"POSIX", run_simple_posix_open_test, 0},
8645 {"POSIX-APPEND", run_posix_append, 0},
8646 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8647 {"ASYNC-ECHO", run_async_echo, 0},
8648 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8649 { "SHORTNAME-TEST", run_shortname_test, 0},
8650 { "ADDRCHANGE", run_addrchange, 0},
8652 {"OPENATTR", run_openattrtest, 0},
8654 {"XCOPY", run_xcopy, 0},
8655 {"RENAME", run_rename, 0},
8656 {"DELETE", run_deletetest, 0},
8657 {"DELETE-LN", run_deletetest_ln, 0},
8658 {"PROPERTIES", run_properties, 0},
8659 {"MANGLE", torture_mangle, 0},
8660 {"MANGLE1", run_mangle1, 0},
8661 {"W2K", run_w2ktest, 0},
8662 {"TRANS2SCAN", torture_trans2_scan, 0},
8663 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8664 {"UTABLE", torture_utable, 0},
8665 {"CASETABLE", torture_casetable, 0},
8666 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8667 {"PIPE_NUMBER", run_pipe_number, 0},
8668 {"TCON2", run_tcon2_test, 0},
8669 {"IOCTL", torture_ioctl_test, 0},
8670 {"CHKPATH", torture_chkpath_test, 0},
8671 {"FDSESS", run_fdsesstest, 0},
8672 { "EATEST", run_eatest, 0},
8673 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8674 { "CHAIN1", run_chain1, 0},
8675 { "CHAIN2", run_chain2, 0},
8676 { "WINDOWS-WRITE", run_windows_write, 0},
8677 { "NTTRANS-CREATE", run_nttrans_create, 0},
8678 { "CLI_ECHO", run_cli_echo, 0},
8679 { "GETADDRINFO", run_getaddrinfo_send, 0},
8680 { "TLDAP", run_tldap },
8681 { "STREAMERROR", run_streamerror },
8682 { "NOTIFY-BENCH", run_notify_bench },
8683 { "BAD-NBT-SESSION", run_bad_nbt_session },
8684 { "SMB-ANY-CONNECT", run_smb_any_connect },
8685 { "NOTIFY-ONLINE", run_notify_online },
8686 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8687 { "LOCAL-GENCACHE", run_local_gencache, 0},
8688 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8689 { "LOCAL-BASE64", run_local_base64, 0},
8690 { "LOCAL-RBTREE", run_local_rbtree, 0},
8691 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8692 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8693 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8694 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8695 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8696 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8697 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8698 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8703 /****************************************************************************
8704 run a specified test or "ALL"
8705 ****************************************************************************/
8706 static bool run_test(const char *name)
8713 if (strequal(name,"ALL")) {
8714 for (i=0;torture_ops[i].name;i++) {
8715 run_test(torture_ops[i].name);
8720 for (i=0;torture_ops[i].name;i++) {
8721 fstr_sprintf(randomfname, "\\XX%x",
8722 (unsigned)random());
8724 if (strequal(name, torture_ops[i].name)) {
8726 printf("Running %s\n", name);
8727 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8728 t = create_procs(torture_ops[i].fn, &result);
8731 printf("TEST %s FAILED!\n", name);
8734 struct timeval start;
8735 start = timeval_current();
8736 if (!torture_ops[i].fn(0)) {
8738 printf("TEST %s FAILED!\n", name);
8740 t = timeval_elapsed(&start);
8742 printf("%s took %g secs\n\n", name, t);
8747 printf("Did not find a test named %s\n", name);
8755 static void usage(void)
8759 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8760 printf("Please use samba4 torture.\n\n");
8762 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8764 printf("\t-d debuglevel\n");
8765 printf("\t-U user%%pass\n");
8766 printf("\t-k use kerberos\n");
8767 printf("\t-N numprocs\n");
8768 printf("\t-n my_netbios_name\n");
8769 printf("\t-W workgroup\n");
8770 printf("\t-o num_operations\n");
8771 printf("\t-O socket_options\n");
8772 printf("\t-m maximum protocol\n");
8773 printf("\t-L use oplocks\n");
8774 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8775 printf("\t-A showall\n");
8776 printf("\t-p port\n");
8777 printf("\t-s seed\n");
8778 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8779 printf("\t-f filename filename to test\n");
8782 printf("tests are:");
8783 for (i=0;torture_ops[i].name;i++) {
8784 printf(" %s", torture_ops[i].name);
8788 printf("default test is ALL\n");
8793 /****************************************************************************
8795 ****************************************************************************/
8796 int main(int argc,char *argv[])
8802 bool correct = True;
8803 TALLOC_CTX *frame = talloc_stackframe();
8804 int seed = time(NULL);
8806 #ifdef HAVE_SETBUFFER
8807 setbuffer(stdout, NULL, 0);
8810 setup_logging("smbtorture", DEBUG_STDOUT);
8814 if (is_default_dyn_CONFIGFILE()) {
8815 if(getenv("SMB_CONF_PATH")) {
8816 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8819 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8826 for(p = argv[1]; *p; p++)
8830 if (strncmp(argv[1], "//", 2)) {
8834 fstrcpy(host, &argv[1][2]);
8835 p = strchr_m(&host[2],'/');
8840 fstrcpy(share, p+1);
8842 fstrcpy(myname, get_myname(talloc_tos()));
8844 fprintf(stderr, "Failed to get my hostname.\n");
8848 if (*username == 0 && getenv("LOGNAME")) {
8849 fstrcpy(username,getenv("LOGNAME"));
8855 fstrcpy(workgroup, lp_workgroup());
8857 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8861 port_to_use = atoi(optarg);
8864 seed = atoi(optarg);
8867 fstrcpy(workgroup,optarg);
8870 max_protocol = interpret_protocol(optarg, max_protocol);
8873 nprocs = atoi(optarg);
8876 torture_numops = atoi(optarg);
8879 lp_set_cmdline("log level", optarg);
8888 local_path = optarg;
8891 torture_showall = True;
8894 fstrcpy(myname, optarg);
8897 client_txt = optarg;
8904 use_kerberos = True;
8906 d_printf("No kerberos support compiled in\n");
8912 fstrcpy(username,optarg);
8913 p = strchr_m(username,'%');
8916 fstrcpy(password, p+1);
8921 fstrcpy(multishare_conn_fname, optarg);
8922 use_multishare_conn = True;
8925 torture_blocksize = atoi(optarg);
8928 test_filename = SMB_STRDUP(optarg);
8931 printf("Unknown option %c (%d)\n", (char)opt, opt);
8936 d_printf("using seed %d\n", seed);
8940 if(use_kerberos && !gotuser) gotpass = True;
8943 p = getpass("Password:");
8945 fstrcpy(password, p);
8950 printf("host=%s share=%s user=%s myname=%s\n",
8951 host, share, username, myname);
8953 if (argc == optind) {
8954 correct = run_test("ALL");
8956 for (i=optind;i<argc;i++) {
8957 if (!run_test(argv[i])) {