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)
181 struct nmb_name called, calling;
182 struct sockaddr_storage ss;
186 make_nmb_name(&calling, myname, 0x0);
187 make_nmb_name(&called , host, 0x20);
191 if (!(c = cli_initialise_ex(signing_state))) {
192 printf("Failed initialize cli_struct to connect with %s\n", host);
196 c->port = port_to_use;
198 status = cli_connect(c, host, &ss);
199 if (!NT_STATUS_IS_OK(status)) {
200 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
204 c->use_kerberos = use_kerberos;
206 c->timeout = 120000; /* set a really long timeout (2 minutes) */
207 if (use_oplocks) c->use_oplocks = True;
208 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
210 if (!cli_session_request(c, &calling, &called)) {
212 * Well, that failed, try *SMBSERVER ...
213 * However, we must reconnect as well ...
215 status = cli_connect(c, host, &ss);
216 if (!NT_STATUS_IS_OK(status)) {
217 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
221 make_nmb_name(&called, "*SMBSERVER", 0x20);
222 if (!cli_session_request(c, &calling, &called)) {
223 printf("%s rejected the session\n",host);
224 printf("We tried with a called name of %s & %s\n",
234 /****************************************************************************
235 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
236 ****************************************************************************/
238 static bool cli_bad_session_request(struct cli_state *cli,
239 struct nmb_name *calling, struct nmb_name *called)
249 memcpy(&(cli->calling), calling, sizeof(*calling));
250 memcpy(&(cli->called ), called , sizeof(*called ));
252 /* 445 doesn't have session request */
253 if (cli->port == 445)
256 frame = talloc_stackframe();
258 iov[0].iov_base = len_buf;
259 iov[0].iov_len = sizeof(len_buf);
261 /* put in the destination name */
263 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
265 if (iov[1].iov_base == NULL) {
268 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
269 talloc_get_size(iov[1].iov_base));
273 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
275 if (iov[2].iov_base == NULL) {
278 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
279 talloc_get_size(iov[2].iov_base));
281 /* Deliberately corrupt the name len (first byte) */
282 *((uint8_t *)iov[2].iov_base) = 100;
284 /* send a session request (RFC 1002) */
285 /* setup the packet length
286 * Remove four bytes from the length count, since the length
287 * field in the NBT Session Service header counts the number
288 * of bytes which follow. The cli_send_smb() function knows
289 * about this and accounts for those four bytes.
293 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
294 SCVAL(len_buf,0,0x81);
296 len = write_data_iov(cli->fd, iov, 3);
300 len = read_smb(cli->fd, talloc_tos(), &inbuf, &err);
306 if (CVAL(inbuf,0) != 0x82) {
307 /* This is the wrong place to put the error... JRA. */
308 cli->rap_error = CVAL(inbuf,4);
318 static struct cli_state *open_bad_nbt_connection(void)
320 struct nmb_name called, calling;
321 struct sockaddr_storage ss;
325 make_nmb_name(&calling, myname, 0x0);
326 make_nmb_name(&called , host, 0x20);
330 if (!(c = cli_initialise_ex(signing_state))) {
331 printf("Failed initialize cli_struct to connect with %s\n", host);
337 status = cli_connect(c, host, &ss);
338 if (!NT_STATUS_IS_OK(status)) {
339 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
343 c->timeout = 4000; /* set a short timeout (4 seconds) */
345 if (!cli_bad_session_request(c, &calling, &called)) {
346 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
354 /* Insert a NULL at the first separator of the given path and return a pointer
355 * to the remainder of the string.
358 terminate_path_at_separator(char * path)
366 if ((p = strchr_m(path, '/'))) {
371 if ((p = strchr_m(path, '\\'))) {
381 parse a //server/share type UNC name
383 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
384 char **hostname, char **sharename)
388 *hostname = *sharename = NULL;
390 if (strncmp(unc_name, "\\\\", 2) &&
391 strncmp(unc_name, "//", 2)) {
395 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
396 p = terminate_path_at_separator(*hostname);
399 *sharename = talloc_strdup(mem_ctx, p);
400 terminate_path_at_separator(*sharename);
403 if (*hostname && *sharename) {
407 TALLOC_FREE(*hostname);
408 TALLOC_FREE(*sharename);
412 static bool torture_open_connection_share(struct cli_state **c,
413 const char *hostname,
414 const char *sharename)
420 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
422 flags |= CLI_FULL_CONNECTION_OPLOCKS;
423 if (use_level_II_oplocks)
424 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
426 status = cli_full_connection(c, myname,
427 hostname, NULL, port_to_use,
430 password, flags, signing_state);
431 if (!NT_STATUS_IS_OK(status)) {
432 printf("failed to open share connection: //%s/%s port:%d - %s\n",
433 hostname, sharename, port_to_use, nt_errstr(status));
437 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
440 return force_cli_encryption(*c,
446 bool torture_open_connection(struct cli_state **c, int conn_index)
448 char **unc_list = NULL;
449 int num_unc_names = 0;
452 if (use_multishare_conn==True) {
454 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
455 if (!unc_list || num_unc_names <= 0) {
456 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
460 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
462 printf("Failed to parse UNC name %s\n",
463 unc_list[conn_index % num_unc_names]);
464 TALLOC_FREE(unc_list);
468 result = torture_open_connection_share(c, h, s);
470 /* h, s were copied earlier */
471 TALLOC_FREE(unc_list);
475 return torture_open_connection_share(c, host, share);
478 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
480 uint16 old_vuid = cli->vuid;
481 fstring old_user_name;
482 size_t passlen = strlen(password);
486 fstrcpy(old_user_name, cli->user_name);
488 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
492 *new_vuid = cli->vuid;
493 cli->vuid = old_vuid;
494 status = cli_set_username(cli, old_user_name);
495 if (!NT_STATUS_IS_OK(status)) {
502 bool torture_close_connection(struct cli_state *c)
507 status = cli_tdis(c);
508 if (!NT_STATUS_IS_OK(status)) {
509 printf("tdis failed (%s)\n", nt_errstr(status));
519 /* check if the server produced the expected error code */
520 static bool check_error(int line, struct cli_state *c,
521 uint8 eclass, uint32 ecode, NTSTATUS nterr)
523 if (cli_is_dos_error(c)) {
527 /* Check DOS error */
529 cli_dos_error(c, &cclass, &num);
531 if (eclass != cclass || ecode != num) {
532 printf("unexpected error code class=%d code=%d\n",
533 (int)cclass, (int)num);
534 printf(" expected %d/%d %s (line=%d)\n",
535 (int)eclass, (int)ecode, nt_errstr(nterr), line);
544 status = cli_nt_error(c);
546 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
547 printf("unexpected error code %s\n", nt_errstr(status));
548 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
557 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
559 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
560 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
566 static bool rw_torture(struct cli_state *c)
568 const char *lockfname = "\\torture.lck";
572 pid_t pid2, pid = getpid();
578 memset(buf, '\0', sizeof(buf));
580 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
582 if (!NT_STATUS_IS_OK(status)) {
583 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
585 if (!NT_STATUS_IS_OK(status)) {
586 printf("open of %s failed (%s)\n",
587 lockfname, nt_errstr(status));
591 for (i=0;i<torture_numops;i++) {
592 unsigned n = (unsigned)sys_random()%10;
595 printf("%d\r", i); fflush(stdout);
597 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
599 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
603 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
605 if (!NT_STATUS_IS_OK(status)) {
606 printf("open failed (%s)\n", nt_errstr(status));
611 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
613 if (!NT_STATUS_IS_OK(status)) {
614 printf("write failed (%s)\n", nt_errstr(status));
619 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
620 sizeof(pid)+(j*sizeof(buf)),
622 if (!NT_STATUS_IS_OK(status)) {
623 printf("write failed (%s)\n",
631 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
632 printf("read failed (%s)\n", cli_errstr(c));
637 printf("data corruption!\n");
641 status = cli_close(c, fnum);
642 if (!NT_STATUS_IS_OK(status)) {
643 printf("close failed (%s)\n", nt_errstr(status));
647 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("unlink failed (%s)\n", nt_errstr(status));
653 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
654 if (!NT_STATUS_IS_OK(status)) {
655 printf("unlock failed (%s)\n", nt_errstr(status));
661 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
668 static bool run_torture(int dummy)
670 struct cli_state *cli;
675 cli_sockopt(cli, sockops);
677 ret = rw_torture(cli);
679 if (!torture_close_connection(cli)) {
686 static bool rw_torture3(struct cli_state *c, char *lockfname)
688 uint16_t fnum = (uint16_t)-1;
693 unsigned countprev = 0;
696 NTSTATUS status = NT_STATUS_OK;
699 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
701 SIVAL(buf, i, sys_random());
706 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
707 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
710 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
712 if (!NT_STATUS_IS_OK(status)) {
713 printf("first open read/write of %s failed (%s)\n",
714 lockfname, nt_errstr(status));
720 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
722 status = cli_open(c, lockfname, O_RDONLY,
724 if (!NT_STATUS_IS_OK(status)) {
729 if (!NT_STATUS_IS_OK(status)) {
730 printf("second open read-only of %s failed (%s)\n",
731 lockfname, nt_errstr(status));
737 for (count = 0; count < sizeof(buf); count += sent)
739 if (count >= countprev) {
740 printf("%d %8d\r", i, count);
743 countprev += (sizeof(buf) / 20);
748 sent = ((unsigned)sys_random()%(20))+ 1;
749 if (sent > sizeof(buf) - count)
751 sent = sizeof(buf) - count;
754 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
755 count, (size_t)sent, NULL);
756 if (!NT_STATUS_IS_OK(status)) {
757 printf("write failed (%s)\n",
764 sent = cli_read(c, fnum, buf_rd+count, count,
768 printf("read failed offset:%d size:%ld (%s)\n",
769 count, (unsigned long)sizeof(buf)-count,
776 if (memcmp(buf_rd+count, buf+count, sent) != 0)
778 printf("read/write compare failed\n");
779 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
788 status = cli_close(c, fnum);
789 if (!NT_STATUS_IS_OK(status)) {
790 printf("close failed (%s)\n", nt_errstr(status));
797 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
799 const char *lockfname = "\\torture2.lck";
809 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
810 if (!NT_STATUS_IS_OK(status)) {
811 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
814 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("first open read/write of %s failed (%s)\n",
818 lockfname, nt_errstr(status));
822 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("second open read-only of %s failed (%s)\n",
825 lockfname, nt_errstr(status));
826 cli_close(c1, fnum1);
830 for (i = 0; i < torture_numops; i++)
832 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
834 printf("%d\r", i); fflush(stdout);
837 generate_random_buffer((unsigned char *)buf, buf_size);
839 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("write failed (%s)\n", nt_errstr(status));
847 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
848 printf("read failed (%s)\n", cli_errstr(c2));
849 printf("read %d, expected %ld\n", (int)bytes_read,
850 (unsigned long)buf_size);
855 if (memcmp(buf_rd, buf, buf_size) != 0)
857 printf("read/write compare failed\n");
863 status = cli_close(c2, fnum2);
864 if (!NT_STATUS_IS_OK(status)) {
865 printf("close failed (%s)\n", nt_errstr(status));
869 status = cli_close(c1, fnum1);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("close failed (%s)\n", nt_errstr(status));
875 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
876 if (!NT_STATUS_IS_OK(status)) {
877 printf("unlink failed (%s)\n", nt_errstr(status));
884 static bool run_readwritetest(int dummy)
886 struct cli_state *cli1, *cli2;
887 bool test1, test2 = False;
889 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
892 cli_sockopt(cli1, sockops);
893 cli_sockopt(cli2, sockops);
895 printf("starting readwritetest\n");
897 test1 = rw_torture2(cli1, cli2);
898 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
901 test2 = rw_torture2(cli1, cli1);
902 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
905 if (!torture_close_connection(cli1)) {
909 if (!torture_close_connection(cli2)) {
913 return (test1 && test2);
916 static bool run_readwritemulti(int dummy)
918 struct cli_state *cli;
923 cli_sockopt(cli, sockops);
925 printf("run_readwritemulti: fname %s\n", randomfname);
926 test = rw_torture3(cli, randomfname);
928 if (!torture_close_connection(cli)) {
935 static bool run_readwritelarge_internal(int max_xmit_k)
937 static struct cli_state *cli1;
939 const char *lockfname = "\\large.dat";
945 if (!torture_open_connection(&cli1, 0)) {
948 cli_sockopt(cli1, sockops);
949 memset(buf,'\0',sizeof(buf));
951 cli1->max_xmit = max_xmit_k*1024;
953 if (signing_state == Required) {
954 /* Horrible cheat to force
955 multiple signed outstanding
956 packets against a Samba server.
958 cli1->is_samba = false;
961 printf("starting readwritelarge_internal\n");
963 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
965 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
972 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
974 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
976 if (!NT_STATUS_IS_OK(status)) {
977 printf("qfileinfo failed (%s)\n", nt_errstr(status));
981 if (fsize == sizeof(buf))
982 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
983 (unsigned long)fsize);
985 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
986 (unsigned long)fsize);
990 status = cli_close(cli1, fnum1);
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("close failed (%s)\n", nt_errstr(status));
996 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
997 if (!NT_STATUS_IS_OK(status)) {
998 printf("unlink failed (%s)\n", nt_errstr(status));
1002 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1009 cli1->max_xmit = 4*1024;
1011 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1013 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1015 if (!NT_STATUS_IS_OK(status)) {
1016 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1020 if (fsize == sizeof(buf))
1021 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1022 (unsigned long)fsize);
1024 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1025 (unsigned long)fsize);
1030 /* ToDo - set allocation. JRA */
1031 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1032 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1035 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1037 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1041 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1044 status = cli_close(cli1, fnum1);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 printf("close failed (%s)\n", nt_errstr(status));
1050 if (!torture_close_connection(cli1)) {
1056 static bool run_readwritelarge(int dummy)
1058 return run_readwritelarge_internal(128);
1061 static bool run_readwritelarge_signtest(int dummy)
1064 signing_state = Required;
1065 ret = run_readwritelarge_internal(2);
1066 signing_state = Undefined;
1073 #define ival(s) strtol(s, NULL, 0)
1075 /* run a test that simulates an approximate netbench client load */
1076 static bool run_netbench(int client)
1078 struct cli_state *cli;
1083 const char *params[20];
1084 bool correct = True;
1090 cli_sockopt(cli, sockops);
1094 slprintf(cname,sizeof(cname)-1, "client%d", client);
1096 f = fopen(client_txt, "r");
1103 while (fgets(line, sizeof(line)-1, f)) {
1107 line[strlen(line)-1] = 0;
1109 /* printf("[%d] %s\n", line_count, line); */
1111 all_string_sub(line,"client1", cname, sizeof(line));
1113 /* parse the command parameters */
1114 params[0] = strtok_r(line, " ", &saveptr);
1116 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1120 if (i < 2) continue;
1122 if (!strncmp(params[0],"SMB", 3)) {
1123 printf("ERROR: You are using a dbench 1 load file\n");
1127 if (!strcmp(params[0],"NTCreateX")) {
1128 nb_createx(params[1], ival(params[2]), ival(params[3]),
1130 } else if (!strcmp(params[0],"Close")) {
1131 nb_close(ival(params[1]));
1132 } else if (!strcmp(params[0],"Rename")) {
1133 nb_rename(params[1], params[2]);
1134 } else if (!strcmp(params[0],"Unlink")) {
1135 nb_unlink(params[1]);
1136 } else if (!strcmp(params[0],"Deltree")) {
1137 nb_deltree(params[1]);
1138 } else if (!strcmp(params[0],"Rmdir")) {
1139 nb_rmdir(params[1]);
1140 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1141 nb_qpathinfo(params[1]);
1142 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1143 nb_qfileinfo(ival(params[1]));
1144 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1145 nb_qfsinfo(ival(params[1]));
1146 } else if (!strcmp(params[0],"FIND_FIRST")) {
1147 nb_findfirst(params[1]);
1148 } else if (!strcmp(params[0],"WriteX")) {
1149 nb_writex(ival(params[1]),
1150 ival(params[2]), ival(params[3]), ival(params[4]));
1151 } else if (!strcmp(params[0],"ReadX")) {
1152 nb_readx(ival(params[1]),
1153 ival(params[2]), ival(params[3]), ival(params[4]));
1154 } else if (!strcmp(params[0],"Flush")) {
1155 nb_flush(ival(params[1]));
1157 printf("Unknown operation %s\n", params[0]);
1165 if (!torture_close_connection(cli)) {
1173 /* run a test that simulates an approximate netbench client load */
1174 static bool run_nbench(int dummy)
1177 bool correct = True;
1183 signal(SIGALRM, nb_alarm);
1185 t = create_procs(run_netbench, &correct);
1188 printf("\nThroughput %g MB/sec\n",
1189 1.0e-6 * nbio_total() / t);
1195 This test checks for two things:
1197 1) correct support for retaining locks over a close (ie. the server
1198 must not use posix semantics)
1199 2) support for lock timeouts
1201 static bool run_locktest1(int dummy)
1203 struct cli_state *cli1, *cli2;
1204 const char *fname = "\\lockt1.lck";
1205 uint16_t fnum1, fnum2, fnum3;
1207 unsigned lock_timeout;
1210 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1213 cli_sockopt(cli1, sockops);
1214 cli_sockopt(cli2, sockops);
1216 printf("starting locktest1\n");
1218 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1220 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1227 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1228 if (!NT_STATUS_IS_OK(status)) {
1229 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1233 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1234 if (!NT_STATUS_IS_OK(status)) {
1235 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1239 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1240 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1245 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1246 printf("lock2 succeeded! This is a locking bug\n");
1249 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1250 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1254 lock_timeout = (1 + (random() % 20));
1255 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1257 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1258 printf("lock3 succeeded! This is a locking bug\n");
1261 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1262 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1266 if (ABS(t2 - t1) < lock_timeout-1) {
1267 printf("error: This server appears not to support timed lock requests\n");
1270 printf("server slept for %u seconds for a %u second timeout\n",
1271 (unsigned int)(t2-t1), lock_timeout);
1273 status = cli_close(cli1, fnum2);
1274 if (!NT_STATUS_IS_OK(status)) {
1275 printf("close1 failed (%s)\n", nt_errstr(status));
1279 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1280 printf("lock4 succeeded! This is a locking bug\n");
1283 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1284 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1287 status = cli_close(cli1, fnum1);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("close2 failed (%s)\n", nt_errstr(status));
1293 status = cli_close(cli2, fnum3);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("close3 failed (%s)\n", nt_errstr(status));
1299 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("unlink failed (%s)\n", nt_errstr(status));
1306 if (!torture_close_connection(cli1)) {
1310 if (!torture_close_connection(cli2)) {
1314 printf("Passed locktest1\n");
1319 this checks to see if a secondary tconx can use open files from an
1322 static bool run_tcon_test(int dummy)
1324 static struct cli_state *cli;
1325 const char *fname = "\\tcontest.tmp";
1327 uint16 cnum1, cnum2, cnum3;
1328 uint16 vuid1, vuid2;
1333 memset(buf, '\0', sizeof(buf));
1335 if (!torture_open_connection(&cli, 0)) {
1338 cli_sockopt(cli, sockops);
1340 printf("starting tcontest\n");
1342 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1344 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1353 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1354 if (!NT_STATUS_IS_OK(status)) {
1355 printf("initial write failed (%s)", nt_errstr(status));
1359 status = cli_tcon_andx(cli, share, "?????",
1360 password, strlen(password)+1);
1361 if (!NT_STATUS_IS_OK(status)) {
1362 printf("%s refused 2nd tree connect (%s)\n", host,
1369 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1370 vuid2 = cli->vuid + 1;
1372 /* try a write with the wrong tid */
1375 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1376 if (NT_STATUS_IS_OK(status)) {
1377 printf("* server allows write with wrong TID\n");
1380 printf("server fails write with wrong TID : %s\n",
1385 /* try a write with an invalid tid */
1388 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1389 if (NT_STATUS_IS_OK(status)) {
1390 printf("* server allows write with invalid TID\n");
1393 printf("server fails write with invalid TID : %s\n",
1397 /* try a write with an invalid vuid */
1401 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1402 if (NT_STATUS_IS_OK(status)) {
1403 printf("* server allows write with invalid VUID\n");
1406 printf("server fails write with invalid VUID : %s\n",
1413 status = cli_close(cli, fnum1);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 printf("close failed (%s)\n", nt_errstr(status));
1421 status = cli_tdis(cli);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1429 if (!torture_close_connection(cli)) {
1438 checks for old style tcon support
1440 static bool run_tcon2_test(int dummy)
1442 static struct cli_state *cli;
1443 uint16 cnum, max_xmit;
1447 if (!torture_open_connection(&cli, 0)) {
1450 cli_sockopt(cli, sockops);
1452 printf("starting tcon2 test\n");
1454 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1458 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 printf("tcon2 failed : %s\n", nt_errstr(status));
1465 printf("tcon OK : max_xmit=%d cnum=%d\n",
1466 (int)max_xmit, (int)cnum);
1469 if (!torture_close_connection(cli)) {
1473 printf("Passed tcon2 test\n");
1477 static bool tcon_devtest(struct cli_state *cli,
1478 const char *myshare, const char *devtype,
1479 const char *return_devtype,
1480 NTSTATUS expected_error)
1485 status = cli_tcon_andx(cli, myshare, devtype,
1486 password, strlen(password)+1);
1488 if (NT_STATUS_IS_OK(expected_error)) {
1489 if (NT_STATUS_IS_OK(status)) {
1490 if (strcmp(cli->dev, return_devtype) == 0) {
1493 printf("tconX to share %s with type %s "
1494 "succeeded but returned the wrong "
1495 "device type (got [%s] but should have got [%s])\n",
1496 myshare, devtype, cli->dev, return_devtype);
1500 printf("tconX to share %s with type %s "
1501 "should have succeeded but failed\n",
1507 if (NT_STATUS_IS_OK(status)) {
1508 printf("tconx to share %s with type %s "
1509 "should have failed but succeeded\n",
1513 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1517 printf("Returned unexpected error\n");
1526 checks for correct tconX support
1528 static bool run_tcon_devtype_test(int dummy)
1530 static struct cli_state *cli1 = NULL;
1535 status = cli_full_connection(&cli1, myname,
1536 host, NULL, port_to_use,
1538 username, workgroup,
1539 password, flags, signing_state);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("could not open connection\n");
1546 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1549 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1552 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1555 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1558 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1561 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1564 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1567 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1570 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1573 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1579 printf("Passed tcondevtest\n");
1586 This test checks that
1588 1) the server supports multiple locking contexts on the one SMB
1589 connection, distinguished by PID.
1591 2) the server correctly fails overlapping locks made by the same PID (this
1592 goes against POSIX behaviour, which is why it is tricky to implement)
1594 3) the server denies unlock requests by an incorrect client PID
1596 static bool run_locktest2(int dummy)
1598 static struct cli_state *cli;
1599 const char *fname = "\\lockt2.lck";
1600 uint16_t fnum1, fnum2, fnum3;
1601 bool correct = True;
1604 if (!torture_open_connection(&cli, 0)) {
1608 cli_sockopt(cli, sockops);
1610 printf("starting locktest2\n");
1612 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1616 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1622 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1623 if (!NT_STATUS_IS_OK(status)) {
1624 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1630 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1638 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1639 printf("lock1 failed (%s)\n", cli_errstr(cli));
1643 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1644 printf("WRITE lock1 succeeded! This is a locking bug\n");
1647 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1648 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1651 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1652 printf("WRITE lock2 succeeded! This is a locking bug\n");
1655 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1656 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1659 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1660 printf("READ lock2 succeeded! This is a locking bug\n");
1663 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1664 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1667 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1668 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1671 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1672 printf("unlock at 100 succeeded! This is a locking bug\n");
1676 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1677 printf("unlock1 succeeded! This is a locking bug\n");
1680 if (!check_error(__LINE__, cli,
1682 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1685 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1686 printf("unlock2 succeeded! This is a locking bug\n");
1689 if (!check_error(__LINE__, cli,
1691 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1694 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1695 printf("lock3 succeeded! This is a locking bug\n");
1698 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1703 status = cli_close(cli, fnum1);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 printf("close1 failed (%s)\n", nt_errstr(status));
1709 status = cli_close(cli, fnum2);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 printf("close2 failed (%s)\n", nt_errstr(status));
1715 status = cli_close(cli, fnum3);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 printf("close3 failed (%s)\n", nt_errstr(status));
1721 if (!torture_close_connection(cli)) {
1725 printf("locktest2 finished\n");
1732 This test checks that
1734 1) the server supports the full offset range in lock requests
1736 static bool run_locktest3(int dummy)
1738 static struct cli_state *cli1, *cli2;
1739 const char *fname = "\\lockt3.lck";
1740 uint16_t fnum1, fnum2;
1743 bool correct = True;
1746 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1748 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1751 cli_sockopt(cli1, sockops);
1752 cli_sockopt(cli2, sockops);
1754 printf("starting locktest3\n");
1756 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1758 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1760 if (!NT_STATUS_IS_OK(status)) {
1761 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1765 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1766 if (!NT_STATUS_IS_OK(status)) {
1767 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1771 for (offset=i=0;i<torture_numops;i++) {
1773 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1774 printf("lock1 %d failed (%s)\n",
1780 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1781 printf("lock2 %d failed (%s)\n",
1788 for (offset=i=0;i<torture_numops;i++) {
1791 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1792 printf("error: lock1 %d succeeded!\n", i);
1796 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1797 printf("error: lock2 %d succeeded!\n", i);
1801 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1802 printf("error: lock3 %d succeeded!\n", i);
1806 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1807 printf("error: lock4 %d succeeded!\n", i);
1812 for (offset=i=0;i<torture_numops;i++) {
1815 status = cli_unlock(cli1, fnum1, offset-1, 1);
1816 if (!NT_STATUS_IS_OK(status)) {
1817 printf("unlock1 %d failed (%s)\n",
1823 status = cli_unlock(cli2, fnum2, offset-2, 1);
1824 if (!NT_STATUS_IS_OK(status)) {
1825 printf("unlock2 %d failed (%s)\n",
1832 status = cli_close(cli1, fnum1);
1833 if (!NT_STATUS_IS_OK(status)) {
1834 printf("close1 failed (%s)\n", nt_errstr(status));
1838 status = cli_close(cli2, fnum2);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 printf("close2 failed (%s)\n", nt_errstr(status));
1844 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 printf("unlink failed (%s)\n", nt_errstr(status));
1850 if (!torture_close_connection(cli1)) {
1854 if (!torture_close_connection(cli2)) {
1858 printf("finished locktest3\n");
1863 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1864 printf("** "); correct = False; \
1868 looks at overlapping locks
1870 static bool run_locktest4(int dummy)
1872 static struct cli_state *cli1, *cli2;
1873 const char *fname = "\\lockt4.lck";
1874 uint16_t fnum1, fnum2, f;
1877 bool correct = True;
1880 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1884 cli_sockopt(cli1, sockops);
1885 cli_sockopt(cli2, sockops);
1887 printf("starting locktest4\n");
1889 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1891 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1892 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1894 memset(buf, 0, sizeof(buf));
1896 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1898 if (!NT_STATUS_IS_OK(status)) {
1899 printf("Failed to create file: %s\n", nt_errstr(status));
1904 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1905 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1906 EXPECTED(ret, False);
1907 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1909 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1910 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1911 EXPECTED(ret, True);
1912 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1914 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1915 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1916 EXPECTED(ret, False);
1917 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1919 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1920 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1921 EXPECTED(ret, True);
1922 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1924 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1925 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1926 EXPECTED(ret, False);
1927 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1929 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1930 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1931 EXPECTED(ret, True);
1932 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1934 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1935 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1936 EXPECTED(ret, True);
1937 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1939 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1940 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1941 EXPECTED(ret, False);
1942 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1944 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1945 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1946 EXPECTED(ret, False);
1947 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1949 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1950 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1951 EXPECTED(ret, True);
1952 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1954 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1955 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1956 EXPECTED(ret, False);
1957 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1959 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1960 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1961 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1962 EXPECTED(ret, False);
1963 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1966 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1967 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1968 EXPECTED(ret, False);
1969 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1971 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1973 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1975 ret = NT_STATUS_IS_OK(status);
1977 EXPECTED(ret, False);
1978 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1981 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1982 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1983 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1984 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1985 EXPECTED(ret, True);
1986 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1989 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1990 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1991 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1992 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1993 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1995 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1996 EXPECTED(ret, True);
1997 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1999 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
2000 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2001 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2003 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
2004 EXPECTED(ret, True);
2005 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2007 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
2008 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2009 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2011 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
2012 EXPECTED(ret, True);
2013 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2015 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
2016 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
2017 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2018 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2020 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
2021 EXPECTED(ret, True);
2022 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2024 cli_close(cli1, fnum1);
2025 cli_close(cli2, fnum2);
2026 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2027 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2028 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2029 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
2030 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2031 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2032 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2034 cli_close(cli1, fnum1);
2035 EXPECTED(ret, True);
2036 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2039 cli_close(cli1, fnum1);
2040 cli_close(cli2, fnum2);
2041 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2042 torture_close_connection(cli1);
2043 torture_close_connection(cli2);
2045 printf("finished locktest4\n");
2050 looks at lock upgrade/downgrade.
2052 static bool run_locktest5(int dummy)
2054 static struct cli_state *cli1, *cli2;
2055 const char *fname = "\\lockt5.lck";
2056 uint16_t fnum1, fnum2, fnum3;
2059 bool correct = True;
2062 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2066 cli_sockopt(cli1, sockops);
2067 cli_sockopt(cli2, sockops);
2069 printf("starting locktest5\n");
2071 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2073 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2074 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2075 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2077 memset(buf, 0, sizeof(buf));
2079 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2081 if (!NT_STATUS_IS_OK(status)) {
2082 printf("Failed to create file: %s\n", nt_errstr(status));
2087 /* Check for NT bug... */
2088 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2089 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2090 cli_close(cli1, fnum1);
2091 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2092 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2093 EXPECTED(ret, True);
2094 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2095 cli_close(cli1, fnum1);
2096 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2097 cli_unlock(cli1, fnum3, 0, 1);
2099 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2100 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2101 EXPECTED(ret, True);
2102 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2104 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2105 EXPECTED(ret, False);
2107 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2109 /* Unlock the process 2 lock. */
2110 cli_unlock(cli2, fnum2, 0, 4);
2112 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2113 EXPECTED(ret, False);
2115 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2117 /* Unlock the process 1 fnum3 lock. */
2118 cli_unlock(cli1, fnum3, 0, 4);
2120 /* Stack 2 more locks here. */
2121 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2122 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2124 EXPECTED(ret, True);
2125 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2127 /* Unlock the first process lock, then check this was the WRITE lock that was
2130 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2131 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2133 EXPECTED(ret, True);
2134 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2136 /* Unlock the process 2 lock. */
2137 cli_unlock(cli2, fnum2, 0, 4);
2139 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2141 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2142 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2143 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2145 EXPECTED(ret, True);
2146 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2148 /* Ensure the next unlock fails. */
2149 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2150 EXPECTED(ret, False);
2151 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2153 /* Ensure connection 2 can get a write lock. */
2154 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2155 EXPECTED(ret, True);
2157 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2161 cli_close(cli1, fnum1);
2162 cli_close(cli2, fnum2);
2163 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2164 if (!torture_close_connection(cli1)) {
2167 if (!torture_close_connection(cli2)) {
2171 printf("finished locktest5\n");
2177 tries the unusual lockingX locktype bits
2179 static bool run_locktest6(int dummy)
2181 static struct cli_state *cli;
2182 const char *fname[1] = { "\\lock6.txt" };
2187 if (!torture_open_connection(&cli, 0)) {
2191 cli_sockopt(cli, sockops);
2193 printf("starting locktest6\n");
2196 printf("Testing %s\n", fname[i]);
2198 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2200 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2201 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2202 cli_close(cli, fnum);
2203 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2205 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2206 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2207 cli_close(cli, fnum);
2208 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2210 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2213 torture_close_connection(cli);
2215 printf("finished locktest6\n");
2219 static bool run_locktest7(int dummy)
2221 struct cli_state *cli1;
2222 const char *fname = "\\lockt7.lck";
2225 bool correct = False;
2228 if (!torture_open_connection(&cli1, 0)) {
2232 cli_sockopt(cli1, sockops);
2234 printf("starting locktest7\n");
2236 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2238 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2240 memset(buf, 0, sizeof(buf));
2242 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2244 if (!NT_STATUS_IS_OK(status)) {
2245 printf("Failed to create file: %s\n", nt_errstr(status));
2249 cli_setpid(cli1, 1);
2251 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2252 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2255 printf("pid1 successfully locked range 130:4 for READ\n");
2258 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2259 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2262 printf("pid1 successfully read the range 130:4\n");
2265 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2266 if (!NT_STATUS_IS_OK(status)) {
2267 printf("pid1 unable to write to the range 130:4, error was "
2268 "%s\n", nt_errstr(status));
2269 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2270 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2274 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2278 cli_setpid(cli1, 2);
2280 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2281 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2283 printf("pid2 successfully read the range 130:4\n");
2286 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2287 if (!NT_STATUS_IS_OK(status)) {
2288 printf("pid2 unable to write to the range 130:4, error was "
2289 "%s\n", nt_errstr(status));
2290 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2291 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2295 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2299 cli_setpid(cli1, 1);
2300 cli_unlock(cli1, fnum1, 130, 4);
2302 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2303 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2306 printf("pid1 successfully locked range 130:4 for WRITE\n");
2309 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2310 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2313 printf("pid1 successfully read the range 130:4\n");
2316 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2317 if (!NT_STATUS_IS_OK(status)) {
2318 printf("pid1 unable to write to the range 130:4, error was "
2319 "%s\n", nt_errstr(status));
2322 printf("pid1 successfully wrote to the range 130:4\n");
2325 cli_setpid(cli1, 2);
2327 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2328 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2329 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2330 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2334 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2338 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2339 if (!NT_STATUS_IS_OK(status)) {
2340 printf("pid2 unable to write to the range 130:4, error was "
2341 "%s\n", nt_errstr(status));
2342 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2343 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2347 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2351 cli_unlock(cli1, fnum1, 130, 0);
2355 cli_close(cli1, fnum1);
2356 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2357 torture_close_connection(cli1);
2359 printf("finished locktest7\n");
2364 * This demonstrates a problem with our use of GPFS share modes: A file
2365 * descriptor sitting in the pending close queue holding a GPFS share mode
2366 * blocks opening a file another time. Happens with Word 2007 temp files.
2367 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2368 * open is denied with NT_STATUS_SHARING_VIOLATION.
2371 static bool run_locktest8(int dummy)
2373 struct cli_state *cli1;
2374 const char *fname = "\\lockt8.lck";
2375 uint16_t fnum1, fnum2;
2377 bool correct = False;
2380 if (!torture_open_connection(&cli1, 0)) {
2384 cli_sockopt(cli1, sockops);
2386 printf("starting locktest8\n");
2388 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2390 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2392 if (!NT_STATUS_IS_OK(status)) {
2393 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2397 memset(buf, 0, sizeof(buf));
2399 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2400 if (!NT_STATUS_IS_OK(status)) {
2401 d_fprintf(stderr, "cli_open second time returned %s\n",
2406 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2407 printf("Unable to apply read lock on range 1:1, error was "
2408 "%s\n", cli_errstr(cli1));
2412 status = cli_close(cli1, fnum1);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2418 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2419 if (!NT_STATUS_IS_OK(status)) {
2420 d_fprintf(stderr, "cli_open third time returned %s\n",
2428 cli_close(cli1, fnum1);
2429 cli_close(cli1, fnum2);
2430 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2431 torture_close_connection(cli1);
2433 printf("finished locktest8\n");
2438 * This test is designed to be run in conjunction with
2439 * external NFS or POSIX locks taken in the filesystem.
2440 * It checks that the smbd server will block until the
2441 * lock is released and then acquire it. JRA.
2444 static bool got_alarm;
2445 static int alarm_fd;
2447 static void alarm_handler(int dummy)
2452 static void alarm_handler_parent(int dummy)
2457 static void do_local_lock(int read_fd, int write_fd)
2462 const char *local_pathname = NULL;
2465 local_pathname = talloc_asprintf(talloc_tos(),
2466 "%s/lockt9.lck", local_path);
2467 if (!local_pathname) {
2468 printf("child: alloc fail\n");
2472 unlink(local_pathname);
2473 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2475 printf("child: open of %s failed %s.\n",
2476 local_pathname, strerror(errno));
2480 /* Now take a fcntl lock. */
2481 lock.l_type = F_WRLCK;
2482 lock.l_whence = SEEK_SET;
2485 lock.l_pid = getpid();
2487 ret = fcntl(fd,F_SETLK,&lock);
2489 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2490 local_pathname, strerror(errno));
2493 printf("child: got lock 0:4 on file %s.\n",
2498 CatchSignal(SIGALRM, alarm_handler);
2500 /* Signal the parent. */
2501 if (write(write_fd, &c, 1) != 1) {
2502 printf("child: start signal fail %s.\n",
2509 /* Wait for the parent to be ready. */
2510 if (read(read_fd, &c, 1) != 1) {
2511 printf("child: reply signal fail %s.\n",
2519 printf("child: released lock 0:4 on file %s.\n",
2525 static bool run_locktest9(int dummy)
2527 struct cli_state *cli1;
2528 const char *fname = "\\lockt9.lck";
2530 bool correct = False;
2531 int pipe_in[2], pipe_out[2];
2535 struct timeval start;
2539 printf("starting locktest9\n");
2541 if (local_path == NULL) {
2542 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2546 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2551 if (child_pid == -1) {
2555 if (child_pid == 0) {
2557 do_local_lock(pipe_out[0], pipe_in[1]);
2567 ret = read(pipe_in[0], &c, 1);
2569 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2574 if (!torture_open_connection(&cli1, 0)) {
2578 cli_sockopt(cli1, sockops);
2580 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2582 if (!NT_STATUS_IS_OK(status)) {
2583 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2587 /* Ensure the child has the lock. */
2588 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2589 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2592 d_printf("Child has the lock.\n");
2595 /* Tell the child to wait 5 seconds then exit. */
2596 ret = write(pipe_out[1], &c, 1);
2598 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2603 /* Wait 20 seconds for the lock. */
2604 alarm_fd = cli1->fd;
2605 CatchSignal(SIGALRM, alarm_handler_parent);
2608 start = timeval_current();
2610 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2611 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2612 "%s\n", cli_errstr(cli1));
2617 seconds = timeval_elapsed(&start);
2619 printf("Parent got the lock after %.2f seconds.\n",
2622 status = cli_close(cli1, fnum);
2623 if (!NT_STATUS_IS_OK(status)) {
2624 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2631 cli_close(cli1, fnum);
2632 torture_close_connection(cli1);
2636 printf("finished locktest9\n");
2641 test whether fnums and tids open on one VC are available on another (a major
2644 static bool run_fdpasstest(int dummy)
2646 struct cli_state *cli1, *cli2;
2647 const char *fname = "\\fdpass.tst";
2652 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2655 cli_sockopt(cli1, sockops);
2656 cli_sockopt(cli2, sockops);
2658 printf("starting fdpasstest\n");
2660 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2662 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2664 if (!NT_STATUS_IS_OK(status)) {
2665 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2669 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2671 if (!NT_STATUS_IS_OK(status)) {
2672 printf("write failed (%s)\n", nt_errstr(status));
2676 cli2->vuid = cli1->vuid;
2677 cli2->cnum = cli1->cnum;
2678 cli2->pid = cli1->pid;
2680 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2681 printf("read succeeded! nasty security hole [%s]\n",
2686 cli_close(cli1, fnum1);
2687 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2689 torture_close_connection(cli1);
2690 torture_close_connection(cli2);
2692 printf("finished fdpasstest\n");
2696 static bool run_fdsesstest(int dummy)
2698 struct cli_state *cli;
2703 const char *fname = "\\fdsess.tst";
2704 const char *fname1 = "\\fdsess1.tst";
2711 if (!torture_open_connection(&cli, 0))
2713 cli_sockopt(cli, sockops);
2715 if (!torture_cli_session_setup2(cli, &new_vuid))
2718 saved_cnum = cli->cnum;
2719 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2721 new_cnum = cli->cnum;
2722 cli->cnum = saved_cnum;
2724 printf("starting fdsesstest\n");
2726 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2727 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2729 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2730 if (!NT_STATUS_IS_OK(status)) {
2731 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2735 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2737 if (!NT_STATUS_IS_OK(status)) {
2738 printf("write failed (%s)\n", nt_errstr(status));
2742 saved_vuid = cli->vuid;
2743 cli->vuid = new_vuid;
2745 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2746 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2750 /* Try to open a file with different vuid, samba cnum. */
2751 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2752 printf("create with different vuid, same cnum succeeded.\n");
2753 cli_close(cli, fnum2);
2754 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2756 printf("create with different vuid, same cnum failed.\n");
2757 printf("This will cause problems with service clients.\n");
2761 cli->vuid = saved_vuid;
2763 /* Try with same vuid, different cnum. */
2764 cli->cnum = new_cnum;
2766 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2767 printf("read succeeded with different cnum![%s]\n",
2772 cli->cnum = saved_cnum;
2773 cli_close(cli, fnum1);
2774 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2776 torture_close_connection(cli);
2778 printf("finished fdsesstest\n");
2783 This test checks that
2785 1) the server does not allow an unlink on a file that is open
2787 static bool run_unlinktest(int dummy)
2789 struct cli_state *cli;
2790 const char *fname = "\\unlink.tst";
2792 bool correct = True;
2795 if (!torture_open_connection(&cli, 0)) {
2799 cli_sockopt(cli, sockops);
2801 printf("starting unlink test\n");
2803 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2807 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2808 if (!NT_STATUS_IS_OK(status)) {
2809 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2813 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2814 printf("error: server allowed unlink on an open file\n");
2817 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2818 NT_STATUS_SHARING_VIOLATION);
2821 cli_close(cli, fnum);
2822 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2824 if (!torture_close_connection(cli)) {
2828 printf("unlink test finished\n");
2835 test how many open files this server supports on the one socket
2837 static bool run_maxfidtest(int dummy)
2839 struct cli_state *cli;
2841 uint16_t fnums[0x11000];
2844 bool correct = True;
2850 printf("failed to connect\n");
2854 cli_sockopt(cli, sockops);
2856 for (i=0; i<0x11000; i++) {
2857 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2858 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2860 if (!NT_STATUS_IS_OK(status)) {
2861 printf("open of %s failed (%s)\n",
2862 fname, nt_errstr(status));
2863 printf("maximum fnum is %d\n", i);
2871 printf("cleaning up\n");
2873 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2874 cli_close(cli, fnums[i]);
2876 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("unlink of %s failed (%s)\n",
2879 fname, nt_errstr(status));
2886 printf("maxfid test finished\n");
2887 if (!torture_close_connection(cli)) {
2893 /* generate a random buffer */
2894 static void rand_buf(char *buf, int len)
2897 *buf = (char)sys_random();
2902 /* send smb negprot commands, not reading the response */
2903 static bool run_negprot_nowait(int dummy)
2905 struct tevent_context *ev;
2907 struct cli_state *cli;
2908 bool correct = True;
2910 printf("starting negprot nowait test\n");
2912 ev = tevent_context_init(talloc_tos());
2917 if (!(cli = open_nbt_connection())) {
2922 for (i=0;i<50000;i++) {
2923 struct tevent_req *req;
2925 req = cli_negprot_send(ev, ev, cli);
2930 if (!tevent_req_poll(req, ev)) {
2931 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2939 if (torture_close_connection(cli)) {
2943 printf("finished negprot nowait test\n");
2948 /* send smb negprot commands, not reading the response */
2949 static bool run_bad_nbt_session(int dummy)
2951 static struct cli_state *cli;
2953 printf("starting bad nbt session test\n");
2955 if (!(cli = open_bad_nbt_connection())) {
2960 printf("finished bad nbt session test\n");
2964 /* send random IPC commands */
2965 static bool run_randomipc(int dummy)
2967 char *rparam = NULL;
2969 unsigned int rdrcnt,rprcnt;
2971 int api, param_len, i;
2972 struct cli_state *cli;
2973 bool correct = True;
2976 printf("starting random ipc test\n");
2978 if (!torture_open_connection(&cli, 0)) {
2982 for (i=0;i<count;i++) {
2983 api = sys_random() % 500;
2984 param_len = (sys_random() % 64);
2986 rand_buf(param, param_len);
2991 param, param_len, 8,
2992 NULL, 0, BUFFER_SIZE,
2996 printf("%d/%d\r", i,count);
2999 printf("%d/%d\n", i, count);
3001 if (!torture_close_connection(cli)) {
3005 printf("finished random ipc test\n");
3012 static void browse_callback(const char *sname, uint32 stype,
3013 const char *comment, void *state)
3015 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3021 This test checks the browse list code
3024 static bool run_browsetest(int dummy)
3026 static struct cli_state *cli;
3027 bool correct = True;
3029 printf("starting browse test\n");
3031 if (!torture_open_connection(&cli, 0)) {
3035 printf("domain list:\n");
3036 cli_NetServerEnum(cli, cli->server_domain,
3037 SV_TYPE_DOMAIN_ENUM,
3038 browse_callback, NULL);
3040 printf("machine list:\n");
3041 cli_NetServerEnum(cli, cli->server_domain,
3043 browse_callback, NULL);
3045 if (!torture_close_connection(cli)) {
3049 printf("browse test finished\n");
3057 This checks how the getatr calls works
3059 static bool run_attrtest(int dummy)
3061 struct cli_state *cli;
3064 const char *fname = "\\attrib123456789.tst";
3065 bool correct = True;
3068 printf("starting attrib test\n");
3070 if (!torture_open_connection(&cli, 0)) {
3074 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3075 cli_open(cli, fname,
3076 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3077 cli_close(cli, fnum);
3079 status = cli_getatr(cli, fname, NULL, NULL, &t);
3080 if (!NT_STATUS_IS_OK(status)) {
3081 printf("getatr failed (%s)\n", nt_errstr(status));
3085 if (abs(t - time(NULL)) > 60*60*24*10) {
3086 printf("ERROR: SMBgetatr bug. time is %s",
3092 t2 = t-60*60*24; /* 1 day ago */
3094 status = cli_setatr(cli, fname, 0, t2);
3095 if (!NT_STATUS_IS_OK(status)) {
3096 printf("setatr failed (%s)\n", nt_errstr(status));
3100 status = cli_getatr(cli, fname, NULL, NULL, &t);
3101 if (!NT_STATUS_IS_OK(status)) {
3102 printf("getatr failed (%s)\n", nt_errstr(status));
3107 printf("ERROR: getatr/setatr bug. times are\n%s",
3109 printf("%s", ctime(&t2));
3113 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3115 if (!torture_close_connection(cli)) {
3119 printf("attrib test finished\n");
3126 This checks a couple of trans2 calls
3128 static bool run_trans2test(int dummy)
3130 struct cli_state *cli;
3133 time_t c_time, a_time, m_time;
3134 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3135 const char *fname = "\\trans2.tst";
3136 const char *dname = "\\trans2";
3137 const char *fname2 = "\\trans2\\trans2.tst";
3139 bool correct = True;
3143 printf("starting trans2 test\n");
3145 if (!torture_open_connection(&cli, 0)) {
3149 status = cli_get_fs_attr_info(cli, &fs_attr);
3150 if (!NT_STATUS_IS_OK(status)) {
3151 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3156 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3157 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3158 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3159 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3165 status = cli_qfilename(cli, fnum, pname, sizeof(pname));
3166 if (!NT_STATUS_IS_OK(status)) {
3167 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3171 if (strcmp(pname, fname)) {
3172 printf("qfilename gave different name? [%s] [%s]\n",
3177 cli_close(cli, fnum);
3181 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3182 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3184 if (!NT_STATUS_IS_OK(status)) {
3185 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3188 cli_close(cli, fnum);
3190 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3192 if (!NT_STATUS_IS_OK(status)) {
3193 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3196 if (c_time != m_time) {
3197 printf("create time=%s", ctime(&c_time));
3198 printf("modify time=%s", ctime(&m_time));
3199 printf("This system appears to have sticky create times\n");
3201 if (a_time % (60*60) == 0) {
3202 printf("access time=%s", ctime(&a_time));
3203 printf("This system appears to set a midnight access time\n");
3207 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3208 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3214 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3215 cli_open(cli, fname,
3216 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3217 cli_close(cli, fnum);
3218 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3219 &m_time_ts, &size, NULL, NULL);
3220 if (!NT_STATUS_IS_OK(status)) {
3221 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3224 if (w_time_ts.tv_sec < 60*60*24*2) {
3225 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3226 printf("This system appears to set a initial 0 write time\n");
3231 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3234 /* check if the server updates the directory modification time
3235 when creating a new file */
3236 status = cli_mkdir(cli, dname);
3237 if (!NT_STATUS_IS_OK(status)) {
3238 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3242 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3243 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3244 if (!NT_STATUS_IS_OK(status)) {
3245 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3249 cli_open(cli, fname2,
3250 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3251 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3252 cli_close(cli, fnum);
3253 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3254 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3259 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3261 printf("This system does not update directory modification times\n");
3265 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3266 cli_rmdir(cli, dname);
3268 if (!torture_close_connection(cli)) {
3272 printf("trans2 test finished\n");
3278 This checks new W2K calls.
3281 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3283 uint8_t *buf = NULL;
3287 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3288 pcli->max_xmit, &buf, &len);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3293 printf("qfileinfo: level %d, len = %u\n", level, len);
3294 dump_data(0, (uint8 *)buf, len);
3301 static bool run_w2ktest(int dummy)
3303 struct cli_state *cli;
3305 const char *fname = "\\w2ktest\\w2k.tst";
3307 bool correct = True;
3309 printf("starting w2k test\n");
3311 if (!torture_open_connection(&cli, 0)) {
3315 cli_open(cli, fname,
3316 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3318 for (level = 1004; level < 1040; level++) {
3319 new_trans(cli, fnum, level);
3322 cli_close(cli, fnum);
3324 if (!torture_close_connection(cli)) {
3328 printf("w2k test finished\n");
3335 this is a harness for some oplock tests
3337 static bool run_oplock1(int dummy)
3339 struct cli_state *cli1;
3340 const char *fname = "\\lockt1.lck";
3342 bool correct = True;
3345 printf("starting oplock test 1\n");
3347 if (!torture_open_connection(&cli1, 0)) {
3351 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3353 cli_sockopt(cli1, sockops);
3355 cli1->use_oplocks = True;
3357 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3359 if (!NT_STATUS_IS_OK(status)) {
3360 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3364 cli1->use_oplocks = False;
3366 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3367 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3369 status = cli_close(cli1, fnum1);
3370 if (!NT_STATUS_IS_OK(status)) {
3371 printf("close2 failed (%s)\n", nt_errstr(status));
3375 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3376 if (!NT_STATUS_IS_OK(status)) {
3377 printf("unlink failed (%s)\n", nt_errstr(status));
3381 if (!torture_close_connection(cli1)) {
3385 printf("finished oplock test 1\n");
3390 static bool run_oplock2(int dummy)
3392 struct cli_state *cli1, *cli2;
3393 const char *fname = "\\lockt2.lck";
3394 uint16_t fnum1, fnum2;
3395 int saved_use_oplocks = use_oplocks;
3397 bool correct = True;
3398 volatile bool *shared_correct;
3401 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3402 *shared_correct = True;
3404 use_level_II_oplocks = True;
3407 printf("starting oplock test 2\n");
3409 if (!torture_open_connection(&cli1, 0)) {
3410 use_level_II_oplocks = False;
3411 use_oplocks = saved_use_oplocks;
3415 cli1->use_oplocks = True;
3416 cli1->use_level_II_oplocks = True;
3418 if (!torture_open_connection(&cli2, 1)) {
3419 use_level_II_oplocks = False;
3420 use_oplocks = saved_use_oplocks;
3424 cli2->use_oplocks = True;
3425 cli2->use_level_II_oplocks = True;
3427 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3429 cli_sockopt(cli1, sockops);
3430 cli_sockopt(cli2, sockops);
3432 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3434 if (!NT_STATUS_IS_OK(status)) {
3435 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3439 /* Don't need the globals any more. */
3440 use_level_II_oplocks = False;
3441 use_oplocks = saved_use_oplocks;
3445 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3446 if (!NT_STATUS_IS_OK(status)) {
3447 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3448 *shared_correct = False;
3454 status = cli_close(cli2, fnum2);
3455 if (!NT_STATUS_IS_OK(status)) {
3456 printf("close2 failed (%s)\n", nt_errstr(status));
3457 *shared_correct = False;
3465 /* Ensure cli1 processes the break. Empty file should always return 0
3468 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3469 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3473 /* Should now be at level II. */
3474 /* Test if sending a write locks causes a break to none. */
3476 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3477 printf("lock failed (%s)\n", cli_errstr(cli1));
3481 cli_unlock(cli1, fnum1, 0, 4);
3485 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3486 printf("lock failed (%s)\n", cli_errstr(cli1));
3490 cli_unlock(cli1, fnum1, 0, 4);
3494 cli_read(cli1, fnum1, buf, 0, 4);
3496 status = cli_close(cli1, fnum1);
3497 if (!NT_STATUS_IS_OK(status)) {
3498 printf("close1 failed (%s)\n", nt_errstr(status));
3504 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3505 if (!NT_STATUS_IS_OK(status)) {
3506 printf("unlink failed (%s)\n", nt_errstr(status));
3510 if (!torture_close_connection(cli1)) {
3514 if (!*shared_correct) {
3518 printf("finished oplock test 2\n");
3523 struct oplock4_state {
3524 struct tevent_context *ev;
3525 struct cli_state *cli;
3530 static void oplock4_got_break(struct tevent_req *req);
3531 static void oplock4_got_open(struct tevent_req *req);
3533 static bool run_oplock4(int dummy)
3535 struct tevent_context *ev;
3536 struct cli_state *cli1, *cli2;
3537 struct tevent_req *oplock_req, *open_req;
3538 const char *fname = "\\lockt4.lck";
3539 const char *fname_ln = "\\lockt4_ln.lck";
3540 uint16_t fnum1, fnum2;
3541 int saved_use_oplocks = use_oplocks;
3543 bool correct = true;
3547 struct oplock4_state *state;
3549 printf("starting oplock test 4\n");
3551 if (!torture_open_connection(&cli1, 0)) {
3552 use_level_II_oplocks = false;
3553 use_oplocks = saved_use_oplocks;
3557 if (!torture_open_connection(&cli2, 1)) {
3558 use_level_II_oplocks = false;
3559 use_oplocks = saved_use_oplocks;
3563 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3564 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3566 cli_sockopt(cli1, sockops);
3567 cli_sockopt(cli2, sockops);
3569 /* Create the file. */
3570 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3572 if (!NT_STATUS_IS_OK(status)) {
3573 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3577 status = cli_close(cli1, fnum1);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 printf("close1 failed (%s)\n", nt_errstr(status));
3583 /* Now create a hardlink. */
3584 status = cli_nt_hardlink(cli1, fname, fname_ln);
3585 if (!NT_STATUS_IS_OK(status)) {
3586 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3590 /* Prove that opening hardlinks cause deny modes to conflict. */
3591 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3592 if (!NT_STATUS_IS_OK(status)) {
3593 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3597 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3598 if (NT_STATUS_IS_OK(status)) {
3599 printf("open of %s succeeded - should fail with sharing violation.\n",
3604 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3605 printf("open of %s should fail with sharing violation. Got %s\n",
3606 fname_ln, nt_errstr(status));
3610 status = cli_close(cli1, fnum1);
3611 if (!NT_STATUS_IS_OK(status)) {
3612 printf("close1 failed (%s)\n", nt_errstr(status));
3616 cli1->use_oplocks = true;
3617 cli1->use_level_II_oplocks = true;
3619 cli2->use_oplocks = true;
3620 cli2->use_level_II_oplocks = true;
3622 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3623 if (!NT_STATUS_IS_OK(status)) {
3624 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3628 ev = tevent_context_init(talloc_tos());
3630 printf("tevent_req_create failed\n");
3634 state = talloc(ev, struct oplock4_state);
3635 if (state == NULL) {
3636 printf("talloc failed\n");
3641 state->got_break = &got_break;
3642 state->fnum2 = &fnum2;
3644 oplock_req = cli_smb_oplock_break_waiter_send(
3645 talloc_tos(), ev, cli1);
3646 if (oplock_req == NULL) {
3647 printf("cli_smb_oplock_break_waiter_send failed\n");
3650 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3652 open_req = cli_open_send(
3653 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3654 if (oplock_req == NULL) {
3655 printf("cli_open_send failed\n");
3658 tevent_req_set_callback(open_req, oplock4_got_open, state);
3663 while (!got_break || fnum2 == 0xffff) {
3665 ret = tevent_loop_once(ev);
3667 printf("tevent_loop_once failed: %s\n",
3673 status = cli_close(cli2, fnum2);
3674 if (!NT_STATUS_IS_OK(status)) {
3675 printf("close2 failed (%s)\n", nt_errstr(status));
3679 status = cli_close(cli1, fnum1);
3680 if (!NT_STATUS_IS_OK(status)) {
3681 printf("close1 failed (%s)\n", nt_errstr(status));
3685 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3686 if (!NT_STATUS_IS_OK(status)) {
3687 printf("unlink failed (%s)\n", nt_errstr(status));
3691 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3692 if (!NT_STATUS_IS_OK(status)) {
3693 printf("unlink failed (%s)\n", nt_errstr(status));
3697 if (!torture_close_connection(cli1)) {
3705 printf("finished oplock test 4\n");
3710 static void oplock4_got_break(struct tevent_req *req)
3712 struct oplock4_state *state = tevent_req_callback_data(
3713 req, struct oplock4_state);
3718 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3720 if (!NT_STATUS_IS_OK(status)) {
3721 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3725 *state->got_break = true;
3727 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3730 printf("cli_oplock_ack_send failed\n");
3735 static void oplock4_got_open(struct tevent_req *req)
3737 struct oplock4_state *state = tevent_req_callback_data(
3738 req, struct oplock4_state);
3741 status = cli_open_recv(req, state->fnum2);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 printf("cli_open_recv returned %s\n", nt_errstr(status));
3744 *state->fnum2 = 0xffff;
3749 Test delete on close semantics.
3751 static bool run_deletetest(int dummy)
3753 struct cli_state *cli1 = NULL;
3754 struct cli_state *cli2 = NULL;
3755 const char *fname = "\\delete.file";
3756 uint16_t fnum1 = (uint16_t)-1;
3757 uint16_t fnum2 = (uint16_t)-1;
3758 bool correct = True;
3761 printf("starting delete test\n");
3763 if (!torture_open_connection(&cli1, 0)) {
3767 cli_sockopt(cli1, sockops);
3769 /* Test 1 - this should delete the file on close. */
3771 cli_setatr(cli1, fname, 0, 0);
3772 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3774 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3775 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3776 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3777 if (!NT_STATUS_IS_OK(status)) {
3778 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3783 status = cli_close(cli1, fnum1);
3784 if (!NT_STATUS_IS_OK(status)) {
3785 printf("[1] close failed (%s)\n", nt_errstr(status));
3790 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3791 printf("[1] open of %s succeeded (should fail)\n", fname);
3796 printf("first delete on close test succeeded.\n");
3798 /* Test 2 - this should delete the file on close. */
3800 cli_setatr(cli1, fname, 0, 0);
3801 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3803 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3804 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3805 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3806 if (!NT_STATUS_IS_OK(status)) {
3807 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3812 status = cli_nt_delete_on_close(cli1, fnum1, true);
3813 if (!NT_STATUS_IS_OK(status)) {
3814 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3819 status = cli_close(cli1, fnum1);
3820 if (!NT_STATUS_IS_OK(status)) {
3821 printf("[2] close failed (%s)\n", nt_errstr(status));
3826 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3827 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3828 status = cli_close(cli1, fnum1);
3829 if (!NT_STATUS_IS_OK(status)) {
3830 printf("[2] close failed (%s)\n", nt_errstr(status));
3834 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3836 printf("second delete on close test succeeded.\n");
3839 cli_setatr(cli1, fname, 0, 0);
3840 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3842 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3843 FILE_ATTRIBUTE_NORMAL,
3844 FILE_SHARE_READ|FILE_SHARE_WRITE,
3845 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3852 /* This should fail with a sharing violation - open for delete is only compatible
3853 with SHARE_DELETE. */
3855 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3856 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3857 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3862 /* This should succeed. */
3863 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3864 FILE_ATTRIBUTE_NORMAL,
3865 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3866 FILE_OPEN, 0, 0, &fnum2);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3873 status = cli_nt_delete_on_close(cli1, fnum1, true);
3874 if (!NT_STATUS_IS_OK(status)) {
3875 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3880 status = cli_close(cli1, fnum1);
3881 if (!NT_STATUS_IS_OK(status)) {
3882 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3887 status = cli_close(cli1, fnum2);
3888 if (!NT_STATUS_IS_OK(status)) {
3889 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3894 /* This should fail - file should no longer be there. */
3896 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3897 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3898 status = cli_close(cli1, fnum1);
3899 if (!NT_STATUS_IS_OK(status)) {
3900 printf("[3] close failed (%s)\n", nt_errstr(status));
3902 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3906 printf("third delete on close test succeeded.\n");
3909 cli_setatr(cli1, fname, 0, 0);
3910 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3912 status = cli_ntcreate(cli1, fname, 0,
3913 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3914 FILE_ATTRIBUTE_NORMAL,
3915 FILE_SHARE_READ|FILE_SHARE_WRITE,
3916 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3917 if (!NT_STATUS_IS_OK(status)) {
3918 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3923 /* This should succeed. */
3924 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3925 FILE_ATTRIBUTE_NORMAL,
3926 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3927 FILE_OPEN, 0, 0, &fnum2);
3928 if (!NT_STATUS_IS_OK(status)) {
3929 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3934 status = cli_close(cli1, fnum2);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3941 status = cli_nt_delete_on_close(cli1, fnum1, true);
3942 if (!NT_STATUS_IS_OK(status)) {
3943 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3948 /* This should fail - no more opens once delete on close set. */
3949 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3950 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3951 FILE_OPEN, 0, 0, &fnum2))) {
3952 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3956 printf("fourth delete on close test succeeded.\n");
3958 status = cli_close(cli1, fnum1);
3959 if (!NT_STATUS_IS_OK(status)) {
3960 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3966 cli_setatr(cli1, fname, 0, 0);
3967 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3969 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3970 if (!NT_STATUS_IS_OK(status)) {
3971 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3976 /* This should fail - only allowed on NT opens with DELETE access. */
3978 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3979 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3984 status = cli_close(cli1, fnum1);
3985 if (!NT_STATUS_IS_OK(status)) {
3986 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3991 printf("fifth delete on close test succeeded.\n");
3994 cli_setatr(cli1, fname, 0, 0);
3995 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3997 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3998 FILE_ATTRIBUTE_NORMAL,
3999 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4000 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 printf("[6] open of %s failed (%s)\n", fname,
4008 /* This should fail - only allowed on NT opens with DELETE access. */
4010 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4011 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4016 status = cli_close(cli1, fnum1);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4023 printf("sixth delete on close test succeeded.\n");
4026 cli_setatr(cli1, fname, 0, 0);
4027 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4029 status = cli_ntcreate(cli1, fname, 0,
4030 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4031 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4033 if (!NT_STATUS_IS_OK(status)) {
4034 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4039 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4040 printf("[7] setting delete_on_close on file failed !\n");
4045 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4046 printf("[7] unsetting delete_on_close on file failed !\n");
4051 status = cli_close(cli1, fnum1);
4052 if (!NT_STATUS_IS_OK(status)) {
4053 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4058 /* This next open should succeed - we reset the flag. */
4059 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4066 status = cli_close(cli1, fnum1);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4073 printf("seventh delete on close test succeeded.\n");
4076 cli_setatr(cli1, fname, 0, 0);
4077 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4079 if (!torture_open_connection(&cli2, 1)) {
4080 printf("[8] failed to open second connection.\n");
4085 cli_sockopt(cli1, sockops);
4087 status = cli_ntcreate(cli1, fname, 0,
4088 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4089 FILE_ATTRIBUTE_NORMAL,
4090 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4091 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4098 status = cli_ntcreate(cli2, fname, 0,
4099 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4100 FILE_ATTRIBUTE_NORMAL,
4101 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4102 FILE_OPEN, 0, 0, &fnum2);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4109 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4110 printf("[8] setting delete_on_close on file failed !\n");
4115 status = cli_close(cli1, fnum1);
4116 if (!NT_STATUS_IS_OK(status)) {
4117 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4122 status = cli_close(cli2, fnum2);
4123 if (!NT_STATUS_IS_OK(status)) {
4124 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4129 /* This should fail.. */
4130 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4131 if (NT_STATUS_IS_OK(status)) {
4132 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4136 printf("eighth delete on close test succeeded.\n");
4138 /* This should fail - we need to set DELETE_ACCESS. */
4139 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4140 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4141 printf("[9] open of %s succeeded should have failed!\n", fname);
4146 printf("ninth delete on close test succeeded.\n");
4148 status = cli_ntcreate(cli1, fname, 0,
4149 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4150 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4151 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4153 if (!NT_STATUS_IS_OK(status)) {
4154 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4159 /* This should delete the file. */
4160 status = cli_close(cli1, fnum1);
4161 if (!NT_STATUS_IS_OK(status)) {
4162 printf("[10] close failed (%s)\n", nt_errstr(status));
4167 /* This should fail.. */
4168 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4169 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4173 printf("tenth delete on close test succeeded.\n");
4175 cli_setatr(cli1, fname, 0, 0);
4176 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4178 /* What error do we get when attempting to open a read-only file with
4181 /* Create a readonly file. */
4182 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4183 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4184 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4191 status = cli_close(cli1, fnum1);
4192 if (!NT_STATUS_IS_OK(status)) {
4193 printf("[11] close failed (%s)\n", nt_errstr(status));
4198 /* Now try open for delete access. */
4199 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4200 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4201 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4202 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4203 cli_close(cli1, fnum1);
4207 NTSTATUS nterr = cli_nt_error(cli1);
4208 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4209 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4213 printf("eleventh delete on close test succeeded.\n");
4217 printf("finished delete test\n");
4220 /* FIXME: This will crash if we aborted before cli2 got
4221 * intialized, because these functions don't handle
4222 * uninitialized connections. */
4224 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4225 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4226 cli_setatr(cli1, fname, 0, 0);
4227 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4229 if (cli1 && !torture_close_connection(cli1)) {
4232 if (cli2 && !torture_close_connection(cli2)) {
4238 static bool run_deletetest_ln(int dummy)
4240 struct cli_state *cli;
4241 const char *fname = "\\delete1";
4242 const char *fname_ln = "\\delete1_ln";
4246 bool correct = true;
4249 printf("starting deletetest-ln\n");
4251 if (!torture_open_connection(&cli, 0)) {
4255 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4256 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4258 cli_sockopt(cli, sockops);
4260 /* Create the file. */
4261 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4262 if (!NT_STATUS_IS_OK(status)) {
4263 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4267 status = cli_close(cli, fnum);
4268 if (!NT_STATUS_IS_OK(status)) {
4269 printf("close1 failed (%s)\n", nt_errstr(status));
4273 /* Now create a hardlink. */
4274 status = cli_nt_hardlink(cli, fname, fname_ln);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4280 /* Open the original file. */
4281 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4282 FILE_ATTRIBUTE_NORMAL,
4283 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4284 FILE_OPEN_IF, 0, 0, &fnum);
4285 if (!NT_STATUS_IS_OK(status)) {
4286 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4290 /* Unlink the hard link path. */
4291 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4292 FILE_ATTRIBUTE_NORMAL,
4293 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4294 FILE_OPEN_IF, 0, 0, &fnum1);
4295 if (!NT_STATUS_IS_OK(status)) {
4296 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4299 status = cli_nt_delete_on_close(cli, fnum1, true);
4300 if (!NT_STATUS_IS_OK(status)) {
4301 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4302 __location__, fname_ln, nt_errstr(status));
4306 status = cli_close(cli, fnum1);
4307 if (!NT_STATUS_IS_OK(status)) {
4308 printf("close %s failed (%s)\n",
4309 fname_ln, nt_errstr(status));
4313 status = cli_close(cli, fnum);
4314 if (!NT_STATUS_IS_OK(status)) {
4315 printf("close %s failed (%s)\n",
4316 fname, nt_errstr(status));
4320 /* Ensure the original file is still there. */
4321 status = cli_getatr(cli, fname, NULL, NULL, &t);
4322 if (!NT_STATUS_IS_OK(status)) {
4323 printf("%s getatr on file %s failed (%s)\n",
4330 /* Ensure the link path is gone. */
4331 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4332 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4333 printf("%s, getatr for file %s returned wrong error code %s "
4334 "- should have been deleted\n",
4336 fname_ln, nt_errstr(status));
4340 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4341 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4343 if (!torture_close_connection(cli)) {
4347 printf("finished deletetest-ln\n");
4353 print out server properties
4355 static bool run_properties(int dummy)
4357 struct cli_state *cli;
4358 bool correct = True;
4360 printf("starting properties test\n");
4364 if (!torture_open_connection(&cli, 0)) {
4368 cli_sockopt(cli, sockops);
4370 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4372 if (!torture_close_connection(cli)) {
4381 /* FIRST_DESIRED_ACCESS 0xf019f */
4382 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4383 FILE_READ_EA| /* 0xf */ \
4384 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4385 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4386 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4387 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4388 /* SECOND_DESIRED_ACCESS 0xe0080 */
4389 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4390 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4391 WRITE_OWNER_ACCESS /* 0xe0000 */
4394 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4395 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4397 WRITE_OWNER_ACCESS /* */
4401 Test ntcreate calls made by xcopy
4403 static bool run_xcopy(int dummy)
4405 static struct cli_state *cli1;
4406 const char *fname = "\\test.txt";
4407 bool correct = True;
4408 uint16_t fnum1, fnum2;
4411 printf("starting xcopy test\n");
4413 if (!torture_open_connection(&cli1, 0)) {
4417 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4418 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4419 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4420 if (!NT_STATUS_IS_OK(status)) {
4421 printf("First open failed - %s\n", nt_errstr(status));
4425 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4426 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4427 FILE_OPEN, 0x200000, 0, &fnum2);
4428 if (!NT_STATUS_IS_OK(status)) {
4429 printf("second open failed - %s\n", nt_errstr(status));
4433 if (!torture_close_connection(cli1)) {
4441 Test rename on files open with share delete and no share delete.
4443 static bool run_rename(int dummy)
4445 static struct cli_state *cli1;
4446 const char *fname = "\\test.txt";
4447 const char *fname1 = "\\test1.txt";
4448 bool correct = True;
4453 printf("starting rename test\n");
4455 if (!torture_open_connection(&cli1, 0)) {
4459 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4460 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4462 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4463 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4464 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4465 if (!NT_STATUS_IS_OK(status)) {
4466 printf("First open failed - %s\n", nt_errstr(status));
4470 status = cli_rename(cli1, fname, fname1);
4471 if (!NT_STATUS_IS_OK(status)) {
4472 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4474 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4478 status = cli_close(cli1, fnum1);
4479 if (!NT_STATUS_IS_OK(status)) {
4480 printf("close - 1 failed (%s)\n", nt_errstr(status));
4484 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4485 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4486 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4488 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4490 FILE_SHARE_DELETE|FILE_SHARE_READ,
4492 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4493 if (!NT_STATUS_IS_OK(status)) {
4494 printf("Second open failed - %s\n", nt_errstr(status));
4498 status = cli_rename(cli1, fname, fname1);
4499 if (!NT_STATUS_IS_OK(status)) {
4500 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4503 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4506 status = cli_close(cli1, fnum1);
4507 if (!NT_STATUS_IS_OK(status)) {
4508 printf("close - 2 failed (%s)\n", nt_errstr(status));
4512 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4513 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4515 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4516 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4517 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4518 if (!NT_STATUS_IS_OK(status)) {
4519 printf("Third open failed - %s\n", nt_errstr(status));
4528 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4529 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4530 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4533 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4534 printf("[8] setting delete_on_close on file failed !\n");
4538 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4539 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4545 status = cli_rename(cli1, fname, fname1);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4550 printf("Third rename succeeded (SHARE_NONE)\n");
4553 status = cli_close(cli1, fnum1);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("close - 3 failed (%s)\n", nt_errstr(status));
4559 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4560 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4564 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4565 FILE_ATTRIBUTE_NORMAL,
4566 FILE_SHARE_READ | FILE_SHARE_WRITE,
4567 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 printf("Fourth open failed - %s\n", nt_errstr(status));
4573 status = cli_rename(cli1, fname, fname1);
4574 if (!NT_STATUS_IS_OK(status)) {
4575 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4577 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4581 status = cli_close(cli1, fnum1);
4582 if (!NT_STATUS_IS_OK(status)) {
4583 printf("close - 4 failed (%s)\n", nt_errstr(status));
4587 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4588 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4592 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4593 FILE_ATTRIBUTE_NORMAL,
4594 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4595 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4596 if (!NT_STATUS_IS_OK(status)) {
4597 printf("Fifth open failed - %s\n", nt_errstr(status));
4601 status = cli_rename(cli1, fname, fname1);
4602 if (!NT_STATUS_IS_OK(status)) {
4603 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4606 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4610 * Now check if the first name still exists ...
4613 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4614 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4615 printf("Opening original file after rename of open file fails: %s\n",
4619 printf("Opening original file after rename of open file works ...\n");
4620 (void)cli_close(cli1, fnum2);
4624 status = cli_close(cli1, fnum1);
4625 if (!NT_STATUS_IS_OK(status)) {
4626 printf("close - 5 failed (%s)\n", nt_errstr(status));
4630 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4631 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4632 if (!NT_STATUS_IS_OK(status)) {
4633 printf("getatr on file %s failed - %s ! \n",
4634 fname1, nt_errstr(status));
4637 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4638 printf("Renamed file %s has wrong attr 0x%x "
4639 "(should be 0x%x)\n",
4642 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4645 printf("Renamed file %s has archive bit set\n", fname1);
4649 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4650 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4652 if (!torture_close_connection(cli1)) {
4659 static bool run_pipe_number(int dummy)
4661 struct cli_state *cli1;
4662 const char *pipe_name = "\\SPOOLSS";
4667 printf("starting pipenumber test\n");
4668 if (!torture_open_connection(&cli1, 0)) {
4672 cli_sockopt(cli1, sockops);
4674 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4675 FILE_ATTRIBUTE_NORMAL,
4676 FILE_SHARE_READ|FILE_SHARE_WRITE,
4677 FILE_OPEN_IF, 0, 0, &fnum);
4678 if (!NT_STATUS_IS_OK(status)) {
4679 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4683 printf("\r%6d", num_pipes);
4686 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4687 torture_close_connection(cli1);
4692 Test open mode returns on read-only files.
4694 static bool run_opentest(int dummy)
4696 static struct cli_state *cli1;
4697 static struct cli_state *cli2;
4698 const char *fname = "\\readonly.file";
4699 uint16_t fnum1, fnum2;
4702 bool correct = True;
4706 printf("starting open test\n");
4708 if (!torture_open_connection(&cli1, 0)) {
4712 cli_setatr(cli1, fname, 0, 0);
4713 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4715 cli_sockopt(cli1, sockops);
4717 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4718 if (!NT_STATUS_IS_OK(status)) {
4719 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4723 status = cli_close(cli1, fnum1);
4724 if (!NT_STATUS_IS_OK(status)) {
4725 printf("close2 failed (%s)\n", nt_errstr(status));
4729 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4730 if (!NT_STATUS_IS_OK(status)) {
4731 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4735 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4736 if (!NT_STATUS_IS_OK(status)) {
4737 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4741 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4742 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4744 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4745 NT_STATUS_ACCESS_DENIED)) {
4746 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4749 printf("finished open test 1\n");
4751 cli_close(cli1, fnum1);
4753 /* Now try not readonly and ensure ERRbadshare is returned. */
4755 cli_setatr(cli1, fname, 0, 0);
4757 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4758 if (!NT_STATUS_IS_OK(status)) {
4759 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4763 /* This will fail - but the error should be ERRshare. */
4764 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4766 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4767 NT_STATUS_SHARING_VIOLATION)) {
4768 printf("correct error code ERRDOS/ERRbadshare returned\n");
4771 status = cli_close(cli1, fnum1);
4772 if (!NT_STATUS_IS_OK(status)) {
4773 printf("close2 failed (%s)\n", nt_errstr(status));
4777 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4779 printf("finished open test 2\n");
4781 /* Test truncate open disposition on file opened for read. */
4782 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4783 if (!NT_STATUS_IS_OK(status)) {
4784 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4788 /* write 20 bytes. */
4790 memset(buf, '\0', 20);
4792 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4793 if (!NT_STATUS_IS_OK(status)) {
4794 printf("write failed (%s)\n", nt_errstr(status));
4798 status = cli_close(cli1, fnum1);
4799 if (!NT_STATUS_IS_OK(status)) {
4800 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4804 /* Ensure size == 20. */
4805 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4806 if (!NT_STATUS_IS_OK(status)) {
4807 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4812 printf("(3) file size != 20\n");
4816 /* Now test if we can truncate a file opened for readonly. */
4817 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4823 status = cli_close(cli1, fnum1);
4824 if (!NT_STATUS_IS_OK(status)) {
4825 printf("close2 failed (%s)\n", nt_errstr(status));
4829 /* Ensure size == 0. */
4830 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4831 if (!NT_STATUS_IS_OK(status)) {
4832 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4837 printf("(3) file size != 0\n");
4840 printf("finished open test 3\n");
4842 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4844 printf("Do ctemp tests\n");
4845 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 printf("ctemp failed (%s)\n", nt_errstr(status));
4851 printf("ctemp gave path %s\n", tmp_path);
4852 status = cli_close(cli1, fnum1);
4853 if (!NT_STATUS_IS_OK(status)) {
4854 printf("close of temp failed (%s)\n", nt_errstr(status));
4857 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4858 if (!NT_STATUS_IS_OK(status)) {
4859 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4862 /* Test the non-io opens... */
4864 if (!torture_open_connection(&cli2, 1)) {
4868 cli_setatr(cli2, fname, 0, 0);
4869 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4871 cli_sockopt(cli2, sockops);
4873 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4874 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4875 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4876 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4877 if (!NT_STATUS_IS_OK(status)) {
4878 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4882 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4883 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4884 FILE_OPEN_IF, 0, 0, &fnum2);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4890 status = cli_close(cli1, fnum1);
4891 if (!NT_STATUS_IS_OK(status)) {
4892 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4896 status = cli_close(cli2, fnum2);
4897 if (!NT_STATUS_IS_OK(status)) {
4898 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4902 printf("non-io open test #1 passed.\n");
4904 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4906 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4908 status = cli_ntcreate(cli1, fname, 0,
4909 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4910 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4911 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4912 if (!NT_STATUS_IS_OK(status)) {
4913 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4917 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4918 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4919 FILE_OPEN_IF, 0, 0, &fnum2);
4920 if (!NT_STATUS_IS_OK(status)) {
4921 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4925 status = cli_close(cli1, fnum1);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4931 status = cli_close(cli2, fnum2);
4932 if (!NT_STATUS_IS_OK(status)) {
4933 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4937 printf("non-io open test #2 passed.\n");
4939 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4941 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4943 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4944 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4945 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4946 if (!NT_STATUS_IS_OK(status)) {
4947 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4951 status = cli_ntcreate(cli2, fname, 0,
4952 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4953 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4954 FILE_OPEN_IF, 0, 0, &fnum2);
4955 if (!NT_STATUS_IS_OK(status)) {
4956 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4960 status = cli_close(cli1, fnum1);
4961 if (!NT_STATUS_IS_OK(status)) {
4962 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4966 status = cli_close(cli2, fnum2);
4967 if (!NT_STATUS_IS_OK(status)) {
4968 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4972 printf("non-io open test #3 passed.\n");
4974 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4976 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4978 status = cli_ntcreate(cli1, fname, 0,
4979 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4980 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4981 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4982 if (!NT_STATUS_IS_OK(status)) {
4983 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4987 status = cli_ntcreate(cli2, fname, 0,
4988 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4989 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4990 FILE_OPEN_IF, 0, 0, &fnum2);
4991 if (NT_STATUS_IS_OK(status)) {
4992 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4996 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4998 status = cli_close(cli1, fnum1);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5004 printf("non-io open test #4 passed.\n");
5006 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5008 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5010 status = cli_ntcreate(cli1, fname, 0,
5011 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5012 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5013 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5014 if (!NT_STATUS_IS_OK(status)) {
5015 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5019 status = cli_ntcreate(cli2, fname, 0,
5020 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5021 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5022 FILE_OPEN_IF, 0, 0, &fnum2);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5028 status = cli_close(cli1, fnum1);
5029 if (!NT_STATUS_IS_OK(status)) {
5030 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5034 status = cli_close(cli2, fnum2);
5035 if (!NT_STATUS_IS_OK(status)) {
5036 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5040 printf("non-io open test #5 passed.\n");
5042 printf("TEST #6 testing 1 non-io open, one io open\n");
5044 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5046 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5047 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5048 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5049 if (!NT_STATUS_IS_OK(status)) {
5050 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5054 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5055 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5056 FILE_OPEN_IF, 0, 0, &fnum2);
5057 if (!NT_STATUS_IS_OK(status)) {
5058 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5062 status = cli_close(cli1, fnum1);
5063 if (!NT_STATUS_IS_OK(status)) {
5064 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5068 status = cli_close(cli2, fnum2);
5069 if (!NT_STATUS_IS_OK(status)) {
5070 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5074 printf("non-io open test #6 passed.\n");
5076 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5078 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5080 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5081 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5082 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5083 if (!NT_STATUS_IS_OK(status)) {
5084 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5088 status = cli_ntcreate(cli2, fname, 0,
5089 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5090 FILE_ATTRIBUTE_NORMAL,
5091 FILE_SHARE_READ|FILE_SHARE_DELETE,
5092 FILE_OPEN_IF, 0, 0, &fnum2);
5093 if (NT_STATUS_IS_OK(status)) {
5094 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5098 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5100 status = cli_close(cli1, fnum1);
5101 if (!NT_STATUS_IS_OK(status)) {
5102 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5106 printf("non-io open test #7 passed.\n");
5108 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5110 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5111 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5112 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5113 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5114 if (!NT_STATUS_IS_OK(status)) {
5115 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5120 /* Write to ensure we have to update the file time. */
5121 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5123 if (!NT_STATUS_IS_OK(status)) {
5124 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5129 status = cli_close(cli1, fnum1);
5130 if (!NT_STATUS_IS_OK(status)) {
5131 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5137 if (!torture_close_connection(cli1)) {
5140 if (!torture_close_connection(cli2)) {
5147 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5149 uint16 major, minor;
5150 uint32 caplow, caphigh;
5153 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5154 printf("Server doesn't support UNIX CIFS extensions.\n");
5155 return NT_STATUS_NOT_SUPPORTED;
5158 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5160 if (!NT_STATUS_IS_OK(status)) {
5161 printf("Server didn't return UNIX CIFS extensions: %s\n",
5166 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5168 if (!NT_STATUS_IS_OK(status)) {
5169 printf("Server doesn't support setting UNIX CIFS extensions: "
5170 "%s.\n", nt_errstr(status));
5174 return NT_STATUS_OK;
5178 Test POSIX open /mkdir calls.
5180 static bool run_simple_posix_open_test(int dummy)
5182 static struct cli_state *cli1;
5183 const char *fname = "posix:file";
5184 const char *hname = "posix:hlink";
5185 const char *sname = "posix:symlink";
5186 const char *dname = "posix:dir";
5189 uint16_t fnum1 = (uint16_t)-1;
5190 SMB_STRUCT_STAT sbuf;
5191 bool correct = false;
5194 printf("Starting simple POSIX open test\n");
5196 if (!torture_open_connection(&cli1, 0)) {
5200 cli_sockopt(cli1, sockops);
5202 status = torture_setup_unix_extensions(cli1);
5203 if (!NT_STATUS_IS_OK(status)) {
5207 cli_setatr(cli1, fname, 0, 0);
5208 cli_posix_unlink(cli1, fname);
5209 cli_setatr(cli1, dname, 0, 0);
5210 cli_posix_rmdir(cli1, dname);
5211 cli_setatr(cli1, hname, 0, 0);
5212 cli_posix_unlink(cli1, hname);
5213 cli_setatr(cli1, sname, 0, 0);
5214 cli_posix_unlink(cli1, sname);
5216 /* Create a directory. */
5217 status = cli_posix_mkdir(cli1, dname, 0777);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5223 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5225 if (!NT_STATUS_IS_OK(status)) {
5226 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5230 /* Test ftruncate - set file size. */
5231 status = cli_ftruncate(cli1, fnum1, 1000);
5232 if (!NT_STATUS_IS_OK(status)) {
5233 printf("ftruncate failed (%s)\n", nt_errstr(status));
5237 /* Ensure st_size == 1000 */
5238 status = cli_posix_stat(cli1, fname, &sbuf);
5239 if (!NT_STATUS_IS_OK(status)) {
5240 printf("stat failed (%s)\n", nt_errstr(status));
5244 if (sbuf.st_ex_size != 1000) {
5245 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5249 /* Test ftruncate - set file size back to zero. */
5250 status = cli_ftruncate(cli1, fnum1, 0);
5251 if (!NT_STATUS_IS_OK(status)) {
5252 printf("ftruncate failed (%s)\n", nt_errstr(status));
5256 status = cli_close(cli1, fnum1);
5257 if (!NT_STATUS_IS_OK(status)) {
5258 printf("close failed (%s)\n", nt_errstr(status));
5262 /* Now open the file again for read only. */
5263 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5269 /* Now unlink while open. */
5270 status = cli_posix_unlink(cli1, fname);
5271 if (!NT_STATUS_IS_OK(status)) {
5272 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5276 status = cli_close(cli1, fnum1);
5277 if (!NT_STATUS_IS_OK(status)) {
5278 printf("close(2) failed (%s)\n", nt_errstr(status));
5282 /* Ensure the file has gone. */
5283 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5284 if (NT_STATUS_IS_OK(status)) {
5285 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5289 /* Create again to test open with O_TRUNC. */
5290 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5291 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5295 /* Test ftruncate - set file size. */
5296 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5297 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5301 /* Ensure st_size == 1000 */
5302 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5303 printf("stat failed (%s)\n", cli_errstr(cli1));
5307 if (sbuf.st_ex_size != 1000) {
5308 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5312 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5313 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5317 /* Re-open with O_TRUNC. */
5318 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5319 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5323 /* Ensure st_size == 0 */
5324 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5325 printf("stat failed (%s)\n", cli_errstr(cli1));
5329 if (sbuf.st_ex_size != 0) {
5330 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5334 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5335 printf("close failed (%s)\n", cli_errstr(cli1));
5339 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5340 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5344 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5345 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5346 dname, cli_errstr(cli1));
5350 cli_close(cli1, fnum1);
5352 /* What happens when we try and POSIX open a directory for write ? */
5353 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5354 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5357 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5358 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5363 /* Create the file. */
5364 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5366 if (!NT_STATUS_IS_OK(status)) {
5367 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5371 /* Write some data into it. */
5372 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5374 if (!NT_STATUS_IS_OK(status)) {
5375 printf("cli_write failed: %s\n", nt_errstr(status));
5379 cli_close(cli1, fnum1);
5381 /* Now create a hardlink. */
5382 status = cli_posix_hardlink(cli1, fname, hname);
5383 if (!NT_STATUS_IS_OK(status)) {
5384 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5388 /* Now create a symlink. */
5389 status = cli_posix_symlink(cli1, fname, sname);
5390 if (!NT_STATUS_IS_OK(status)) {
5391 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5395 /* Open the hardlink for read. */
5396 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5397 if (!NT_STATUS_IS_OK(status)) {
5398 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5402 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5403 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5407 if (memcmp(buf, "TEST DATA\n", 10)) {
5408 printf("invalid data read from hardlink\n");
5412 /* Do a POSIX lock/unlock. */
5413 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5414 if (!NT_STATUS_IS_OK(status)) {
5415 printf("POSIX lock failed %s\n", nt_errstr(status));
5419 /* Punch a hole in the locked area. */
5420 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5421 if (!NT_STATUS_IS_OK(status)) {
5422 printf("POSIX unlock failed %s\n", nt_errstr(status));
5426 cli_close(cli1, fnum1);
5428 /* Open the symlink for read - this should fail. A POSIX
5429 client should not be doing opens on a symlink. */
5430 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5431 if (NT_STATUS_IS_OK(status)) {
5432 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5435 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5436 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5437 printf("POSIX open of %s should have failed "
5438 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5439 "failed with %s instead.\n",
5440 sname, nt_errstr(status));
5445 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5446 if (!NT_STATUS_IS_OK(status)) {
5447 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5451 if (strcmp(namebuf, fname) != 0) {
5452 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5453 sname, fname, namebuf);
5457 status = cli_posix_rmdir(cli1, dname);
5458 if (!NT_STATUS_IS_OK(status)) {
5459 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5463 printf("Simple POSIX open test passed\n");
5468 if (fnum1 != (uint16_t)-1) {
5469 cli_close(cli1, fnum1);
5470 fnum1 = (uint16_t)-1;
5473 cli_setatr(cli1, sname, 0, 0);
5474 cli_posix_unlink(cli1, sname);
5475 cli_setatr(cli1, hname, 0, 0);
5476 cli_posix_unlink(cli1, hname);
5477 cli_setatr(cli1, fname, 0, 0);
5478 cli_posix_unlink(cli1, fname);
5479 cli_setatr(cli1, dname, 0, 0);
5480 cli_posix_rmdir(cli1, dname);
5482 if (!torture_close_connection(cli1)) {
5490 static uint32 open_attrs_table[] = {
5491 FILE_ATTRIBUTE_NORMAL,
5492 FILE_ATTRIBUTE_ARCHIVE,
5493 FILE_ATTRIBUTE_READONLY,
5494 FILE_ATTRIBUTE_HIDDEN,
5495 FILE_ATTRIBUTE_SYSTEM,
5497 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5498 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5499 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5500 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5501 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5502 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5504 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5505 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5506 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5507 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5510 struct trunc_open_results {
5517 static struct trunc_open_results attr_results[] = {
5518 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5519 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5520 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5521 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5522 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5523 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5524 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5525 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5526 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5527 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5528 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5529 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5530 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5531 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5532 { 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 },
5533 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5534 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5535 { 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 },
5536 { 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 },
5537 { 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 },
5538 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5539 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5540 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5541 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5542 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5543 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5546 static bool run_openattrtest(int dummy)
5548 static struct cli_state *cli1;
5549 const char *fname = "\\openattr.file";
5551 bool correct = True;
5553 unsigned int i, j, k, l;
5556 printf("starting open attr test\n");
5558 if (!torture_open_connection(&cli1, 0)) {
5562 cli_sockopt(cli1, sockops);
5564 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5565 cli_setatr(cli1, fname, 0, 0);
5566 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5568 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5569 open_attrs_table[i], FILE_SHARE_NONE,
5570 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5571 if (!NT_STATUS_IS_OK(status)) {
5572 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5576 status = cli_close(cli1, fnum1);
5577 if (!NT_STATUS_IS_OK(status)) {
5578 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5582 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5583 status = cli_ntcreate(cli1, fname, 0,
5584 FILE_READ_DATA|FILE_WRITE_DATA,
5585 open_attrs_table[j],
5586 FILE_SHARE_NONE, FILE_OVERWRITE,
5588 if (!NT_STATUS_IS_OK(status)) {
5589 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5590 if (attr_results[l].num == k) {
5591 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5592 k, open_attrs_table[i],
5593 open_attrs_table[j],
5594 fname, NT_STATUS_V(status), nt_errstr(status));
5599 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5600 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5601 k, open_attrs_table[i], open_attrs_table[j],
5606 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5612 status = cli_close(cli1, fnum1);
5613 if (!NT_STATUS_IS_OK(status)) {
5614 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5618 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5619 if (!NT_STATUS_IS_OK(status)) {
5620 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5625 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5626 k, open_attrs_table[i], open_attrs_table[j], attr );
5629 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5630 if (attr_results[l].num == k) {
5631 if (attr != attr_results[l].result_attr ||
5632 open_attrs_table[i] != attr_results[l].init_attr ||
5633 open_attrs_table[j] != attr_results[l].trunc_attr) {
5634 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5635 open_attrs_table[i],
5636 open_attrs_table[j],
5638 attr_results[l].result_attr);
5648 cli_setatr(cli1, fname, 0, 0);
5649 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5651 printf("open attr test %s.\n", correct ? "passed" : "failed");
5653 if (!torture_close_connection(cli1)) {
5659 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5660 const char *name, void *state)
5662 int *matched = (int *)state;
5663 if (matched != NULL) {
5666 return NT_STATUS_OK;
5670 test directory listing speed
5672 static bool run_dirtest(int dummy)
5675 static struct cli_state *cli;
5677 struct timeval core_start;
5678 bool correct = True;
5681 printf("starting directory test\n");
5683 if (!torture_open_connection(&cli, 0)) {
5687 cli_sockopt(cli, sockops);
5690 for (i=0;i<torture_numops;i++) {
5692 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5693 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5694 fprintf(stderr,"Failed to open %s\n", fname);
5697 cli_close(cli, fnum);
5700 core_start = timeval_current();
5703 cli_list(cli, "a*.*", 0, list_fn, &matched);
5704 printf("Matched %d\n", matched);
5707 cli_list(cli, "b*.*", 0, list_fn, &matched);
5708 printf("Matched %d\n", matched);
5711 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5712 printf("Matched %d\n", matched);
5714 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5717 for (i=0;i<torture_numops;i++) {
5719 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5720 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5723 if (!torture_close_connection(cli)) {
5727 printf("finished dirtest\n");
5732 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5735 struct cli_state *pcli = (struct cli_state *)state;
5737 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5739 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5740 return NT_STATUS_OK;
5742 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5743 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5744 printf("del_fn: failed to rmdir %s\n,", fname );
5746 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5747 printf("del_fn: failed to unlink %s\n,", fname );
5749 return NT_STATUS_OK;
5754 sees what IOCTLs are supported
5756 bool torture_ioctl_test(int dummy)
5758 static struct cli_state *cli;
5759 uint16_t device, function;
5761 const char *fname = "\\ioctl.dat";
5765 if (!torture_open_connection(&cli, 0)) {
5769 printf("starting ioctl test\n");
5771 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5773 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5779 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5780 printf("ioctl device info: %s\n", nt_errstr(status));
5782 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5783 printf("ioctl job info: %s\n", nt_errstr(status));
5785 for (device=0;device<0x100;device++) {
5786 printf("ioctl test with device = 0x%x\n", device);
5787 for (function=0;function<0x100;function++) {
5788 uint32 code = (device<<16) | function;
5790 status = cli_raw_ioctl(cli, fnum, code, &blob);
5792 if (NT_STATUS_IS_OK(status)) {
5793 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5795 data_blob_free(&blob);
5800 if (!torture_close_connection(cli)) {
5809 tries varients of chkpath
5811 bool torture_chkpath_test(int dummy)
5813 static struct cli_state *cli;
5818 if (!torture_open_connection(&cli, 0)) {
5822 printf("starting chkpath test\n");
5824 /* cleanup from an old run */
5825 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5826 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5827 cli_rmdir(cli, "\\chkpath.dir");
5829 status = cli_mkdir(cli, "\\chkpath.dir");
5830 if (!NT_STATUS_IS_OK(status)) {
5831 printf("mkdir1 failed : %s\n", nt_errstr(status));
5835 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5836 if (!NT_STATUS_IS_OK(status)) {
5837 printf("mkdir2 failed : %s\n", nt_errstr(status));
5841 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5843 if (!NT_STATUS_IS_OK(status)) {
5844 printf("open1 failed (%s)\n", nt_errstr(status));
5847 cli_close(cli, fnum);
5849 status = cli_chkpath(cli, "\\chkpath.dir");
5850 if (!NT_STATUS_IS_OK(status)) {
5851 printf("chkpath1 failed: %s\n", nt_errstr(status));
5855 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5856 if (!NT_STATUS_IS_OK(status)) {
5857 printf("chkpath2 failed: %s\n", nt_errstr(status));
5861 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5862 if (!NT_STATUS_IS_OK(status)) {
5863 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5864 NT_STATUS_NOT_A_DIRECTORY);
5866 printf("* chkpath on a file should fail\n");
5870 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5871 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5872 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5874 printf("* chkpath on a non existant file should fail\n");
5878 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5879 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5880 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5882 printf("* chkpath on a non existent component should fail\n");
5886 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5887 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5888 cli_rmdir(cli, "\\chkpath.dir");
5890 if (!torture_close_connection(cli)) {
5897 static bool run_eatest(int dummy)
5899 static struct cli_state *cli;
5900 const char *fname = "\\eatest.txt";
5901 bool correct = True;
5905 struct ea_struct *ea_list = NULL;
5906 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5909 printf("starting eatest\n");
5911 if (!torture_open_connection(&cli, 0)) {
5912 talloc_destroy(mem_ctx);
5916 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5918 status = cli_ntcreate(cli, fname, 0,
5919 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5920 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5922 if (!NT_STATUS_IS_OK(status)) {
5923 printf("open failed - %s\n", nt_errstr(status));
5924 talloc_destroy(mem_ctx);
5928 for (i = 0; i < 10; i++) {
5929 fstring ea_name, ea_val;
5931 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5932 memset(ea_val, (char)i+1, i+1);
5933 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5934 if (!NT_STATUS_IS_OK(status)) {
5935 printf("ea_set of name %s failed - %s\n", ea_name,
5937 talloc_destroy(mem_ctx);
5942 cli_close(cli, fnum);
5943 for (i = 0; i < 10; i++) {
5944 fstring ea_name, ea_val;
5946 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5947 memset(ea_val, (char)i+1, i+1);
5948 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5949 if (!NT_STATUS_IS_OK(status)) {
5950 printf("ea_set of name %s failed - %s\n", ea_name,
5952 talloc_destroy(mem_ctx);
5957 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5958 if (!NT_STATUS_IS_OK(status)) {
5959 printf("ea_get list failed - %s\n", nt_errstr(status));
5963 printf("num_eas = %d\n", (int)num_eas);
5965 if (num_eas != 20) {
5966 printf("Should be 20 EA's stored... failing.\n");
5970 for (i = 0; i < num_eas; i++) {
5971 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5972 dump_data(0, ea_list[i].value.data,
5973 ea_list[i].value.length);
5976 /* Setting EA's to zero length deletes them. Test this */
5977 printf("Now deleting all EA's - case indepenent....\n");
5980 cli_set_ea_path(cli, fname, "", "", 0);
5982 for (i = 0; i < 20; i++) {
5984 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5985 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5986 if (!NT_STATUS_IS_OK(status)) {
5987 printf("ea_set of name %s failed - %s\n", ea_name,
5989 talloc_destroy(mem_ctx);
5995 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5996 if (!NT_STATUS_IS_OK(status)) {
5997 printf("ea_get list failed - %s\n", nt_errstr(status));
6001 printf("num_eas = %d\n", (int)num_eas);
6002 for (i = 0; i < num_eas; i++) {
6003 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6004 dump_data(0, ea_list[i].value.data,
6005 ea_list[i].value.length);
6009 printf("deleting EA's failed.\n");
6013 /* Try and delete a non existant EA. */
6014 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6015 if (!NT_STATUS_IS_OK(status)) {
6016 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6021 talloc_destroy(mem_ctx);
6022 if (!torture_close_connection(cli)) {
6029 static bool run_dirtest1(int dummy)
6032 static struct cli_state *cli;
6035 bool correct = True;
6037 printf("starting directory test\n");
6039 if (!torture_open_connection(&cli, 0)) {
6043 cli_sockopt(cli, sockops);
6045 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6046 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6047 cli_rmdir(cli, "\\LISTDIR");
6048 cli_mkdir(cli, "\\LISTDIR");
6050 /* Create 1000 files and 1000 directories. */
6051 for (i=0;i<1000;i++) {
6053 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6054 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6055 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6056 fprintf(stderr,"Failed to open %s\n", fname);
6059 cli_close(cli, fnum);
6061 for (i=0;i<1000;i++) {
6063 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6064 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6065 fprintf(stderr,"Failed to open %s\n", fname);
6070 /* Now ensure that doing an old list sees both files and directories. */
6072 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6073 printf("num_seen = %d\n", num_seen );
6074 /* We should see 100 files + 1000 directories + . and .. */
6075 if (num_seen != 2002)
6078 /* Ensure if we have the "must have" bits we only see the
6082 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6083 printf("num_seen = %d\n", num_seen );
6084 if (num_seen != 1002)
6088 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6089 printf("num_seen = %d\n", num_seen );
6090 if (num_seen != 1000)
6093 /* Delete everything. */
6094 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6095 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6096 cli_rmdir(cli, "\\LISTDIR");
6099 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6100 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6101 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6104 if (!torture_close_connection(cli)) {
6108 printf("finished dirtest1\n");
6113 static bool run_error_map_extract(int dummy) {
6115 static struct cli_state *c_dos;
6116 static struct cli_state *c_nt;
6121 uint32 flgs2, errnum;
6128 /* NT-Error connection */
6130 if (!(c_nt = open_nbt_connection())) {
6134 c_nt->use_spnego = False;
6136 status = cli_negprot(c_nt);
6138 if (!NT_STATUS_IS_OK(status)) {
6139 printf("%s rejected the NT-error negprot (%s)\n", host,
6145 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6146 if (!NT_STATUS_IS_OK(status)) {
6147 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6151 /* DOS-Error connection */
6153 if (!(c_dos = open_nbt_connection())) {
6157 c_dos->use_spnego = False;
6158 c_dos->force_dos_errors = True;
6160 status = cli_negprot(c_dos);
6161 if (!NT_STATUS_IS_OK(status)) {
6162 printf("%s rejected the DOS-error negprot (%s)\n", host,
6164 cli_shutdown(c_dos);
6168 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6169 if (!NT_STATUS_IS_OK(status)) {
6170 printf("%s rejected the DOS-error initial session setup (%s)\n",
6171 host, nt_errstr(status));
6175 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6176 fstr_sprintf(user, "%X", error);
6178 status = cli_session_setup(c_nt, user,
6179 password, strlen(password),
6180 password, strlen(password),
6182 if (NT_STATUS_IS_OK(status)) {
6183 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6186 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6188 /* Case #1: 32-bit NT errors */
6189 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6190 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6192 printf("/** Dos error on NT connection! (%s) */\n",
6194 nt_status = NT_STATUS(0xc0000000);
6197 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6198 password, strlen(password),
6199 password, strlen(password),
6201 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6203 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6205 /* Case #1: 32-bit NT errors */
6206 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6207 printf("/** NT error on DOS connection! (%s) */\n",
6209 errnum = errclass = 0;
6211 cli_dos_error(c_dos, &errclass, &errnum);
6214 if (NT_STATUS_V(nt_status) != error) {
6215 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6216 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6217 get_nt_error_c_code(talloc_tos(), nt_status));
6220 printf("\t{%s,\t%s,\t%s},\n",
6221 smb_dos_err_class(errclass),
6222 smb_dos_err_name(errclass, errnum),
6223 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6228 static bool run_sesssetup_bench(int dummy)
6230 static struct cli_state *c;
6231 const char *fname = "\\file.dat";
6236 if (!torture_open_connection(&c, 0)) {
6240 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6241 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6242 FILE_DELETE_ON_CLOSE, 0, &fnum);
6243 if (!NT_STATUS_IS_OK(status)) {
6244 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6248 for (i=0; i<torture_numops; i++) {
6249 status = cli_session_setup(
6251 password, strlen(password),
6252 password, strlen(password),
6254 if (!NT_STATUS_IS_OK(status)) {
6255 d_printf("(%s) cli_session_setup failed: %s\n",
6256 __location__, nt_errstr(status));
6260 d_printf("\r%d ", (int)c->vuid);
6262 status = cli_ulogoff(c);
6263 if (!NT_STATUS_IS_OK(status)) {
6264 d_printf("(%s) cli_ulogoff failed: %s\n",
6265 __location__, nt_errstr(status));
6274 static bool subst_test(const char *str, const char *user, const char *domain,
6275 uid_t uid, gid_t gid, const char *expected)
6280 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6282 if (strcmp(subst, expected) != 0) {
6283 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6284 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6293 static void chain1_open_completion(struct tevent_req *req)
6297 status = cli_open_recv(req, &fnum);
6300 d_printf("cli_open_recv returned %s: %d\n",
6302 NT_STATUS_IS_OK(status) ? fnum : -1);
6305 static void chain1_write_completion(struct tevent_req *req)
6309 status = cli_write_andx_recv(req, &written);
6312 d_printf("cli_write_andx_recv returned %s: %d\n",
6314 NT_STATUS_IS_OK(status) ? (int)written : -1);
6317 static void chain1_close_completion(struct tevent_req *req)
6320 bool *done = (bool *)tevent_req_callback_data_void(req);
6322 status = cli_close_recv(req);
6327 d_printf("cli_close returned %s\n", nt_errstr(status));
6330 static bool run_chain1(int dummy)
6332 struct cli_state *cli1;
6333 struct event_context *evt = event_context_init(NULL);
6334 struct tevent_req *reqs[3], *smbreqs[3];
6336 const char *str = "foobar";
6339 printf("starting chain1 test\n");
6340 if (!torture_open_connection(&cli1, 0)) {
6344 cli_sockopt(cli1, sockops);
6346 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6347 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6348 if (reqs[0] == NULL) return false;
6349 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6352 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6353 (const uint8_t *)str, 0, strlen(str)+1,
6354 smbreqs, 1, &smbreqs[1]);
6355 if (reqs[1] == NULL) return false;
6356 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6358 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6359 if (reqs[2] == NULL) return false;
6360 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6362 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6363 if (!NT_STATUS_IS_OK(status)) {
6368 event_loop_once(evt);
6371 torture_close_connection(cli1);
6375 static void chain2_sesssetup_completion(struct tevent_req *req)
6378 status = cli_session_setup_guest_recv(req);
6379 d_printf("sesssetup returned %s\n", nt_errstr(status));
6382 static void chain2_tcon_completion(struct tevent_req *req)
6384 bool *done = (bool *)tevent_req_callback_data_void(req);
6386 status = cli_tcon_andx_recv(req);
6387 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6391 static bool run_chain2(int dummy)
6393 struct cli_state *cli1;
6394 struct event_context *evt = event_context_init(NULL);
6395 struct tevent_req *reqs[2], *smbreqs[2];
6399 printf("starting chain2 test\n");
6400 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6401 port_to_use, Undefined, 0);
6402 if (!NT_STATUS_IS_OK(status)) {
6406 cli_sockopt(cli1, sockops);
6408 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6410 if (reqs[0] == NULL) return false;
6411 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6413 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6414 "?????", NULL, 0, &smbreqs[1]);
6415 if (reqs[1] == NULL) return false;
6416 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6418 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6419 if (!NT_STATUS_IS_OK(status)) {
6424 event_loop_once(evt);
6427 torture_close_connection(cli1);
6432 struct torture_createdel_state {
6433 struct tevent_context *ev;
6434 struct cli_state *cli;
6437 static void torture_createdel_created(struct tevent_req *subreq);
6438 static void torture_createdel_closed(struct tevent_req *subreq);
6440 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6441 struct tevent_context *ev,
6442 struct cli_state *cli,
6445 struct tevent_req *req, *subreq;
6446 struct torture_createdel_state *state;
6448 req = tevent_req_create(mem_ctx, &state,
6449 struct torture_createdel_state);
6456 subreq = cli_ntcreate_send(
6457 state, ev, cli, name, 0,
6458 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6459 FILE_ATTRIBUTE_NORMAL,
6460 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6461 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6463 if (tevent_req_nomem(subreq, req)) {
6464 return tevent_req_post(req, ev);
6466 tevent_req_set_callback(subreq, torture_createdel_created, req);
6470 static void torture_createdel_created(struct tevent_req *subreq)
6472 struct tevent_req *req = tevent_req_callback_data(
6473 subreq, struct tevent_req);
6474 struct torture_createdel_state *state = tevent_req_data(
6475 req, struct torture_createdel_state);
6479 status = cli_ntcreate_recv(subreq, &fnum);
6480 TALLOC_FREE(subreq);
6481 if (!NT_STATUS_IS_OK(status)) {
6482 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6483 nt_errstr(status)));
6484 tevent_req_nterror(req, status);
6488 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6489 if (tevent_req_nomem(subreq, req)) {
6492 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6495 static void torture_createdel_closed(struct tevent_req *subreq)
6497 struct tevent_req *req = tevent_req_callback_data(
6498 subreq, struct tevent_req);
6501 status = cli_close_recv(subreq);
6502 if (!NT_STATUS_IS_OK(status)) {
6503 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6504 tevent_req_nterror(req, status);
6507 tevent_req_done(req);
6510 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6512 return tevent_req_simple_recv_ntstatus(req);
6515 struct torture_createdels_state {
6516 struct tevent_context *ev;
6517 struct cli_state *cli;
6518 const char *base_name;
6522 struct tevent_req **reqs;
6525 static void torture_createdels_done(struct tevent_req *subreq);
6527 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6528 struct tevent_context *ev,
6529 struct cli_state *cli,
6530 const char *base_name,
6534 struct tevent_req *req;
6535 struct torture_createdels_state *state;
6538 req = tevent_req_create(mem_ctx, &state,
6539 struct torture_createdels_state);
6545 state->base_name = talloc_strdup(state, base_name);
6546 if (tevent_req_nomem(state->base_name, req)) {
6547 return tevent_req_post(req, ev);
6549 state->num_files = MAX(num_parallel, num_files);
6551 state->received = 0;
6553 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6554 if (tevent_req_nomem(state->reqs, req)) {
6555 return tevent_req_post(req, ev);
6558 for (i=0; i<num_parallel; i++) {
6561 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6563 if (tevent_req_nomem(name, req)) {
6564 return tevent_req_post(req, ev);
6566 state->reqs[i] = torture_createdel_send(
6567 state->reqs, state->ev, state->cli, name);
6568 if (tevent_req_nomem(state->reqs[i], req)) {
6569 return tevent_req_post(req, ev);
6571 name = talloc_move(state->reqs[i], &name);
6572 tevent_req_set_callback(state->reqs[i],
6573 torture_createdels_done, req);
6579 static void torture_createdels_done(struct tevent_req *subreq)
6581 struct tevent_req *req = tevent_req_callback_data(
6582 subreq, struct tevent_req);
6583 struct torture_createdels_state *state = tevent_req_data(
6584 req, struct torture_createdels_state);
6585 size_t num_parallel = talloc_array_length(state->reqs);
6590 status = torture_createdel_recv(subreq);
6591 if (!NT_STATUS_IS_OK(status)){
6592 DEBUG(10, ("torture_createdel_recv returned %s\n",
6593 nt_errstr(status)));
6594 TALLOC_FREE(subreq);
6595 tevent_req_nterror(req, status);
6599 for (i=0; i<num_parallel; i++) {
6600 if (subreq == state->reqs[i]) {
6604 if (i == num_parallel) {
6605 DEBUG(10, ("received something we did not send\n"));
6606 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6609 TALLOC_FREE(state->reqs[i]);
6611 if (state->sent >= state->num_files) {
6612 tevent_req_done(req);
6616 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6618 if (tevent_req_nomem(name, req)) {
6621 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6623 if (tevent_req_nomem(state->reqs[i], req)) {
6626 name = talloc_move(state->reqs[i], &name);
6627 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6631 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6633 return tevent_req_simple_recv_ntstatus(req);
6636 struct swallow_notify_state {
6637 struct tevent_context *ev;
6638 struct cli_state *cli;
6640 uint32_t completion_filter;
6642 bool (*fn)(uint32_t action, const char *name, void *priv);
6646 static void swallow_notify_done(struct tevent_req *subreq);
6648 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6649 struct tevent_context *ev,
6650 struct cli_state *cli,
6652 uint32_t completion_filter,
6654 bool (*fn)(uint32_t action,
6659 struct tevent_req *req, *subreq;
6660 struct swallow_notify_state *state;
6662 req = tevent_req_create(mem_ctx, &state,
6663 struct swallow_notify_state);
6670 state->completion_filter = completion_filter;
6671 state->recursive = recursive;
6675 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6676 0xffff, state->completion_filter,
6678 if (tevent_req_nomem(subreq, req)) {
6679 return tevent_req_post(req, ev);
6681 tevent_req_set_callback(subreq, swallow_notify_done, req);
6685 static void swallow_notify_done(struct tevent_req *subreq)
6687 struct tevent_req *req = tevent_req_callback_data(
6688 subreq, struct tevent_req);
6689 struct swallow_notify_state *state = tevent_req_data(
6690 req, struct swallow_notify_state);
6692 uint32_t i, num_changes;
6693 struct notify_change *changes;
6695 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6696 TALLOC_FREE(subreq);
6697 if (!NT_STATUS_IS_OK(status)) {
6698 DEBUG(10, ("cli_notify_recv returned %s\n",
6699 nt_errstr(status)));
6700 tevent_req_nterror(req, status);
6704 for (i=0; i<num_changes; i++) {
6705 state->fn(changes[i].action, changes[i].name, state->priv);
6707 TALLOC_FREE(changes);
6709 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6710 0xffff, state->completion_filter,
6712 if (tevent_req_nomem(subreq, req)) {
6715 tevent_req_set_callback(subreq, swallow_notify_done, req);
6718 static bool print_notifies(uint32_t action, const char *name, void *priv)
6720 if (DEBUGLEVEL > 5) {
6721 d_printf("%d %s\n", (int)action, name);
6726 static void notify_bench_done(struct tevent_req *req)
6728 int *num_finished = (int *)tevent_req_callback_data_void(req);
6732 static bool run_notify_bench(int dummy)
6734 const char *dname = "\\notify-bench";
6735 struct tevent_context *ev;
6738 struct tevent_req *req1;
6739 struct tevent_req *req2 = NULL;
6740 int i, num_unc_names;
6741 int num_finished = 0;
6743 printf("starting notify-bench test\n");
6745 if (use_multishare_conn) {
6747 unc_list = file_lines_load(multishare_conn_fname,
6748 &num_unc_names, 0, NULL);
6749 if (!unc_list || num_unc_names <= 0) {
6750 d_printf("Failed to load unc names list from '%s'\n",
6751 multishare_conn_fname);
6754 TALLOC_FREE(unc_list);
6759 ev = tevent_context_init(talloc_tos());
6761 d_printf("tevent_context_init failed\n");
6765 for (i=0; i<num_unc_names; i++) {
6766 struct cli_state *cli;
6769 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6771 if (base_fname == NULL) {
6775 if (!torture_open_connection(&cli, i)) {
6779 status = cli_ntcreate(cli, dname, 0,
6780 MAXIMUM_ALLOWED_ACCESS,
6781 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6783 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6786 if (!NT_STATUS_IS_OK(status)) {
6787 d_printf("Could not create %s: %s\n", dname,
6792 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6793 FILE_NOTIFY_CHANGE_FILE_NAME |
6794 FILE_NOTIFY_CHANGE_DIR_NAME |
6795 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6796 FILE_NOTIFY_CHANGE_LAST_WRITE,
6797 false, print_notifies, NULL);
6799 d_printf("Could not create notify request\n");
6803 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6804 base_fname, 10, torture_numops);
6806 d_printf("Could not create createdels request\n");
6809 TALLOC_FREE(base_fname);
6811 tevent_req_set_callback(req2, notify_bench_done,
6815 while (num_finished < num_unc_names) {
6817 ret = tevent_loop_once(ev);
6819 d_printf("tevent_loop_once failed\n");
6824 if (!tevent_req_poll(req2, ev)) {
6825 d_printf("tevent_req_poll failed\n");
6828 status = torture_createdels_recv(req2);
6829 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6834 static bool run_mangle1(int dummy)
6836 struct cli_state *cli;
6837 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6841 time_t change_time, access_time, write_time;
6845 printf("starting mangle1 test\n");
6846 if (!torture_open_connection(&cli, 0)) {
6850 cli_sockopt(cli, sockops);
6852 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6853 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6855 if (!NT_STATUS_IS_OK(status)) {
6856 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6859 cli_close(cli, fnum);
6861 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6862 if (!NT_STATUS_IS_OK(status)) {
6863 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6867 d_printf("alt_name: %s\n", alt_name);
6869 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6870 if (!NT_STATUS_IS_OK(status)) {
6871 d_printf("cli_open(%s) failed: %s\n", alt_name,
6875 cli_close(cli, fnum);
6877 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6878 &write_time, &size, &mode);
6879 if (!NT_STATUS_IS_OK(status)) {
6880 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6888 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6890 size_t *to_pull = (size_t *)priv;
6891 size_t thistime = *to_pull;
6893 thistime = MIN(thistime, n);
6894 if (thistime == 0) {
6898 memset(buf, 0, thistime);
6899 *to_pull -= thistime;
6903 static bool run_windows_write(int dummy)
6905 struct cli_state *cli1;
6909 const char *fname = "\\writetest.txt";
6910 struct timeval start_time;
6915 printf("starting windows_write test\n");
6916 if (!torture_open_connection(&cli1, 0)) {
6920 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6921 if (!NT_STATUS_IS_OK(status)) {
6922 printf("open failed (%s)\n", nt_errstr(status));
6926 cli_sockopt(cli1, sockops);
6928 start_time = timeval_current();
6930 for (i=0; i<torture_numops; i++) {
6932 off_t start = i * torture_blocksize;
6933 size_t to_pull = torture_blocksize - 1;
6935 status = cli_writeall(cli1, fnum, 0, &c,
6936 start + torture_blocksize - 1, 1, NULL);
6937 if (!NT_STATUS_IS_OK(status)) {
6938 printf("cli_write failed: %s\n", nt_errstr(status));
6942 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6943 null_source, &to_pull);
6944 if (!NT_STATUS_IS_OK(status)) {
6945 printf("cli_push returned: %s\n", nt_errstr(status));
6950 seconds = timeval_elapsed(&start_time);
6951 kbytes = (double)torture_blocksize * torture_numops;
6954 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6955 (double)seconds, (int)(kbytes/seconds));
6959 cli_close(cli1, fnum);
6960 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6961 torture_close_connection(cli1);
6965 static bool run_cli_echo(int dummy)
6967 struct cli_state *cli;
6970 printf("starting cli_echo test\n");
6971 if (!torture_open_connection(&cli, 0)) {
6974 cli_sockopt(cli, sockops);
6976 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6978 d_printf("cli_echo returned %s\n", nt_errstr(status));
6980 torture_close_connection(cli);
6981 return NT_STATUS_IS_OK(status);
6984 static bool run_uid_regression_test(int dummy)
6986 static struct cli_state *cli;
6989 bool correct = True;
6992 printf("starting uid regression test\n");
6994 if (!torture_open_connection(&cli, 0)) {
6998 cli_sockopt(cli, sockops);
7000 /* Ok - now save then logoff our current user. */
7001 old_vuid = cli->vuid;
7003 status = cli_ulogoff(cli);
7004 if (!NT_STATUS_IS_OK(status)) {
7005 d_printf("(%s) cli_ulogoff failed: %s\n",
7006 __location__, nt_errstr(status));
7011 cli->vuid = old_vuid;
7013 /* Try an operation. */
7014 status = cli_mkdir(cli, "\\uid_reg_test");
7015 if (NT_STATUS_IS_OK(status)) {
7016 d_printf("(%s) cli_mkdir succeeded\n",
7021 /* Should be bad uid. */
7022 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7023 NT_STATUS_USER_SESSION_DELETED)) {
7029 old_cnum = cli->cnum;
7031 /* Now try a SMBtdis with the invald vuid set to zero. */
7034 /* This should succeed. */
7035 status = cli_tdis(cli);
7037 if (NT_STATUS_IS_OK(status)) {
7038 d_printf("First tdis with invalid vuid should succeed.\n");
7040 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7045 cli->vuid = old_vuid;
7046 cli->cnum = old_cnum;
7048 /* This should fail. */
7049 status = cli_tdis(cli);
7050 if (NT_STATUS_IS_OK(status)) {
7051 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7055 /* Should be bad tid. */
7056 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7057 NT_STATUS_NETWORK_NAME_DELETED)) {
7063 cli_rmdir(cli, "\\uid_reg_test");
7072 static const char *illegal_chars = "*\\/?<>|\":";
7073 static char force_shortname_chars[] = " +,.[];=\177";
7075 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7076 const char *mask, void *state)
7078 struct cli_state *pcli = (struct cli_state *)state;
7080 NTSTATUS status = NT_STATUS_OK;
7082 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7084 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7085 return NT_STATUS_OK;
7087 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7088 status = cli_rmdir(pcli, fname);
7089 if (!NT_STATUS_IS_OK(status)) {
7090 printf("del_fn: failed to rmdir %s\n,", fname );
7093 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7094 if (!NT_STATUS_IS_OK(status)) {
7095 printf("del_fn: failed to unlink %s\n,", fname );
7107 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7108 const char *name, void *state)
7110 struct sn_state *s = (struct sn_state *)state;
7114 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7115 i, finfo->name, finfo->short_name);
7118 if (strchr(force_shortname_chars, i)) {
7119 if (!finfo->short_name[0]) {
7120 /* Shortname not created when it should be. */
7121 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7122 __location__, finfo->name, i);
7125 } else if (finfo->short_name[0]){
7126 /* Shortname created when it should not be. */
7127 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7128 __location__, finfo->short_name, finfo->name);
7132 return NT_STATUS_OK;
7135 static bool run_shortname_test(int dummy)
7137 static struct cli_state *cli;
7138 bool correct = True;
7144 printf("starting shortname test\n");
7146 if (!torture_open_connection(&cli, 0)) {
7150 cli_sockopt(cli, sockops);
7152 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7153 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7154 cli_rmdir(cli, "\\shortname");
7156 status = cli_mkdir(cli, "\\shortname");
7157 if (!NT_STATUS_IS_OK(status)) {
7158 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7159 __location__, nt_errstr(status));
7164 strlcpy(fname, "\\shortname\\", sizeof(fname));
7165 strlcat(fname, "test .txt", sizeof(fname));
7169 for (i = 32; i < 128; i++) {
7170 uint16_t fnum = (uint16_t)-1;
7174 if (strchr(illegal_chars, i)) {
7179 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7180 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7181 if (!NT_STATUS_IS_OK(status)) {
7182 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7183 __location__, fname, nt_errstr(status));
7187 cli_close(cli, fnum);
7190 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7192 if (s.matched != 1) {
7193 d_printf("(%s) failed to list %s: %s\n",
7194 __location__, fname, cli_errstr(cli));
7199 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7200 if (!NT_STATUS_IS_OK(status)) {
7201 d_printf("(%s) failed to delete %s: %s\n",
7202 __location__, fname, nt_errstr(status));
7215 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7216 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7217 cli_rmdir(cli, "\\shortname");
7218 torture_close_connection(cli);
7222 static void pagedsearch_cb(struct tevent_req *req)
7225 struct tldap_message *msg;
7228 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7229 if (rc != TLDAP_SUCCESS) {
7230 d_printf("tldap_search_paged_recv failed: %s\n",
7231 tldap_err2string(rc));
7234 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7238 if (!tldap_entry_dn(msg, &dn)) {
7239 d_printf("tldap_entry_dn failed\n");
7242 d_printf("%s\n", dn);
7246 static bool run_tldap(int dummy)
7248 struct tldap_context *ld;
7251 struct sockaddr_storage addr;
7252 struct tevent_context *ev;
7253 struct tevent_req *req;
7257 if (!resolve_name(host, &addr, 0, false)) {
7258 d_printf("could not find host %s\n", host);
7261 status = open_socket_out(&addr, 389, 9999, &fd);
7262 if (!NT_STATUS_IS_OK(status)) {
7263 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7267 ld = tldap_context_create(talloc_tos(), fd);
7270 d_printf("tldap_context_create failed\n");
7274 rc = tldap_fetch_rootdse(ld);
7275 if (rc != TLDAP_SUCCESS) {
7276 d_printf("tldap_fetch_rootdse failed: %s\n",
7277 tldap_errstr(talloc_tos(), ld, rc));
7281 basedn = tldap_talloc_single_attribute(
7282 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7283 if (basedn == NULL) {
7284 d_printf("no defaultNamingContext\n");
7287 d_printf("defaultNamingContext: %s\n", basedn);
7289 ev = tevent_context_init(talloc_tos());
7291 d_printf("tevent_context_init failed\n");
7295 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7296 TLDAP_SCOPE_SUB, "(objectclass=*)",
7298 NULL, 0, NULL, 0, 0, 0, 0, 5);
7300 d_printf("tldap_search_paged_send failed\n");
7303 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7305 tevent_req_poll(req, ev);
7309 /* test search filters against rootDSE */
7310 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7311 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7313 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7314 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7315 talloc_tos(), NULL, NULL);
7316 if (rc != TLDAP_SUCCESS) {
7317 d_printf("tldap_search with complex filter failed: %s\n",
7318 tldap_errstr(talloc_tos(), ld, rc));
7326 /* Torture test to ensure no regression of :
7327 https://bugzilla.samba.org/show_bug.cgi?id=7084
7330 static bool run_dir_createtime(int dummy)
7332 struct cli_state *cli;
7333 const char *dname = "\\testdir";
7334 const char *fname = "\\testdir\\testfile";
7336 struct timespec create_time;
7337 struct timespec create_time1;
7341 if (!torture_open_connection(&cli, 0)) {
7345 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7346 cli_rmdir(cli, dname);
7348 status = cli_mkdir(cli, dname);
7349 if (!NT_STATUS_IS_OK(status)) {
7350 printf("mkdir failed: %s\n", nt_errstr(status));
7354 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7356 if (!NT_STATUS_IS_OK(status)) {
7357 printf("cli_qpathinfo2 returned %s\n",
7362 /* Sleep 3 seconds, then create a file. */
7365 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7367 if (!NT_STATUS_IS_OK(status)) {
7368 printf("cli_open failed: %s\n", nt_errstr(status));
7372 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7374 if (!NT_STATUS_IS_OK(status)) {
7375 printf("cli_qpathinfo2 (2) returned %s\n",
7380 if (timespec_compare(&create_time1, &create_time)) {
7381 printf("run_dir_createtime: create time was updated (error)\n");
7383 printf("run_dir_createtime: create time was not updated (correct)\n");
7389 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7390 cli_rmdir(cli, dname);
7391 if (!torture_close_connection(cli)) {
7398 static bool run_streamerror(int dummy)
7400 struct cli_state *cli;
7401 const char *dname = "\\testdir";
7402 const char *streamname =
7403 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7405 time_t change_time, access_time, write_time;
7407 uint16_t mode, fnum;
7410 if (!torture_open_connection(&cli, 0)) {
7414 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7415 cli_rmdir(cli, dname);
7417 status = cli_mkdir(cli, dname);
7418 if (!NT_STATUS_IS_OK(status)) {
7419 printf("mkdir failed: %s\n", nt_errstr(status));
7423 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7425 status = cli_nt_error(cli);
7427 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7428 printf("pathinfo returned %s, expected "
7429 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7434 status = cli_ntcreate(cli, streamname, 0x16,
7435 FILE_READ_DATA|FILE_READ_EA|
7436 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7437 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7438 FILE_OPEN, 0, 0, &fnum);
7440 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7441 printf("ntcreate returned %s, expected "
7442 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7448 cli_rmdir(cli, dname);
7452 static bool run_local_substitute(int dummy)
7456 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7457 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7458 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7459 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7460 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7461 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7462 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7463 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7465 /* Different captialization rules in sub_basic... */
7467 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7473 static bool run_local_base64(int dummy)
7478 for (i=1; i<2000; i++) {
7479 DATA_BLOB blob1, blob2;
7482 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7484 generate_random_buffer(blob1.data, blob1.length);
7486 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7488 d_fprintf(stderr, "base64_encode_data_blob failed "
7489 "for %d bytes\n", i);
7492 blob2 = base64_decode_data_blob(b64);
7495 if (data_blob_cmp(&blob1, &blob2)) {
7496 d_fprintf(stderr, "data_blob_cmp failed for %d "
7500 TALLOC_FREE(blob1.data);
7501 data_blob_free(&blob2);
7506 static bool run_local_gencache(int dummy)
7512 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7513 d_printf("%s: gencache_set() failed\n", __location__);
7517 if (!gencache_get("foo", NULL, NULL)) {
7518 d_printf("%s: gencache_get() failed\n", __location__);
7522 if (!gencache_get("foo", &val, &tm)) {
7523 d_printf("%s: gencache_get() failed\n", __location__);
7527 if (strcmp(val, "bar") != 0) {
7528 d_printf("%s: gencache_get() returned %s, expected %s\n",
7529 __location__, val, "bar");
7536 if (!gencache_del("foo")) {
7537 d_printf("%s: gencache_del() failed\n", __location__);
7540 if (gencache_del("foo")) {
7541 d_printf("%s: second gencache_del() succeeded\n",
7546 if (gencache_get("foo", &val, &tm)) {
7547 d_printf("%s: gencache_get() on deleted entry "
7548 "succeeded\n", __location__);
7552 blob = data_blob_string_const_null("bar");
7553 tm = time(NULL) + 60;
7555 if (!gencache_set_data_blob("foo", &blob, tm)) {
7556 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7560 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7561 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7565 if (strcmp((const char *)blob.data, "bar") != 0) {
7566 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7567 __location__, (const char *)blob.data, "bar");
7568 data_blob_free(&blob);
7572 data_blob_free(&blob);
7574 if (!gencache_del("foo")) {
7575 d_printf("%s: gencache_del() failed\n", __location__);
7578 if (gencache_del("foo")) {
7579 d_printf("%s: second gencache_del() succeeded\n",
7584 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7585 d_printf("%s: gencache_get_data_blob() on deleted entry "
7586 "succeeded\n", __location__);
7593 static bool rbt_testval(struct db_context *db, const char *key,
7596 struct db_record *rec;
7597 TDB_DATA data = string_tdb_data(value);
7601 rec = db->fetch_locked(db, db, string_tdb_data(key));
7603 d_fprintf(stderr, "fetch_locked failed\n");
7606 status = rec->store(rec, data, 0);
7607 if (!NT_STATUS_IS_OK(status)) {
7608 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7613 rec = db->fetch_locked(db, db, string_tdb_data(key));
7615 d_fprintf(stderr, "second fetch_locked failed\n");
7618 if ((rec->value.dsize != data.dsize)
7619 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7620 d_fprintf(stderr, "Got wrong data back\n");
7630 static bool run_local_rbtree(int dummy)
7632 struct db_context *db;
7636 db = db_open_rbt(NULL);
7639 d_fprintf(stderr, "db_open_rbt failed\n");
7643 for (i=0; i<1000; i++) {
7646 if (asprintf(&key, "key%ld", random()) == -1) {
7649 if (asprintf(&value, "value%ld", random()) == -1) {
7654 if (!rbt_testval(db, key, value)) {
7661 if (asprintf(&value, "value%ld", random()) == -1) {
7666 if (!rbt_testval(db, key, value)) {
7685 local test for character set functions
7687 This is a very simple test for the functionality in convert_string_error()
7689 static bool run_local_convert_string(int dummy)
7691 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7692 const char *test_strings[2] = { "March", "M\303\244rz" };
7696 for (i=0; i<2; i++) {
7697 const char *str = test_strings[i];
7698 int len = strlen(str);
7699 size_t converted_size;
7702 memset(dst, 'X', sizeof(dst));
7704 /* first try with real source length */
7705 ret = convert_string_error(CH_UNIX, CH_UTF8,
7710 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7714 if (converted_size != len) {
7715 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7716 str, len, (int)converted_size);
7720 if (strncmp(str, dst, converted_size) != 0) {
7721 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7725 if (strlen(str) != converted_size) {
7726 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7727 (int)strlen(str), (int)converted_size);
7731 if (dst[converted_size] != 'X') {
7732 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7736 /* now with srclen==-1, this causes the nul to be
7738 ret = convert_string_error(CH_UNIX, CH_UTF8,
7743 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7747 if (converted_size != len+1) {
7748 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7749 str, len, (int)converted_size);
7753 if (strncmp(str, dst, converted_size) != 0) {
7754 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7758 if (len+1 != converted_size) {
7759 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7760 len+1, (int)converted_size);
7764 if (dst[converted_size] != 'X') {
7765 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7772 TALLOC_FREE(tmp_ctx);
7775 TALLOC_FREE(tmp_ctx);
7780 struct talloc_dict_test {
7784 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7786 int *count = (int *)priv;
7791 static bool run_local_talloc_dict(int dummy)
7793 struct talloc_dict *dict;
7794 struct talloc_dict_test *t;
7797 dict = talloc_dict_init(talloc_tos());
7802 t = talloc(talloc_tos(), struct talloc_dict_test);
7809 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7814 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7827 static bool run_local_string_to_sid(int dummy) {
7830 if (string_to_sid(&sid, "S--1-5-32-545")) {
7831 printf("allowing S--1-5-32-545\n");
7834 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7835 printf("allowing S-1-5-32-+545\n");
7838 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")) {
7839 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7842 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7843 printf("allowing S-1-5-32-545-abc\n");
7846 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7847 printf("could not parse S-1-5-32-545\n");
7850 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7851 printf("mis-parsed S-1-5-32-545 as %s\n",
7852 sid_string_tos(&sid));
7858 static bool run_local_binary_to_sid(int dummy) {
7859 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7860 static const char good_binary_sid[] = {
7861 0x1, /* revision number */
7863 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7864 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7865 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7866 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7867 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7868 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7869 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7870 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7871 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7872 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7873 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7874 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7881 static const char long_binary_sid[] = {
7882 0x1, /* revision number */
7884 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7885 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7886 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7890 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7891 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7892 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7893 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7894 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7895 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7896 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7902 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7905 static const char long_binary_sid2[] = {
7906 0x1, /* revision number */
7908 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7909 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7910 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7914 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7915 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7916 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7917 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7918 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7919 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7920 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7928 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7929 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7930 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7931 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7932 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7933 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7934 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7935 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7936 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7937 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7938 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7939 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7940 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7943 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7946 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7949 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7955 /* Split a path name into filename and stream name components. Canonicalise
7956 * such that an implicit $DATA token is always explicit.
7958 * The "specification" of this function can be found in the
7959 * run_local_stream_name() function in torture.c, I've tried those
7960 * combinations against a W2k3 server.
7963 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7964 char **pbase, char **pstream)
7967 char *stream = NULL;
7968 char *sname; /* stream name */
7969 const char *stype; /* stream type */
7971 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7973 sname = strchr_m(fname, ':');
7975 if (lp_posix_pathnames() || (sname == NULL)) {
7976 if (pbase != NULL) {
7977 base = talloc_strdup(mem_ctx, fname);
7978 NT_STATUS_HAVE_NO_MEMORY(base);
7983 if (pbase != NULL) {
7984 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7985 NT_STATUS_HAVE_NO_MEMORY(base);
7990 stype = strchr_m(sname, ':');
7992 if (stype == NULL) {
7993 sname = talloc_strdup(mem_ctx, sname);
7997 if (strcasecmp_m(stype, ":$DATA") != 0) {
7999 * If there is an explicit stream type, so far we only
8000 * allow $DATA. Is there anything else allowed? -- vl
8002 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8004 return NT_STATUS_OBJECT_NAME_INVALID;
8006 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8010 if (sname == NULL) {
8012 return NT_STATUS_NO_MEMORY;
8015 if (sname[0] == '\0') {
8017 * no stream name, so no stream
8022 if (pstream != NULL) {
8023 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8024 if (stream == NULL) {
8027 return NT_STATUS_NO_MEMORY;
8030 * upper-case the type field
8032 strupper_m(strchr_m(stream, ':')+1);
8036 if (pbase != NULL) {
8039 if (pstream != NULL) {
8042 return NT_STATUS_OK;
8045 static bool test_stream_name(const char *fname, const char *expected_base,
8046 const char *expected_stream,
8047 NTSTATUS expected_status)
8051 char *stream = NULL;
8053 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8054 if (!NT_STATUS_EQUAL(status, expected_status)) {
8058 if (!NT_STATUS_IS_OK(status)) {
8062 if (base == NULL) goto error;
8064 if (strcmp(expected_base, base) != 0) goto error;
8066 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8067 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8069 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8073 TALLOC_FREE(stream);
8077 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8078 fname, expected_base ? expected_base : "<NULL>",
8079 expected_stream ? expected_stream : "<NULL>",
8080 nt_errstr(expected_status));
8081 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8082 base ? base : "<NULL>", stream ? stream : "<NULL>",
8085 TALLOC_FREE(stream);
8089 static bool run_local_stream_name(int dummy)
8093 ret &= test_stream_name(
8094 "bla", "bla", NULL, NT_STATUS_OK);
8095 ret &= test_stream_name(
8096 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8097 ret &= test_stream_name(
8098 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8099 ret &= test_stream_name(
8100 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8101 ret &= test_stream_name(
8102 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8103 ret &= test_stream_name(
8104 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8105 ret &= test_stream_name(
8106 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8107 ret &= test_stream_name(
8108 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8113 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8115 if (a.length != b.length) {
8116 printf("a.length=%d != b.length=%d\n",
8117 (int)a.length, (int)b.length);
8120 if (memcmp(a.data, b.data, a.length) != 0) {
8121 printf("a.data and b.data differ\n");
8127 static bool run_local_memcache(int dummy)
8129 struct memcache *cache;
8131 DATA_BLOB d1, d2, d3;
8132 DATA_BLOB v1, v2, v3;
8134 TALLOC_CTX *mem_ctx;
8136 size_t size1, size2;
8139 cache = memcache_init(NULL, 100);
8141 if (cache == NULL) {
8142 printf("memcache_init failed\n");
8146 d1 = data_blob_const("d1", 2);
8147 d2 = data_blob_const("d2", 2);
8148 d3 = data_blob_const("d3", 2);
8150 k1 = data_blob_const("d1", 2);
8151 k2 = data_blob_const("d2", 2);
8153 memcache_add(cache, STAT_CACHE, k1, d1);
8154 memcache_add(cache, GETWD_CACHE, k2, d2);
8156 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8157 printf("could not find k1\n");
8160 if (!data_blob_equal(d1, v1)) {
8164 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8165 printf("could not find k2\n");
8168 if (!data_blob_equal(d2, v2)) {
8172 memcache_add(cache, STAT_CACHE, k1, d3);
8174 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8175 printf("could not find replaced k1\n");
8178 if (!data_blob_equal(d3, v3)) {
8182 memcache_add(cache, GETWD_CACHE, k1, d1);
8184 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8185 printf("Did find k2, should have been purged\n");
8191 cache = memcache_init(NULL, 0);
8193 mem_ctx = talloc_init("foo");
8195 str1 = talloc_strdup(mem_ctx, "string1");
8196 str2 = talloc_strdup(mem_ctx, "string2");
8198 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8199 data_blob_string_const("torture"), &str1);
8200 size1 = talloc_total_size(cache);
8202 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8203 data_blob_string_const("torture"), &str2);
8204 size2 = talloc_total_size(cache);
8206 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8208 if (size2 > size1) {
8209 printf("memcache leaks memory!\n");
8219 static void wbclient_done(struct tevent_req *req)
8222 struct winbindd_response *wb_resp;
8223 int *i = (int *)tevent_req_callback_data_void(req);
8225 wbc_err = wb_trans_recv(req, req, &wb_resp);
8228 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8231 static bool run_local_wbclient(int dummy)
8233 struct event_context *ev;
8234 struct wb_context **wb_ctx;
8235 struct winbindd_request wb_req;
8236 bool result = false;
8239 BlockSignals(True, SIGPIPE);
8241 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8246 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
8247 if (wb_ctx == NULL) {
8251 ZERO_STRUCT(wb_req);
8252 wb_req.cmd = WINBINDD_PING;
8254 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8256 for (i=0; i<nprocs; i++) {
8257 wb_ctx[i] = wb_context_init(ev, NULL);
8258 if (wb_ctx[i] == NULL) {
8261 for (j=0; j<torture_numops; j++) {
8262 struct tevent_req *req;
8263 req = wb_trans_send(ev, ev, wb_ctx[i],
8264 (j % 2) == 0, &wb_req);
8268 tevent_req_set_callback(req, wbclient_done, &i);
8274 while (i < nprocs * torture_numops) {
8275 event_loop_once(ev);
8284 static void getaddrinfo_finished(struct tevent_req *req)
8286 char *name = (char *)tevent_req_callback_data_void(req);
8287 struct addrinfo *ainfo;
8290 res = getaddrinfo_recv(req, &ainfo);
8292 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8295 d_printf("gai(%s) succeeded\n", name);
8296 freeaddrinfo(ainfo);
8299 static bool run_getaddrinfo_send(int dummy)
8301 TALLOC_CTX *frame = talloc_stackframe();
8302 struct fncall_context *ctx;
8303 struct tevent_context *ev;
8304 bool result = false;
8305 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8306 "www.slashdot.org", "heise.de" };
8307 struct tevent_req *reqs[4];
8310 ev = event_context_init(frame);
8315 ctx = fncall_context_init(frame, 4);
8317 for (i=0; i<ARRAY_SIZE(names); i++) {
8318 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8320 if (reqs[i] == NULL) {
8323 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8324 discard_const_p(void, names[i]));
8327 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8328 tevent_loop_once(ev);
8337 static bool dbtrans_inc(struct db_context *db)
8339 struct db_record *rec;
8344 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8346 printf(__location__ "fetch_lock failed\n");
8350 if (rec->value.dsize != sizeof(uint32_t)) {
8351 printf(__location__ "value.dsize = %d\n",
8352 (int)rec->value.dsize);
8356 val = (uint32_t *)rec->value.dptr;
8359 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8362 if (!NT_STATUS_IS_OK(status)) {
8363 printf(__location__ "store failed: %s\n",
8374 static bool run_local_dbtrans(int dummy)
8376 struct db_context *db;
8377 struct db_record *rec;
8382 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8383 O_RDWR|O_CREAT, 0600);
8385 printf("Could not open transtest.db\n");
8389 res = db->transaction_start(db);
8391 printf(__location__ "transaction_start failed\n");
8395 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8397 printf(__location__ "fetch_lock failed\n");
8401 if (rec->value.dptr == NULL) {
8403 status = rec->store(
8404 rec, make_tdb_data((uint8_t *)&initial,
8407 if (!NT_STATUS_IS_OK(status)) {
8408 printf(__location__ "store returned %s\n",
8416 res = db->transaction_commit(db);
8418 printf(__location__ "transaction_commit failed\n");
8426 res = db->transaction_start(db);
8428 printf(__location__ "transaction_start failed\n");
8432 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8433 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8437 for (i=0; i<10; i++) {
8438 if (!dbtrans_inc(db)) {
8443 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8444 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8448 if (val2 != val + 10) {
8449 printf(__location__ "val=%d, val2=%d\n",
8450 (int)val, (int)val2);
8454 printf("val2=%d\r", val2);
8456 res = db->transaction_commit(db);
8458 printf(__location__ "transaction_commit failed\n");
8468 * Just a dummy test to be run under a debugger. There's no real way
8469 * to inspect the tevent_select specific function from outside of
8473 static bool run_local_tevent_select(int dummy)
8475 struct tevent_context *ev;
8476 struct tevent_fd *fd1, *fd2;
8477 bool result = false;
8479 ev = tevent_context_init_byname(NULL, "select");
8481 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8485 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8487 d_fprintf(stderr, "tevent_add_fd failed\n");
8490 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8492 d_fprintf(stderr, "tevent_add_fd failed\n");
8497 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8499 d_fprintf(stderr, "tevent_add_fd failed\n");
8509 static double create_procs(bool (*fn)(int), bool *result)
8512 volatile pid_t *child_status;
8513 volatile bool *child_status_out;
8516 struct timeval start;
8520 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8521 if (!child_status) {
8522 printf("Failed to setup shared memory\n");
8526 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8527 if (!child_status_out) {
8528 printf("Failed to setup result status shared memory\n");
8532 for (i = 0; i < nprocs; i++) {
8533 child_status[i] = 0;
8534 child_status_out[i] = True;
8537 start = timeval_current();
8539 for (i=0;i<nprocs;i++) {
8542 pid_t mypid = getpid();
8543 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8545 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8548 if (torture_open_connection(¤t_cli, i)) break;
8550 printf("pid %d failed to start\n", (int)getpid());
8556 child_status[i] = getpid();
8558 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8560 child_status_out[i] = fn(i);
8567 for (i=0;i<nprocs;i++) {
8568 if (child_status[i]) synccount++;
8570 if (synccount == nprocs) break;
8572 } while (timeval_elapsed(&start) < 30);
8574 if (synccount != nprocs) {
8575 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8577 return timeval_elapsed(&start);
8580 /* start the client load */
8581 start = timeval_current();
8583 for (i=0;i<nprocs;i++) {
8584 child_status[i] = 0;
8587 printf("%d clients started\n", nprocs);
8589 for (i=0;i<nprocs;i++) {
8590 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8595 for (i=0;i<nprocs;i++) {
8596 if (!child_status_out[i]) {
8600 return timeval_elapsed(&start);
8603 #define FLAG_MULTIPROC 1
8610 {"FDPASS", run_fdpasstest, 0},
8611 {"LOCK1", run_locktest1, 0},
8612 {"LOCK2", run_locktest2, 0},
8613 {"LOCK3", run_locktest3, 0},
8614 {"LOCK4", run_locktest4, 0},
8615 {"LOCK5", run_locktest5, 0},
8616 {"LOCK6", run_locktest6, 0},
8617 {"LOCK7", run_locktest7, 0},
8618 {"LOCK8", run_locktest8, 0},
8619 {"LOCK9", run_locktest9, 0},
8620 {"UNLINK", run_unlinktest, 0},
8621 {"BROWSE", run_browsetest, 0},
8622 {"ATTR", run_attrtest, 0},
8623 {"TRANS2", run_trans2test, 0},
8624 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8625 {"TORTURE",run_torture, FLAG_MULTIPROC},
8626 {"RANDOMIPC", run_randomipc, 0},
8627 {"NEGNOWAIT", run_negprot_nowait, 0},
8628 {"NBENCH", run_nbench, 0},
8629 {"NBENCH2", run_nbench2, 0},
8630 {"OPLOCK1", run_oplock1, 0},
8631 {"OPLOCK2", run_oplock2, 0},
8632 {"OPLOCK4", run_oplock4, 0},
8633 {"DIR", run_dirtest, 0},
8634 {"DIR1", run_dirtest1, 0},
8635 {"DIR-CREATETIME", run_dir_createtime, 0},
8636 {"DENY1", torture_denytest1, 0},
8637 {"DENY2", torture_denytest2, 0},
8638 {"TCON", run_tcon_test, 0},
8639 {"TCONDEV", run_tcon_devtype_test, 0},
8640 {"RW1", run_readwritetest, 0},
8641 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8642 {"RW3", run_readwritelarge, 0},
8643 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8644 {"OPEN", run_opentest, 0},
8645 {"POSIX", run_simple_posix_open_test, 0},
8646 {"POSIX-APPEND", run_posix_append, 0},
8647 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8648 {"ASYNC-ECHO", run_async_echo, 0},
8649 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8650 { "SHORTNAME-TEST", run_shortname_test, 0},
8651 { "ADDRCHANGE", run_addrchange, 0},
8653 {"OPENATTR", run_openattrtest, 0},
8655 {"XCOPY", run_xcopy, 0},
8656 {"RENAME", run_rename, 0},
8657 {"DELETE", run_deletetest, 0},
8658 {"DELETE-LN", run_deletetest_ln, 0},
8659 {"PROPERTIES", run_properties, 0},
8660 {"MANGLE", torture_mangle, 0},
8661 {"MANGLE1", run_mangle1, 0},
8662 {"W2K", run_w2ktest, 0},
8663 {"TRANS2SCAN", torture_trans2_scan, 0},
8664 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8665 {"UTABLE", torture_utable, 0},
8666 {"CASETABLE", torture_casetable, 0},
8667 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8668 {"PIPE_NUMBER", run_pipe_number, 0},
8669 {"TCON2", run_tcon2_test, 0},
8670 {"IOCTL", torture_ioctl_test, 0},
8671 {"CHKPATH", torture_chkpath_test, 0},
8672 {"FDSESS", run_fdsesstest, 0},
8673 { "EATEST", run_eatest, 0},
8674 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8675 { "CHAIN1", run_chain1, 0},
8676 { "CHAIN2", run_chain2, 0},
8677 { "WINDOWS-WRITE", run_windows_write, 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])) {