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/clirap.h"
36 #include "libsmb/nmblib.h"
37 #include "../lib/util/tevent_ntstatus.h"
43 static fstring host, workgroup, share, password, username, myname;
44 static int max_protocol = PROTOCOL_NT1;
45 static const char *sockops="TCP_NODELAY";
47 static int port_to_use=0;
48 int torture_numops=100;
49 int torture_blocksize=1024*1024;
50 static int procnum; /* records process count number when forking */
51 static struct cli_state *current_cli;
52 static fstring randomfname;
53 static bool use_oplocks;
54 static bool use_level_II_oplocks;
55 static const char *client_txt = "client_oplocks.txt";
56 static bool use_kerberos;
57 static fstring multishare_conn_fname;
58 static bool use_multishare_conn = False;
59 static bool do_encrypt;
60 static const char *local_path = NULL;
61 static int signing_state = Undefined;
64 bool torture_showall = False;
66 static double create_procs(bool (*fn)(int), bool *result);
69 /* return a pointer to a anonymous shared memory segment of size "size"
70 which will persist across fork() but will disappear when all processes
73 The memory is not zeroed
75 This function uses system5 shared memory. It takes advantage of a property
76 that the memory is not destroyed if it is attached when the id is removed
78 void *shm_setup(int size)
84 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
86 printf("can't get shared memory\n");
89 shm_unlink("private");
90 if (ftruncate(shmid, size) == -1) {
91 printf("can't set shared memory size\n");
94 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
95 if (ret == MAP_FAILED) {
96 printf("can't map shared memory\n");
100 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
102 printf("can't get shared memory\n");
105 ret = (void *)shmat(shmid, 0, 0);
106 if (!ret || ret == (void *)-1) {
107 printf("can't attach to shared memory\n");
110 /* the following releases the ipc, but note that this process
111 and all its children will still have access to the memory, its
112 just that the shmid is no longer valid for other shm calls. This
113 means we don't leave behind lots of shm segments after we exit
115 See Stevens "advanced programming in unix env" for details
117 shmctl(shmid, IPC_RMID, 0);
123 /********************************************************************
124 Ensure a connection is encrypted.
125 ********************************************************************/
127 static bool force_cli_encryption(struct cli_state *c,
128 const char *sharename)
131 uint32 caplow, caphigh;
134 if (!SERVER_HAS_UNIX_CIFS(c)) {
135 d_printf("Encryption required and "
136 "server that doesn't support "
137 "UNIX extensions - failing connect\n");
141 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
143 if (!NT_STATUS_IS_OK(status)) {
144 d_printf("Encryption required and "
145 "can't get UNIX CIFS extensions "
146 "version from server: %s\n", nt_errstr(status));
150 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
151 d_printf("Encryption required and "
152 "share %s doesn't support "
153 "encryption.\n", sharename);
157 if (c->use_kerberos) {
158 status = cli_gss_smb_encryption_start(c);
160 status = cli_raw_ntlm_smb_encryption_start(c,
166 if (!NT_STATUS_IS_OK(status)) {
167 d_printf("Encryption required and "
168 "setup failed with error %s.\n",
177 static struct cli_state *open_nbt_connection(void)
179 struct nmb_name called, calling;
180 struct sockaddr_storage ss;
184 make_nmb_name(&calling, myname, 0x0);
185 make_nmb_name(&called , host, 0x20);
189 if (!(c = cli_initialise_ex(signing_state))) {
190 printf("Failed initialize cli_struct to connect with %s\n", host);
194 c->port = port_to_use;
196 status = cli_connect(c, host, &ss);
197 if (!NT_STATUS_IS_OK(status)) {
198 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
202 c->use_kerberos = use_kerberos;
204 c->timeout = 120000; /* set a really long timeout (2 minutes) */
205 if (use_oplocks) c->use_oplocks = True;
206 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
208 if (!cli_session_request(c, &calling, &called)) {
210 * Well, that failed, try *SMBSERVER ...
211 * However, we must reconnect as well ...
213 status = cli_connect(c, host, &ss);
214 if (!NT_STATUS_IS_OK(status)) {
215 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
219 make_nmb_name(&called, "*SMBSERVER", 0x20);
220 if (!cli_session_request(c, &calling, &called)) {
221 printf("%s rejected the session\n",host);
222 printf("We tried with a called name of %s & %s\n",
232 /****************************************************************************
233 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
234 ****************************************************************************/
236 static bool cli_bad_session_request(struct cli_state *cli,
237 struct nmb_name *calling, struct nmb_name *called)
244 memcpy(&(cli->calling), calling, sizeof(*calling));
245 memcpy(&(cli->called ), called , sizeof(*called ));
247 /* put in the destination name */
249 tmp = name_mangle(talloc_tos(), cli->called.name,
250 cli->called.name_type);
256 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
258 memcpy(p, tmp, namelen);
263 /* Deliberately corrupt the name len (first byte) */
268 tmp = name_mangle(talloc_tos(), cli->calling.name,
269 cli->calling.name_type);
275 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
277 memcpy(p, tmp, namelen);
281 /* Deliberately corrupt the name len (first byte) */
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(cli->outbuf,len);
294 SCVAL(cli->outbuf,0,0x81);
297 DEBUG(5,("Sent session request\n"));
299 if (!cli_receive_smb(cli))
302 if (CVAL(cli->inbuf,0) != 0x82) {
303 /* This is the wrong place to put the error... JRA. */
304 cli->rap_error = CVAL(cli->inbuf,4);
310 static struct cli_state *open_bad_nbt_connection(void)
312 struct nmb_name called, calling;
313 struct sockaddr_storage ss;
317 make_nmb_name(&calling, myname, 0x0);
318 make_nmb_name(&called , host, 0x20);
322 if (!(c = cli_initialise_ex(signing_state))) {
323 printf("Failed initialize cli_struct to connect with %s\n", host);
329 status = cli_connect(c, host, &ss);
330 if (!NT_STATUS_IS_OK(status)) {
331 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
335 c->timeout = 4000; /* set a short timeout (4 seconds) */
337 if (!cli_bad_session_request(c, &calling, &called)) {
338 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
346 /* Insert a NULL at the first separator of the given path and return a pointer
347 * to the remainder of the string.
350 terminate_path_at_separator(char * path)
358 if ((p = strchr_m(path, '/'))) {
363 if ((p = strchr_m(path, '\\'))) {
373 parse a //server/share type UNC name
375 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
376 char **hostname, char **sharename)
380 *hostname = *sharename = NULL;
382 if (strncmp(unc_name, "\\\\", 2) &&
383 strncmp(unc_name, "//", 2)) {
387 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
388 p = terminate_path_at_separator(*hostname);
391 *sharename = talloc_strdup(mem_ctx, p);
392 terminate_path_at_separator(*sharename);
395 if (*hostname && *sharename) {
399 TALLOC_FREE(*hostname);
400 TALLOC_FREE(*sharename);
404 static bool torture_open_connection_share(struct cli_state **c,
405 const char *hostname,
406 const char *sharename)
412 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
414 flags |= CLI_FULL_CONNECTION_OPLOCKS;
415 if (use_level_II_oplocks)
416 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
418 status = cli_full_connection(c, myname,
419 hostname, NULL, port_to_use,
422 password, flags, signing_state);
423 if (!NT_STATUS_IS_OK(status)) {
424 printf("failed to open share connection: //%s/%s port:%d - %s\n",
425 hostname, sharename, port_to_use, nt_errstr(status));
429 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
432 return force_cli_encryption(*c,
438 bool torture_open_connection(struct cli_state **c, int conn_index)
440 char **unc_list = NULL;
441 int num_unc_names = 0;
444 if (use_multishare_conn==True) {
446 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
447 if (!unc_list || num_unc_names <= 0) {
448 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
452 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
454 printf("Failed to parse UNC name %s\n",
455 unc_list[conn_index % num_unc_names]);
456 TALLOC_FREE(unc_list);
460 result = torture_open_connection_share(c, h, s);
462 /* h, s were copied earlier */
463 TALLOC_FREE(unc_list);
467 return torture_open_connection_share(c, host, share);
470 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
472 uint16 old_vuid = cli->vuid;
473 fstring old_user_name;
474 size_t passlen = strlen(password);
478 fstrcpy(old_user_name, cli->user_name);
480 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
484 *new_vuid = cli->vuid;
485 cli->vuid = old_vuid;
486 status = cli_set_username(cli, old_user_name);
487 if (!NT_STATUS_IS_OK(status)) {
494 bool torture_close_connection(struct cli_state *c)
499 status = cli_tdis(c);
500 if (!NT_STATUS_IS_OK(status)) {
501 printf("tdis failed (%s)\n", nt_errstr(status));
511 /* check if the server produced the expected error code */
512 static bool check_error(int line, struct cli_state *c,
513 uint8 eclass, uint32 ecode, NTSTATUS nterr)
515 if (cli_is_dos_error(c)) {
519 /* Check DOS error */
521 cli_dos_error(c, &cclass, &num);
523 if (eclass != cclass || ecode != num) {
524 printf("unexpected error code class=%d code=%d\n",
525 (int)cclass, (int)num);
526 printf(" expected %d/%d %s (line=%d)\n",
527 (int)eclass, (int)ecode, nt_errstr(nterr), line);
536 status = cli_nt_error(c);
538 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
539 printf("unexpected error code %s\n", nt_errstr(status));
540 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
549 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
551 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
552 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
558 static bool rw_torture(struct cli_state *c)
560 const char *lockfname = "\\torture.lck";
564 pid_t pid2, pid = getpid();
570 memset(buf, '\0', sizeof(buf));
572 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
574 if (!NT_STATUS_IS_OK(status)) {
575 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
577 if (!NT_STATUS_IS_OK(status)) {
578 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
582 for (i=0;i<torture_numops;i++) {
583 unsigned n = (unsigned)sys_random()%10;
586 printf("%d\r", i); fflush(stdout);
588 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
590 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
594 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
595 printf("open failed (%s)\n", cli_errstr(c));
600 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("write failed (%s)\n", nt_errstr(status));
608 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
609 sizeof(pid)+(j*sizeof(buf)),
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("write failed (%s)\n",
620 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
621 printf("read failed (%s)\n", cli_errstr(c));
626 printf("data corruption!\n");
630 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
631 printf("close failed (%s)\n", cli_errstr(c));
635 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
636 printf("unlink failed (%s)\n", cli_errstr(c));
640 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
641 printf("unlock failed (%s)\n", cli_errstr(c));
647 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
654 static bool run_torture(int dummy)
656 struct cli_state *cli;
661 cli_sockopt(cli, sockops);
663 ret = rw_torture(cli);
665 if (!torture_close_connection(cli)) {
672 static bool rw_torture3(struct cli_state *c, char *lockfname)
674 uint16_t fnum = (uint16_t)-1;
679 unsigned countprev = 0;
682 NTSTATUS status = NT_STATUS_OK;
685 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
687 SIVAL(buf, i, sys_random());
692 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
693 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
696 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
697 DENY_NONE, &fnum))) {
698 printf("first open read/write of %s failed (%s)\n",
699 lockfname, cli_errstr(c));
705 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
707 status = cli_open(c, lockfname, O_RDONLY,
709 if (!NT_STATUS_IS_OK(status)) {
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("second open read-only of %s failed (%s)\n",
716 lockfname, cli_errstr(c));
722 for (count = 0; count < sizeof(buf); count += sent)
724 if (count >= countprev) {
725 printf("%d %8d\r", i, count);
728 countprev += (sizeof(buf) / 20);
733 sent = ((unsigned)sys_random()%(20))+ 1;
734 if (sent > sizeof(buf) - count)
736 sent = sizeof(buf) - count;
739 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
740 count, (size_t)sent, NULL);
741 if (!NT_STATUS_IS_OK(status)) {
742 printf("write failed (%s)\n",
749 sent = cli_read(c, fnum, buf_rd+count, count,
753 printf("read failed offset:%d size:%ld (%s)\n",
754 count, (unsigned long)sizeof(buf)-count,
761 if (memcmp(buf_rd+count, buf+count, sent) != 0)
763 printf("read/write compare failed\n");
764 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
773 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
774 printf("close failed (%s)\n", cli_errstr(c));
781 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
783 const char *lockfname = "\\torture2.lck";
792 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
793 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
796 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
797 DENY_NONE, &fnum1))) {
798 printf("first open read/write of %s failed (%s)\n",
799 lockfname, cli_errstr(c1));
802 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
803 DENY_NONE, &fnum2))) {
804 printf("second open read-only of %s failed (%s)\n",
805 lockfname, cli_errstr(c2));
806 cli_close(c1, fnum1);
810 for (i=0;i<torture_numops;i++)
813 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
815 printf("%d\r", i); fflush(stdout);
818 generate_random_buffer((unsigned char *)buf, buf_size);
820 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
822 if (!NT_STATUS_IS_OK(status)) {
823 printf("write failed (%s)\n", nt_errstr(status));
828 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
829 printf("read failed (%s)\n", cli_errstr(c2));
830 printf("read %d, expected %ld\n", (int)bytes_read,
831 (unsigned long)buf_size);
836 if (memcmp(buf_rd, buf, buf_size) != 0)
838 printf("read/write compare failed\n");
844 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
845 printf("close failed (%s)\n", cli_errstr(c2));
848 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
849 printf("close failed (%s)\n", cli_errstr(c1));
853 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
854 printf("unlink failed (%s)\n", cli_errstr(c1));
861 static bool run_readwritetest(int dummy)
863 struct cli_state *cli1, *cli2;
864 bool test1, test2 = False;
866 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
869 cli_sockopt(cli1, sockops);
870 cli_sockopt(cli2, sockops);
872 printf("starting readwritetest\n");
874 test1 = rw_torture2(cli1, cli2);
875 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
878 test2 = rw_torture2(cli1, cli1);
879 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
882 if (!torture_close_connection(cli1)) {
886 if (!torture_close_connection(cli2)) {
890 return (test1 && test2);
893 static bool run_readwritemulti(int dummy)
895 struct cli_state *cli;
900 cli_sockopt(cli, sockops);
902 printf("run_readwritemulti: fname %s\n", randomfname);
903 test = rw_torture3(cli, randomfname);
905 if (!torture_close_connection(cli)) {
912 static bool run_readwritelarge_internal(int max_xmit_k)
914 static struct cli_state *cli1;
916 const char *lockfname = "\\large.dat";
921 if (!torture_open_connection(&cli1, 0)) {
924 cli_sockopt(cli1, sockops);
925 memset(buf,'\0',sizeof(buf));
927 cli1->max_xmit = max_xmit_k*1024;
929 if (signing_state == Required) {
930 /* Horrible cheat to force
931 multiple signed outstanding
932 packets against a Samba server.
934 cli1->is_samba = false;
937 printf("starting readwritelarge_internal\n");
939 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
941 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
942 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
946 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
948 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
949 cli1, fnum1, NULL, &fsize, NULL, NULL,
950 NULL, NULL, NULL))) {
951 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
955 if (fsize == sizeof(buf))
956 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
957 (unsigned long)fsize);
959 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
960 (unsigned long)fsize);
964 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
965 printf("close failed (%s)\n", cli_errstr(cli1));
969 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
970 printf("unlink failed (%s)\n", cli_errstr(cli1));
974 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
975 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
979 cli1->max_xmit = 4*1024;
981 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
983 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
984 cli1, fnum1, NULL, &fsize, NULL, NULL,
985 NULL, NULL, NULL))) {
986 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
990 if (fsize == sizeof(buf))
991 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
992 (unsigned long)fsize);
994 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
995 (unsigned long)fsize);
1000 /* ToDo - set allocation. JRA */
1001 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1002 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1005 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1007 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1011 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1014 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1015 printf("close failed (%s)\n", cli_errstr(cli1));
1019 if (!torture_close_connection(cli1)) {
1025 static bool run_readwritelarge(int dummy)
1027 return run_readwritelarge_internal(128);
1030 static bool run_readwritelarge_signtest(int dummy)
1033 signing_state = Required;
1034 ret = run_readwritelarge_internal(2);
1035 signing_state = Undefined;
1042 #define ival(s) strtol(s, NULL, 0)
1044 /* run a test that simulates an approximate netbench client load */
1045 static bool run_netbench(int client)
1047 struct cli_state *cli;
1052 const char *params[20];
1053 bool correct = True;
1059 cli_sockopt(cli, sockops);
1063 slprintf(cname,sizeof(cname)-1, "client%d", client);
1065 f = fopen(client_txt, "r");
1072 while (fgets(line, sizeof(line)-1, f)) {
1076 line[strlen(line)-1] = 0;
1078 /* printf("[%d] %s\n", line_count, line); */
1080 all_string_sub(line,"client1", cname, sizeof(line));
1082 /* parse the command parameters */
1083 params[0] = strtok_r(line, " ", &saveptr);
1085 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1089 if (i < 2) continue;
1091 if (!strncmp(params[0],"SMB", 3)) {
1092 printf("ERROR: You are using a dbench 1 load file\n");
1096 if (!strcmp(params[0],"NTCreateX")) {
1097 nb_createx(params[1], ival(params[2]), ival(params[3]),
1099 } else if (!strcmp(params[0],"Close")) {
1100 nb_close(ival(params[1]));
1101 } else if (!strcmp(params[0],"Rename")) {
1102 nb_rename(params[1], params[2]);
1103 } else if (!strcmp(params[0],"Unlink")) {
1104 nb_unlink(params[1]);
1105 } else if (!strcmp(params[0],"Deltree")) {
1106 nb_deltree(params[1]);
1107 } else if (!strcmp(params[0],"Rmdir")) {
1108 nb_rmdir(params[1]);
1109 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1110 nb_qpathinfo(params[1]);
1111 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1112 nb_qfileinfo(ival(params[1]));
1113 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1114 nb_qfsinfo(ival(params[1]));
1115 } else if (!strcmp(params[0],"FIND_FIRST")) {
1116 nb_findfirst(params[1]);
1117 } else if (!strcmp(params[0],"WriteX")) {
1118 nb_writex(ival(params[1]),
1119 ival(params[2]), ival(params[3]), ival(params[4]));
1120 } else if (!strcmp(params[0],"ReadX")) {
1121 nb_readx(ival(params[1]),
1122 ival(params[2]), ival(params[3]), ival(params[4]));
1123 } else if (!strcmp(params[0],"Flush")) {
1124 nb_flush(ival(params[1]));
1126 printf("Unknown operation %s\n", params[0]);
1134 if (!torture_close_connection(cli)) {
1142 /* run a test that simulates an approximate netbench client load */
1143 static bool run_nbench(int dummy)
1146 bool correct = True;
1152 signal(SIGALRM, nb_alarm);
1154 t = create_procs(run_netbench, &correct);
1157 printf("\nThroughput %g MB/sec\n",
1158 1.0e-6 * nbio_total() / t);
1164 This test checks for two things:
1166 1) correct support for retaining locks over a close (ie. the server
1167 must not use posix semantics)
1168 2) support for lock timeouts
1170 static bool run_locktest1(int dummy)
1172 struct cli_state *cli1, *cli2;
1173 const char *fname = "\\lockt1.lck";
1174 uint16_t fnum1, fnum2, fnum3;
1176 unsigned lock_timeout;
1178 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1181 cli_sockopt(cli1, sockops);
1182 cli_sockopt(cli2, sockops);
1184 printf("starting locktest1\n");
1186 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1188 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1189 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1192 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1193 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1196 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1197 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1201 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1202 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1207 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1208 printf("lock2 succeeded! This is a locking bug\n");
1211 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1212 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1216 lock_timeout = (1 + (random() % 20));
1217 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1219 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1220 printf("lock3 succeeded! This is a locking bug\n");
1223 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1224 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1228 if (ABS(t2 - t1) < lock_timeout-1) {
1229 printf("error: This server appears not to support timed lock requests\n");
1232 printf("server slept for %u seconds for a %u second timeout\n",
1233 (unsigned int)(t2-t1), lock_timeout);
1235 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1236 printf("close1 failed (%s)\n", cli_errstr(cli1));
1240 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1241 printf("lock4 succeeded! This is a locking bug\n");
1244 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1245 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1248 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1249 printf("close2 failed (%s)\n", cli_errstr(cli1));
1253 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1254 printf("close3 failed (%s)\n", cli_errstr(cli2));
1258 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1259 printf("unlink failed (%s)\n", cli_errstr(cli1));
1264 if (!torture_close_connection(cli1)) {
1268 if (!torture_close_connection(cli2)) {
1272 printf("Passed locktest1\n");
1277 this checks to see if a secondary tconx can use open files from an
1280 static bool run_tcon_test(int dummy)
1282 static struct cli_state *cli;
1283 const char *fname = "\\tcontest.tmp";
1285 uint16 cnum1, cnum2, cnum3;
1286 uint16 vuid1, vuid2;
1291 memset(buf, '\0', sizeof(buf));
1293 if (!torture_open_connection(&cli, 0)) {
1296 cli_sockopt(cli, sockops);
1298 printf("starting tcontest\n");
1300 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1302 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1303 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1310 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1311 if (!NT_STATUS_IS_OK(status)) {
1312 printf("initial write failed (%s)", nt_errstr(status));
1316 status = cli_tcon_andx(cli, share, "?????",
1317 password, strlen(password)+1);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 printf("%s refused 2nd tree connect (%s)\n", host,
1326 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1327 vuid2 = cli->vuid + 1;
1329 /* try a write with the wrong tid */
1332 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1333 if (NT_STATUS_IS_OK(status)) {
1334 printf("* server allows write with wrong TID\n");
1337 printf("server fails write with wrong TID : %s\n",
1342 /* try a write with an invalid tid */
1345 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1346 if (NT_STATUS_IS_OK(status)) {
1347 printf("* server allows write with invalid TID\n");
1350 printf("server fails write with invalid TID : %s\n",
1354 /* try a write with an invalid vuid */
1358 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1359 if (NT_STATUS_IS_OK(status)) {
1360 printf("* server allows write with invalid VUID\n");
1363 printf("server fails write with invalid VUID : %s\n",
1370 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1371 printf("close failed (%s)\n", cli_errstr(cli));
1377 status = cli_tdis(cli);
1378 if (!NT_STATUS_IS_OK(status)) {
1379 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1385 if (!torture_close_connection(cli)) {
1394 checks for old style tcon support
1396 static bool run_tcon2_test(int dummy)
1398 static struct cli_state *cli;
1399 uint16 cnum, max_xmit;
1403 if (!torture_open_connection(&cli, 0)) {
1406 cli_sockopt(cli, sockops);
1408 printf("starting tcon2 test\n");
1410 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1414 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 printf("tcon2 failed : %s\n", nt_errstr(status));
1421 printf("tcon OK : max_xmit=%d cnum=%d\n",
1422 (int)max_xmit, (int)cnum);
1425 if (!torture_close_connection(cli)) {
1429 printf("Passed tcon2 test\n");
1433 static bool tcon_devtest(struct cli_state *cli,
1434 const char *myshare, const char *devtype,
1435 const char *return_devtype,
1436 NTSTATUS expected_error)
1441 status = cli_tcon_andx(cli, myshare, devtype,
1442 password, strlen(password)+1);
1444 if (NT_STATUS_IS_OK(expected_error)) {
1445 if (NT_STATUS_IS_OK(status)) {
1446 if (strcmp(cli->dev, return_devtype) == 0) {
1449 printf("tconX to share %s with type %s "
1450 "succeeded but returned the wrong "
1451 "device type (got [%s] but should have got [%s])\n",
1452 myshare, devtype, cli->dev, return_devtype);
1456 printf("tconX to share %s with type %s "
1457 "should have succeeded but failed\n",
1463 if (NT_STATUS_IS_OK(status)) {
1464 printf("tconx to share %s with type %s "
1465 "should have failed but succeeded\n",
1469 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1473 printf("Returned unexpected error\n");
1482 checks for correct tconX support
1484 static bool run_tcon_devtype_test(int dummy)
1486 static struct cli_state *cli1 = NULL;
1491 status = cli_full_connection(&cli1, myname,
1492 host, NULL, port_to_use,
1494 username, workgroup,
1495 password, flags, signing_state);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 printf("could not open connection\n");
1502 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1505 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1508 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1511 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1514 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1517 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1520 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1523 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1526 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1529 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1535 printf("Passed tcondevtest\n");
1542 This test checks that
1544 1) the server supports multiple locking contexts on the one SMB
1545 connection, distinguished by PID.
1547 2) the server correctly fails overlapping locks made by the same PID (this
1548 goes against POSIX behaviour, which is why it is tricky to implement)
1550 3) the server denies unlock requests by an incorrect client PID
1552 static bool run_locktest2(int dummy)
1554 static struct cli_state *cli;
1555 const char *fname = "\\lockt2.lck";
1556 uint16_t fnum1, fnum2, fnum3;
1557 bool correct = True;
1559 if (!torture_open_connection(&cli, 0)) {
1563 cli_sockopt(cli, sockops);
1565 printf("starting locktest2\n");
1567 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1571 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1572 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1576 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1577 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1583 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1584 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1590 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1591 printf("lock1 failed (%s)\n", cli_errstr(cli));
1595 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1596 printf("WRITE lock1 succeeded! This is a locking bug\n");
1599 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1600 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1603 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1604 printf("WRITE lock2 succeeded! This is a locking bug\n");
1607 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1608 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1611 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1612 printf("READ lock2 succeeded! This is a locking bug\n");
1615 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1616 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1619 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1620 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1623 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1624 printf("unlock at 100 succeeded! This is a locking bug\n");
1628 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1629 printf("unlock1 succeeded! This is a locking bug\n");
1632 if (!check_error(__LINE__, cli,
1634 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1637 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1638 printf("unlock2 succeeded! This is a locking bug\n");
1641 if (!check_error(__LINE__, cli,
1643 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1646 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1647 printf("lock3 succeeded! This is a locking bug\n");
1650 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1655 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1656 printf("close1 failed (%s)\n", cli_errstr(cli));
1660 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1661 printf("close2 failed (%s)\n", cli_errstr(cli));
1665 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1666 printf("close3 failed (%s)\n", cli_errstr(cli));
1670 if (!torture_close_connection(cli)) {
1674 printf("locktest2 finished\n");
1681 This test checks that
1683 1) the server supports the full offset range in lock requests
1685 static bool run_locktest3(int dummy)
1687 static struct cli_state *cli1, *cli2;
1688 const char *fname = "\\lockt3.lck";
1689 uint16_t fnum1, fnum2;
1692 bool correct = True;
1694 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1696 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1699 cli_sockopt(cli1, sockops);
1700 cli_sockopt(cli2, sockops);
1702 printf("starting locktest3\n");
1704 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1706 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1707 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1710 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1711 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1715 for (offset=i=0;i<torture_numops;i++) {
1717 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1718 printf("lock1 %d failed (%s)\n",
1724 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1725 printf("lock2 %d failed (%s)\n",
1732 for (offset=i=0;i<torture_numops;i++) {
1735 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1736 printf("error: lock1 %d succeeded!\n", i);
1740 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1741 printf("error: lock2 %d succeeded!\n", i);
1745 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1746 printf("error: lock3 %d succeeded!\n", i);
1750 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1751 printf("error: lock4 %d succeeded!\n", i);
1756 for (offset=i=0;i<torture_numops;i++) {
1759 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1760 printf("unlock1 %d failed (%s)\n",
1766 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1767 printf("unlock2 %d failed (%s)\n",
1774 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1775 printf("close1 failed (%s)\n", cli_errstr(cli1));
1779 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1780 printf("close2 failed (%s)\n", cli_errstr(cli2));
1784 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1785 printf("unlink failed (%s)\n", cli_errstr(cli1));
1789 if (!torture_close_connection(cli1)) {
1793 if (!torture_close_connection(cli2)) {
1797 printf("finished locktest3\n");
1802 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1803 printf("** "); correct = False; \
1807 looks at overlapping locks
1809 static bool run_locktest4(int dummy)
1811 static struct cli_state *cli1, *cli2;
1812 const char *fname = "\\lockt4.lck";
1813 uint16_t fnum1, fnum2, f;
1816 bool correct = True;
1819 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1823 cli_sockopt(cli1, sockops);
1824 cli_sockopt(cli2, sockops);
1826 printf("starting locktest4\n");
1828 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1830 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1831 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1833 memset(buf, 0, sizeof(buf));
1835 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("Failed to create file: %s\n", nt_errstr(status));
1843 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1844 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1845 EXPECTED(ret, False);
1846 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1848 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1849 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1850 EXPECTED(ret, True);
1851 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1853 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1854 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1855 EXPECTED(ret, False);
1856 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1858 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1859 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1860 EXPECTED(ret, True);
1861 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1863 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1864 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1865 EXPECTED(ret, False);
1866 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1868 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1869 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1870 EXPECTED(ret, True);
1871 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1873 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1874 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1875 EXPECTED(ret, True);
1876 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1878 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1879 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1880 EXPECTED(ret, False);
1881 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1883 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1884 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1885 EXPECTED(ret, False);
1886 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1888 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1889 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1890 EXPECTED(ret, True);
1891 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1893 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1894 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1895 EXPECTED(ret, False);
1896 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1898 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1899 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1901 EXPECTED(ret, False);
1902 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1905 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1906 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1907 EXPECTED(ret, False);
1908 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1910 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1912 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1914 ret = NT_STATUS_IS_OK(status);
1916 EXPECTED(ret, False);
1917 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1920 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1921 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1922 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1923 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1924 EXPECTED(ret, True);
1925 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1928 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1929 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1930 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1931 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1932 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1934 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1935 EXPECTED(ret, True);
1936 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1938 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1939 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1940 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1942 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1943 EXPECTED(ret, True);
1944 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1946 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1947 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1948 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1950 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1951 EXPECTED(ret, True);
1952 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1954 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1955 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1956 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1957 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1959 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1960 EXPECTED(ret, True);
1961 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1963 cli_close(cli1, fnum1);
1964 cli_close(cli2, fnum2);
1965 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1966 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1967 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1968 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1969 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1970 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1971 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1973 cli_close(cli1, fnum1);
1974 EXPECTED(ret, True);
1975 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1978 cli_close(cli1, fnum1);
1979 cli_close(cli2, fnum2);
1980 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1981 torture_close_connection(cli1);
1982 torture_close_connection(cli2);
1984 printf("finished locktest4\n");
1989 looks at lock upgrade/downgrade.
1991 static bool run_locktest5(int dummy)
1993 static struct cli_state *cli1, *cli2;
1994 const char *fname = "\\lockt5.lck";
1995 uint16_t fnum1, fnum2, fnum3;
1998 bool correct = True;
2001 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2005 cli_sockopt(cli1, sockops);
2006 cli_sockopt(cli2, sockops);
2008 printf("starting locktest5\n");
2010 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2012 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2013 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2014 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2016 memset(buf, 0, sizeof(buf));
2018 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2020 if (!NT_STATUS_IS_OK(status)) {
2021 printf("Failed to create file: %s\n", nt_errstr(status));
2026 /* Check for NT bug... */
2027 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2028 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2029 cli_close(cli1, fnum1);
2030 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2031 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2032 EXPECTED(ret, True);
2033 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2034 cli_close(cli1, fnum1);
2035 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2036 cli_unlock(cli1, fnum3, 0, 1);
2038 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2039 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2040 EXPECTED(ret, True);
2041 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2043 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2044 EXPECTED(ret, False);
2046 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2048 /* Unlock the process 2 lock. */
2049 cli_unlock(cli2, fnum2, 0, 4);
2051 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2052 EXPECTED(ret, False);
2054 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2056 /* Unlock the process 1 fnum3 lock. */
2057 cli_unlock(cli1, fnum3, 0, 4);
2059 /* Stack 2 more locks here. */
2060 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2061 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2063 EXPECTED(ret, True);
2064 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2066 /* Unlock the first process lock, then check this was the WRITE lock that was
2069 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2070 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2072 EXPECTED(ret, True);
2073 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2075 /* Unlock the process 2 lock. */
2076 cli_unlock(cli2, fnum2, 0, 4);
2078 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2080 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2082 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2084 EXPECTED(ret, True);
2085 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2087 /* Ensure the next unlock fails. */
2088 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2089 EXPECTED(ret, False);
2090 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2092 /* Ensure connection 2 can get a write lock. */
2093 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2094 EXPECTED(ret, True);
2096 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2100 cli_close(cli1, fnum1);
2101 cli_close(cli2, fnum2);
2102 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2103 if (!torture_close_connection(cli1)) {
2106 if (!torture_close_connection(cli2)) {
2110 printf("finished locktest5\n");
2116 tries the unusual lockingX locktype bits
2118 static bool run_locktest6(int dummy)
2120 static struct cli_state *cli;
2121 const char *fname[1] = { "\\lock6.txt" };
2126 if (!torture_open_connection(&cli, 0)) {
2130 cli_sockopt(cli, sockops);
2132 printf("starting locktest6\n");
2135 printf("Testing %s\n", fname[i]);
2137 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2139 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2140 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2141 cli_close(cli, fnum);
2142 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2144 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2145 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2146 cli_close(cli, fnum);
2147 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2149 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2152 torture_close_connection(cli);
2154 printf("finished locktest6\n");
2158 static bool run_locktest7(int dummy)
2160 struct cli_state *cli1;
2161 const char *fname = "\\lockt7.lck";
2164 bool correct = False;
2167 if (!torture_open_connection(&cli1, 0)) {
2171 cli_sockopt(cli1, sockops);
2173 printf("starting locktest7\n");
2175 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2177 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2179 memset(buf, 0, sizeof(buf));
2181 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2183 if (!NT_STATUS_IS_OK(status)) {
2184 printf("Failed to create file: %s\n", nt_errstr(status));
2188 cli_setpid(cli1, 1);
2190 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2191 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2194 printf("pid1 successfully locked range 130:4 for READ\n");
2197 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2198 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2201 printf("pid1 successfully read the range 130:4\n");
2204 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2205 if (!NT_STATUS_IS_OK(status)) {
2206 printf("pid1 unable to write to the range 130:4, error was "
2207 "%s\n", nt_errstr(status));
2208 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2209 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2213 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2217 cli_setpid(cli1, 2);
2219 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2220 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2222 printf("pid2 successfully read the range 130:4\n");
2225 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 printf("pid2 unable to write to the range 130:4, error was "
2228 "%s\n", nt_errstr(status));
2229 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2230 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2234 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2238 cli_setpid(cli1, 1);
2239 cli_unlock(cli1, fnum1, 130, 4);
2241 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2242 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2245 printf("pid1 successfully locked range 130:4 for WRITE\n");
2248 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2249 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2252 printf("pid1 successfully read the range 130:4\n");
2255 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2256 if (!NT_STATUS_IS_OK(status)) {
2257 printf("pid1 unable to write to the range 130:4, error was "
2258 "%s\n", nt_errstr(status));
2261 printf("pid1 successfully wrote to the range 130:4\n");
2264 cli_setpid(cli1, 2);
2266 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2267 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2268 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2269 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2273 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2277 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2278 if (!NT_STATUS_IS_OK(status)) {
2279 printf("pid2 unable to write to the range 130:4, error was "
2280 "%s\n", nt_errstr(status));
2281 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2282 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2286 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2290 cli_unlock(cli1, fnum1, 130, 0);
2294 cli_close(cli1, fnum1);
2295 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2296 torture_close_connection(cli1);
2298 printf("finished locktest7\n");
2303 * This demonstrates a problem with our use of GPFS share modes: A file
2304 * descriptor sitting in the pending close queue holding a GPFS share mode
2305 * blocks opening a file another time. Happens with Word 2007 temp files.
2306 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2307 * open is denied with NT_STATUS_SHARING_VIOLATION.
2310 static bool run_locktest8(int dummy)
2312 struct cli_state *cli1;
2313 const char *fname = "\\lockt8.lck";
2314 uint16_t fnum1, fnum2;
2316 bool correct = False;
2319 if (!torture_open_connection(&cli1, 0)) {
2323 cli_sockopt(cli1, sockops);
2325 printf("starting locktest8\n");
2327 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2329 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2331 if (!NT_STATUS_IS_OK(status)) {
2332 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2336 memset(buf, 0, sizeof(buf));
2338 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2339 if (!NT_STATUS_IS_OK(status)) {
2340 d_fprintf(stderr, "cli_open second time returned %s\n",
2345 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2346 printf("Unable to apply read lock on range 1:1, error was "
2347 "%s\n", cli_errstr(cli1));
2351 status = cli_close(cli1, fnum1);
2352 if (!NT_STATUS_IS_OK(status)) {
2353 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2357 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 d_fprintf(stderr, "cli_open third time returned %s\n",
2367 cli_close(cli1, fnum1);
2368 cli_close(cli1, fnum2);
2369 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2370 torture_close_connection(cli1);
2372 printf("finished locktest8\n");
2377 * This test is designed to be run in conjunction with
2378 * external NFS or POSIX locks taken in the filesystem.
2379 * It checks that the smbd server will block until the
2380 * lock is released and then acquire it. JRA.
2383 static bool got_alarm;
2384 static int alarm_fd;
2386 static void alarm_handler(int dummy)
2391 static void alarm_handler_parent(int dummy)
2396 static void do_local_lock(int read_fd, int write_fd)
2401 const char *local_pathname = NULL;
2404 local_pathname = talloc_asprintf(talloc_tos(),
2405 "%s/lockt9.lck", local_path);
2406 if (!local_pathname) {
2407 printf("child: alloc fail\n");
2411 unlink(local_pathname);
2412 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2414 printf("child: open of %s failed %s.\n",
2415 local_pathname, strerror(errno));
2419 /* Now take a fcntl lock. */
2420 lock.l_type = F_WRLCK;
2421 lock.l_whence = SEEK_SET;
2424 lock.l_pid = getpid();
2426 ret = fcntl(fd,F_SETLK,&lock);
2428 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2429 local_pathname, strerror(errno));
2432 printf("child: got lock 0:4 on file %s.\n",
2437 CatchSignal(SIGALRM, alarm_handler);
2439 /* Signal the parent. */
2440 if (write(write_fd, &c, 1) != 1) {
2441 printf("child: start signal fail %s.\n",
2448 /* Wait for the parent to be ready. */
2449 if (read(read_fd, &c, 1) != 1) {
2450 printf("child: reply signal fail %s.\n",
2458 printf("child: released lock 0:4 on file %s.\n",
2464 static bool run_locktest9(int dummy)
2466 struct cli_state *cli1;
2467 const char *fname = "\\lockt9.lck";
2469 bool correct = False;
2470 int pipe_in[2], pipe_out[2];
2474 struct timeval start;
2478 printf("starting locktest9\n");
2480 if (local_path == NULL) {
2481 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2485 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2490 if (child_pid == -1) {
2494 if (child_pid == 0) {
2496 do_local_lock(pipe_out[0], pipe_in[1]);
2506 ret = read(pipe_in[0], &c, 1);
2508 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2513 if (!torture_open_connection(&cli1, 0)) {
2517 cli_sockopt(cli1, sockops);
2519 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2521 if (!NT_STATUS_IS_OK(status)) {
2522 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2526 /* Ensure the child has the lock. */
2527 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2528 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2531 d_printf("Child has the lock.\n");
2534 /* Tell the child to wait 5 seconds then exit. */
2535 ret = write(pipe_out[1], &c, 1);
2537 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2542 /* Wait 20 seconds for the lock. */
2543 alarm_fd = cli1->fd;
2544 CatchSignal(SIGALRM, alarm_handler_parent);
2547 start = timeval_current();
2549 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2550 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2551 "%s\n", cli_errstr(cli1));
2556 seconds = timeval_elapsed(&start);
2558 printf("Parent got the lock after %.2f seconds.\n",
2561 status = cli_close(cli1, fnum);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2570 cli_close(cli1, fnum);
2571 torture_close_connection(cli1);
2575 printf("finished locktest9\n");
2580 test whether fnums and tids open on one VC are available on another (a major
2583 static bool run_fdpasstest(int dummy)
2585 struct cli_state *cli1, *cli2;
2586 const char *fname = "\\fdpass.tst";
2591 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2594 cli_sockopt(cli1, sockops);
2595 cli_sockopt(cli2, sockops);
2597 printf("starting fdpasstest\n");
2599 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2601 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2602 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2606 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2608 if (!NT_STATUS_IS_OK(status)) {
2609 printf("write failed (%s)\n", nt_errstr(status));
2613 cli2->vuid = cli1->vuid;
2614 cli2->cnum = cli1->cnum;
2615 cli2->pid = cli1->pid;
2617 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2618 printf("read succeeded! nasty security hole [%s]\n",
2623 cli_close(cli1, fnum1);
2624 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2626 torture_close_connection(cli1);
2627 torture_close_connection(cli2);
2629 printf("finished fdpasstest\n");
2633 static bool run_fdsesstest(int dummy)
2635 struct cli_state *cli;
2640 const char *fname = "\\fdsess.tst";
2641 const char *fname1 = "\\fdsess1.tst";
2648 if (!torture_open_connection(&cli, 0))
2650 cli_sockopt(cli, sockops);
2652 if (!torture_cli_session_setup2(cli, &new_vuid))
2655 saved_cnum = cli->cnum;
2656 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2658 new_cnum = cli->cnum;
2659 cli->cnum = saved_cnum;
2661 printf("starting fdsesstest\n");
2663 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2664 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2666 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2667 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2671 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2673 if (!NT_STATUS_IS_OK(status)) {
2674 printf("write failed (%s)\n", nt_errstr(status));
2678 saved_vuid = cli->vuid;
2679 cli->vuid = new_vuid;
2681 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2682 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2686 /* Try to open a file with different vuid, samba cnum. */
2687 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2688 printf("create with different vuid, same cnum succeeded.\n");
2689 cli_close(cli, fnum2);
2690 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2692 printf("create with different vuid, same cnum failed.\n");
2693 printf("This will cause problems with service clients.\n");
2697 cli->vuid = saved_vuid;
2699 /* Try with same vuid, different cnum. */
2700 cli->cnum = new_cnum;
2702 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2703 printf("read succeeded with different cnum![%s]\n",
2708 cli->cnum = saved_cnum;
2709 cli_close(cli, fnum1);
2710 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2712 torture_close_connection(cli);
2714 printf("finished fdsesstest\n");
2719 This test checks that
2721 1) the server does not allow an unlink on a file that is open
2723 static bool run_unlinktest(int dummy)
2725 struct cli_state *cli;
2726 const char *fname = "\\unlink.tst";
2728 bool correct = True;
2730 if (!torture_open_connection(&cli, 0)) {
2734 cli_sockopt(cli, sockops);
2736 printf("starting unlink test\n");
2738 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2742 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2743 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2747 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2748 printf("error: server allowed unlink on an open file\n");
2751 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2752 NT_STATUS_SHARING_VIOLATION);
2755 cli_close(cli, fnum);
2756 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2758 if (!torture_close_connection(cli)) {
2762 printf("unlink test finished\n");
2769 test how many open files this server supports on the one socket
2771 static bool run_maxfidtest(int dummy)
2773 struct cli_state *cli;
2775 uint16_t fnums[0x11000];
2778 bool correct = True;
2783 printf("failed to connect\n");
2787 cli_sockopt(cli, sockops);
2789 for (i=0; i<0x11000; i++) {
2790 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2791 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2792 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2793 printf("open of %s failed (%s)\n",
2794 fname, cli_errstr(cli));
2795 printf("maximum fnum is %d\n", i);
2803 printf("cleaning up\n");
2805 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2806 cli_close(cli, fnums[i]);
2807 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2808 printf("unlink of %s failed (%s)\n",
2809 fname, cli_errstr(cli));
2816 printf("maxfid test finished\n");
2817 if (!torture_close_connection(cli)) {
2823 /* generate a random buffer */
2824 static void rand_buf(char *buf, int len)
2827 *buf = (char)sys_random();
2832 /* send smb negprot commands, not reading the response */
2833 static bool run_negprot_nowait(int dummy)
2835 struct tevent_context *ev;
2837 struct cli_state *cli;
2838 bool correct = True;
2840 printf("starting negprot nowait test\n");
2842 ev = tevent_context_init(talloc_tos());
2847 if (!(cli = open_nbt_connection())) {
2852 for (i=0;i<50000;i++) {
2853 struct tevent_req *req;
2855 req = cli_negprot_send(ev, ev, cli);
2860 if (!tevent_req_poll(req, ev)) {
2861 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2869 if (torture_close_connection(cli)) {
2873 printf("finished negprot nowait test\n");
2878 /* send smb negprot commands, not reading the response */
2879 static bool run_bad_nbt_session(int dummy)
2881 static struct cli_state *cli;
2883 printf("starting bad nbt session test\n");
2885 if (!(cli = open_bad_nbt_connection())) {
2890 printf("finished bad nbt session test\n");
2894 /* send random IPC commands */
2895 static bool run_randomipc(int dummy)
2897 char *rparam = NULL;
2899 unsigned int rdrcnt,rprcnt;
2901 int api, param_len, i;
2902 struct cli_state *cli;
2903 bool correct = True;
2906 printf("starting random ipc test\n");
2908 if (!torture_open_connection(&cli, 0)) {
2912 for (i=0;i<count;i++) {
2913 api = sys_random() % 500;
2914 param_len = (sys_random() % 64);
2916 rand_buf(param, param_len);
2921 param, param_len, 8,
2922 NULL, 0, BUFFER_SIZE,
2926 printf("%d/%d\r", i,count);
2929 printf("%d/%d\n", i, count);
2931 if (!torture_close_connection(cli)) {
2935 printf("finished random ipc test\n");
2942 static void browse_callback(const char *sname, uint32 stype,
2943 const char *comment, void *state)
2945 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2951 This test checks the browse list code
2954 static bool run_browsetest(int dummy)
2956 static struct cli_state *cli;
2957 bool correct = True;
2959 printf("starting browse test\n");
2961 if (!torture_open_connection(&cli, 0)) {
2965 printf("domain list:\n");
2966 cli_NetServerEnum(cli, cli->server_domain,
2967 SV_TYPE_DOMAIN_ENUM,
2968 browse_callback, NULL);
2970 printf("machine list:\n");
2971 cli_NetServerEnum(cli, cli->server_domain,
2973 browse_callback, NULL);
2975 if (!torture_close_connection(cli)) {
2979 printf("browse test finished\n");
2987 This checks how the getatr calls works
2989 static bool run_attrtest(int dummy)
2991 struct cli_state *cli;
2994 const char *fname = "\\attrib123456789.tst";
2995 bool correct = True;
2997 printf("starting attrib test\n");
2999 if (!torture_open_connection(&cli, 0)) {
3003 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3004 cli_open(cli, fname,
3005 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3006 cli_close(cli, fnum);
3007 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3008 printf("getatr failed (%s)\n", cli_errstr(cli));
3012 if (abs(t - time(NULL)) > 60*60*24*10) {
3013 printf("ERROR: SMBgetatr bug. time is %s",
3019 t2 = t-60*60*24; /* 1 day ago */
3021 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
3022 printf("setatr failed (%s)\n", cli_errstr(cli));
3026 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3027 printf("getatr failed (%s)\n", cli_errstr(cli));
3032 printf("ERROR: getatr/setatr bug. times are\n%s",
3034 printf("%s", ctime(&t2));
3038 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3040 if (!torture_close_connection(cli)) {
3044 printf("attrib test finished\n");
3051 This checks a couple of trans2 calls
3053 static bool run_trans2test(int dummy)
3055 struct cli_state *cli;
3058 time_t c_time, a_time, m_time;
3059 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3060 const char *fname = "\\trans2.tst";
3061 const char *dname = "\\trans2";
3062 const char *fname2 = "\\trans2\\trans2.tst";
3064 bool correct = True;
3068 printf("starting trans2 test\n");
3070 if (!torture_open_connection(&cli, 0)) {
3074 status = cli_get_fs_attr_info(cli, &fs_attr);
3075 if (!NT_STATUS_IS_OK(status)) {
3076 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3081 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3082 cli_open(cli, fname,
3083 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3084 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3085 cli, fnum, NULL, &size, &c_time_ts,
3086 &a_time_ts, &w_time_ts,
3087 &m_time_ts, NULL))) {
3088 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3092 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3093 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3097 if (strcmp(pname, fname)) {
3098 printf("qfilename gave different name? [%s] [%s]\n",
3103 cli_close(cli, fnum);
3107 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3108 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3109 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3110 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3113 cli_close(cli, fnum);
3115 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3117 if (!NT_STATUS_IS_OK(status)) {
3118 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3121 if (c_time != m_time) {
3122 printf("create time=%s", ctime(&c_time));
3123 printf("modify time=%s", ctime(&m_time));
3124 printf("This system appears to have sticky create times\n");
3126 if (a_time % (60*60) == 0) {
3127 printf("access time=%s", ctime(&a_time));
3128 printf("This system appears to set a midnight access time\n");
3132 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3133 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3139 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3140 cli_open(cli, fname,
3141 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3142 cli_close(cli, fnum);
3143 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3144 &m_time_ts, &size, NULL, NULL);
3145 if (!NT_STATUS_IS_OK(status)) {
3146 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3149 if (w_time_ts.tv_sec < 60*60*24*2) {
3150 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3151 printf("This system appears to set a initial 0 write time\n");
3156 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3159 /* check if the server updates the directory modification time
3160 when creating a new file */
3161 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3162 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3166 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3167 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3168 if (!NT_STATUS_IS_OK(status)) {
3169 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3173 cli_open(cli, fname2,
3174 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3175 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3176 cli_close(cli, fnum);
3177 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3178 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3183 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3185 printf("This system does not update directory modification times\n");
3189 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3190 cli_rmdir(cli, dname);
3192 if (!torture_close_connection(cli)) {
3196 printf("trans2 test finished\n");
3202 This checks new W2K calls.
3205 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3207 uint8_t *buf = NULL;
3211 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3212 pcli->max_xmit, &buf, &len);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3217 printf("qfileinfo: level %d, len = %u\n", level, len);
3218 dump_data(0, (uint8 *)buf, len);
3225 static bool run_w2ktest(int dummy)
3227 struct cli_state *cli;
3229 const char *fname = "\\w2ktest\\w2k.tst";
3231 bool correct = True;
3233 printf("starting w2k test\n");
3235 if (!torture_open_connection(&cli, 0)) {
3239 cli_open(cli, fname,
3240 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3242 for (level = 1004; level < 1040; level++) {
3243 new_trans(cli, fnum, level);
3246 cli_close(cli, fnum);
3248 if (!torture_close_connection(cli)) {
3252 printf("w2k test finished\n");
3259 this is a harness for some oplock tests
3261 static bool run_oplock1(int dummy)
3263 struct cli_state *cli1;
3264 const char *fname = "\\lockt1.lck";
3266 bool correct = True;
3268 printf("starting oplock test 1\n");
3270 if (!torture_open_connection(&cli1, 0)) {
3274 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3276 cli_sockopt(cli1, sockops);
3278 cli1->use_oplocks = True;
3280 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3281 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3285 cli1->use_oplocks = False;
3287 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3288 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3290 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3291 printf("close2 failed (%s)\n", cli_errstr(cli1));
3295 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3296 printf("unlink failed (%s)\n", cli_errstr(cli1));
3300 if (!torture_close_connection(cli1)) {
3304 printf("finished oplock test 1\n");
3309 static bool run_oplock2(int dummy)
3311 struct cli_state *cli1, *cli2;
3312 const char *fname = "\\lockt2.lck";
3313 uint16_t fnum1, fnum2;
3314 int saved_use_oplocks = use_oplocks;
3316 bool correct = True;
3317 volatile bool *shared_correct;
3319 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3320 *shared_correct = True;
3322 use_level_II_oplocks = True;
3325 printf("starting oplock test 2\n");
3327 if (!torture_open_connection(&cli1, 0)) {
3328 use_level_II_oplocks = False;
3329 use_oplocks = saved_use_oplocks;
3333 cli1->use_oplocks = True;
3334 cli1->use_level_II_oplocks = True;
3336 if (!torture_open_connection(&cli2, 1)) {
3337 use_level_II_oplocks = False;
3338 use_oplocks = saved_use_oplocks;
3342 cli2->use_oplocks = True;
3343 cli2->use_level_II_oplocks = True;
3345 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3347 cli_sockopt(cli1, sockops);
3348 cli_sockopt(cli2, sockops);
3350 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3351 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3355 /* Don't need the globals any more. */
3356 use_level_II_oplocks = False;
3357 use_oplocks = saved_use_oplocks;
3361 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3362 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3363 *shared_correct = False;
3369 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3370 printf("close2 failed (%s)\n", cli_errstr(cli1));
3371 *shared_correct = False;
3379 /* Ensure cli1 processes the break. Empty file should always return 0
3382 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3383 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3387 /* Should now be at level II. */
3388 /* Test if sending a write locks causes a break to none. */
3390 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3391 printf("lock failed (%s)\n", cli_errstr(cli1));
3395 cli_unlock(cli1, fnum1, 0, 4);
3399 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3400 printf("lock failed (%s)\n", cli_errstr(cli1));
3404 cli_unlock(cli1, fnum1, 0, 4);
3408 cli_read(cli1, fnum1, buf, 0, 4);
3410 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3411 printf("close1 failed (%s)\n", cli_errstr(cli1));
3417 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3418 printf("unlink failed (%s)\n", cli_errstr(cli1));
3422 if (!torture_close_connection(cli1)) {
3426 if (!*shared_correct) {
3430 printf("finished oplock test 2\n");
3435 /* handler for oplock 3 tests */
3436 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3438 printf("got oplock break fnum=%d level=%d\n",
3440 return cli_oplock_ack(cli, fnum, level);
3443 static bool run_oplock3(int dummy)
3445 struct cli_state *cli;
3446 const char *fname = "\\oplockt3.dat";
3448 char buf[4] = "abcd";
3449 bool correct = True;
3450 volatile bool *shared_correct;
3452 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3453 *shared_correct = True;
3455 printf("starting oplock test 3\n");
3460 use_level_II_oplocks = True;
3461 if (!torture_open_connection(&cli, 0)) {
3462 *shared_correct = False;
3466 /* try to trigger a oplock break in parent */
3467 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3468 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3474 use_level_II_oplocks = True;
3475 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3478 cli_oplock_handler(cli, oplock3_handler);
3479 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3480 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3481 cli_close(cli, fnum);
3482 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3483 cli->timeout = 20000;
3484 cli_receive_smb(cli);
3485 printf("finished oplock test 3\n");
3487 return (correct && *shared_correct);
3489 /* What are we looking for here? What's sucess and what's FAILURE? */
3492 /* handler for oplock 4 tests */
3493 bool *oplock4_shared_correct;
3495 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3497 printf("got oplock break fnum=%d level=%d\n",
3499 *oplock4_shared_correct = true;
3500 cli_oplock_ack(cli, fnum, level);
3501 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3504 static bool run_oplock4(int dummy)
3506 struct cli_state *cli1, *cli2;
3507 const char *fname = "\\lockt4.lck";
3508 const char *fname_ln = "\\lockt4_ln.lck";
3509 uint16_t fnum1, fnum2;
3510 int saved_use_oplocks = use_oplocks;
3512 bool correct = true;
3514 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3515 *oplock4_shared_correct = false;
3517 printf("starting oplock test 4\n");
3519 if (!torture_open_connection(&cli1, 0)) {
3520 use_level_II_oplocks = false;
3521 use_oplocks = saved_use_oplocks;
3525 if (!torture_open_connection(&cli2, 1)) {
3526 use_level_II_oplocks = false;
3527 use_oplocks = saved_use_oplocks;
3531 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3532 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3534 cli_sockopt(cli1, sockops);
3535 cli_sockopt(cli2, sockops);
3537 /* Create the file. */
3538 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3539 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3543 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3544 printf("close1 failed (%s)\n", cli_errstr(cli1));
3548 /* Now create a hardlink. */
3549 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3550 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3554 /* Prove that opening hardlinks cause deny modes to conflict. */
3555 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3556 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3560 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3561 if (NT_STATUS_IS_OK(status)) {
3562 printf("open of %s succeeded - should fail with sharing violation.\n",
3567 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3568 printf("open of %s should fail with sharing violation. Got %s\n",
3569 fname_ln, nt_errstr(status));
3573 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3574 printf("close1 failed (%s)\n", cli_errstr(cli1));
3578 cli1->use_oplocks = true;
3579 cli1->use_level_II_oplocks = true;
3581 cli2->use_oplocks = true;
3582 cli2->use_level_II_oplocks = true;
3584 cli_oplock_handler(cli1, oplock4_handler);
3585 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3586 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3592 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3593 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3594 *oplock4_shared_correct = false;
3598 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3599 printf("close2 failed (%s)\n", cli_errstr(cli1));
3600 *oplock4_shared_correct = false;
3608 /* Process the oplock break. */
3609 cli_receive_smb(cli1);
3611 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3612 printf("close1 failed (%s)\n", cli_errstr(cli1));
3616 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3617 printf("unlink failed (%s)\n", cli_errstr(cli1));
3620 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3621 printf("unlink failed (%s)\n", cli_errstr(cli1));
3625 if (!torture_close_connection(cli1)) {
3629 if (!*oplock4_shared_correct) {
3633 printf("finished oplock test 4\n");
3640 Test delete on close semantics.
3642 static bool run_deletetest(int dummy)
3644 struct cli_state *cli1 = NULL;
3645 struct cli_state *cli2 = NULL;
3646 const char *fname = "\\delete.file";
3647 uint16_t fnum1 = (uint16_t)-1;
3648 uint16_t fnum2 = (uint16_t)-1;
3649 bool correct = True;
3651 printf("starting delete test\n");
3653 if (!torture_open_connection(&cli1, 0)) {
3657 cli_sockopt(cli1, sockops);
3659 /* Test 1 - this should delete the file on close. */
3661 cli_setatr(cli1, fname, 0, 0);
3662 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3664 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3665 0, FILE_OVERWRITE_IF,
3666 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3667 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3672 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3673 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3678 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3679 printf("[1] open of %s succeeded (should fail)\n", fname);
3684 printf("first delete on close test succeeded.\n");
3686 /* Test 2 - this should delete the file on close. */
3688 cli_setatr(cli1, fname, 0, 0);
3689 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3691 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3692 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3693 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3694 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3699 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3700 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3705 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3706 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3711 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3712 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3713 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3714 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3718 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3720 printf("second delete on close test succeeded.\n");
3723 cli_setatr(cli1, fname, 0, 0);
3724 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3726 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3727 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3728 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3733 /* This should fail with a sharing violation - open for delete is only compatible
3734 with SHARE_DELETE. */
3736 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3737 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3738 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3743 /* This should succeed. */
3745 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3746 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3747 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3752 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3753 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3758 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3759 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3764 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3765 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3770 /* This should fail - file should no longer be there. */
3772 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3773 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3774 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3775 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3777 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3781 printf("third delete on close test succeeded.\n");
3784 cli_setatr(cli1, fname, 0, 0);
3785 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3787 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3788 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3789 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3794 /* This should succeed. */
3795 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3796 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3797 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3802 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3803 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3808 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3809 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3814 /* This should fail - no more opens once delete on close set. */
3815 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3816 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3817 FILE_OPEN, 0, 0, &fnum2))) {
3818 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3822 printf("fourth delete on close test succeeded.\n");
3824 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3825 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3831 cli_setatr(cli1, fname, 0, 0);
3832 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3834 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3835 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3840 /* This should fail - only allowed on NT opens with DELETE access. */
3842 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3843 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3848 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3849 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3854 printf("fifth delete on close test succeeded.\n");
3857 cli_setatr(cli1, fname, 0, 0);
3858 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3860 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3861 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3862 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3863 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3868 /* This should fail - only allowed on NT opens with DELETE access. */
3870 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3871 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3876 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3877 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3882 printf("sixth delete on close test succeeded.\n");
3885 cli_setatr(cli1, fname, 0, 0);
3886 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3888 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3889 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3890 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3895 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3896 printf("[7] setting delete_on_close on file failed !\n");
3901 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3902 printf("[7] unsetting delete_on_close on file failed !\n");
3907 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3908 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3913 /* This next open should succeed - we reset the flag. */
3915 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3916 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3921 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3922 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3927 printf("seventh delete on close test succeeded.\n");
3930 cli_setatr(cli1, fname, 0, 0);
3931 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3933 if (!torture_open_connection(&cli2, 1)) {
3934 printf("[8] failed to open second connection.\n");
3939 cli_sockopt(cli1, sockops);
3941 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3942 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3943 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3944 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3949 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3950 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3951 FILE_OPEN, 0, 0, &fnum2))) {
3952 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3957 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3958 printf("[8] setting delete_on_close on file failed !\n");
3963 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3964 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3969 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3970 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3975 /* This should fail.. */
3976 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3977 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3981 printf("eighth delete on close test succeeded.\n");
3983 /* This should fail - we need to set DELETE_ACCESS. */
3984 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3985 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3986 printf("[9] open of %s succeeded should have failed!\n", fname);
3991 printf("ninth delete on close test succeeded.\n");
3993 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3994 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3995 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4000 /* This should delete the file. */
4001 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4002 printf("[10] close failed (%s)\n", cli_errstr(cli1));
4007 /* This should fail.. */
4008 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4009 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4013 printf("tenth delete on close test succeeded.\n");
4015 cli_setatr(cli1, fname, 0, 0);
4016 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4018 /* What error do we get when attempting to open a read-only file with
4021 /* Create a readonly file. */
4022 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4023 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4024 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4029 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4030 printf("[11] close failed (%s)\n", cli_errstr(cli1));
4035 /* Now try open for delete access. */
4036 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4037 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4038 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4039 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4040 cli_close(cli1, fnum1);
4044 NTSTATUS nterr = cli_nt_error(cli1);
4045 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4046 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4050 printf("eleventh delete on close test succeeded.\n");
4054 printf("finished delete test\n");
4057 /* FIXME: This will crash if we aborted before cli2 got
4058 * intialized, because these functions don't handle
4059 * uninitialized connections. */
4061 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4062 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4063 cli_setatr(cli1, fname, 0, 0);
4064 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4066 if (cli1 && !torture_close_connection(cli1)) {
4069 if (cli2 && !torture_close_connection(cli2)) {
4075 static bool run_deletetest_ln(int dummy)
4077 struct cli_state *cli;
4078 const char *fname = "\\delete1";
4079 const char *fname_ln = "\\delete1_ln";
4083 bool correct = true;
4086 printf("starting deletetest-ln\n");
4088 if (!torture_open_connection(&cli, 0)) {
4092 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4093 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4095 cli_sockopt(cli, sockops);
4097 /* Create the file. */
4098 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4099 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4103 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4104 printf("close1 failed (%s)\n", cli_errstr(cli));
4108 /* Now create a hardlink. */
4109 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4110 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4114 /* Open the original file. */
4115 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4116 FILE_ATTRIBUTE_NORMAL,
4117 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4118 FILE_OPEN_IF, 0, 0, &fnum);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4124 /* Unlink the hard link path. */
4125 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4126 FILE_ATTRIBUTE_NORMAL,
4127 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4128 FILE_OPEN_IF, 0, 0, &fnum1);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4133 status = cli_nt_delete_on_close(cli, fnum1, true);
4134 if (!NT_STATUS_IS_OK(status)) {
4135 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4136 __location__, fname_ln, nt_errstr(status));
4140 status = cli_close(cli, fnum1);
4141 if (!NT_STATUS_IS_OK(status)) {
4142 printf("close %s failed (%s)\n",
4143 fname_ln, nt_errstr(status));
4147 status = cli_close(cli, fnum);
4148 if (!NT_STATUS_IS_OK(status)) {
4149 printf("close %s failed (%s)\n",
4150 fname, nt_errstr(status));
4154 /* Ensure the original file is still there. */
4155 status = cli_getatr(cli, fname, NULL, NULL, &t);
4156 if (!NT_STATUS_IS_OK(status)) {
4157 printf("%s getatr on file %s failed (%s)\n",
4164 /* Ensure the link path is gone. */
4165 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4166 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4167 printf("%s, getatr for file %s returned wrong error code %s "
4168 "- should have been deleted\n",
4170 fname_ln, nt_errstr(status));
4174 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4175 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4177 if (!torture_close_connection(cli)) {
4181 printf("finished deletetest-ln\n");
4187 print out server properties
4189 static bool run_properties(int dummy)
4191 struct cli_state *cli;
4192 bool correct = True;
4194 printf("starting properties test\n");
4198 if (!torture_open_connection(&cli, 0)) {
4202 cli_sockopt(cli, sockops);
4204 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4206 if (!torture_close_connection(cli)) {
4215 /* FIRST_DESIRED_ACCESS 0xf019f */
4216 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4217 FILE_READ_EA| /* 0xf */ \
4218 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4219 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4220 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4221 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4222 /* SECOND_DESIRED_ACCESS 0xe0080 */
4223 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4224 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4225 WRITE_OWNER_ACCESS /* 0xe0000 */
4228 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4229 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4231 WRITE_OWNER_ACCESS /* */
4235 Test ntcreate calls made by xcopy
4237 static bool run_xcopy(int dummy)
4239 static struct cli_state *cli1;
4240 const char *fname = "\\test.txt";
4241 bool correct = True;
4242 uint16_t fnum1, fnum2;
4244 printf("starting xcopy test\n");
4246 if (!torture_open_connection(&cli1, 0)) {
4250 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4251 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4252 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4253 0x4044, 0, &fnum1))) {
4254 printf("First open failed - %s\n", cli_errstr(cli1));
4258 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4259 SECOND_DESIRED_ACCESS, 0,
4260 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4261 0x200000, 0, &fnum2))) {
4262 printf("second open failed - %s\n", cli_errstr(cli1));
4266 if (!torture_close_connection(cli1)) {
4274 Test rename on files open with share delete and no share delete.
4276 static bool run_rename(int dummy)
4278 static struct cli_state *cli1;
4279 const char *fname = "\\test.txt";
4280 const char *fname1 = "\\test1.txt";
4281 bool correct = True;
4286 printf("starting rename test\n");
4288 if (!torture_open_connection(&cli1, 0)) {
4292 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4293 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4294 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4295 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4296 printf("First open failed - %s\n", cli_errstr(cli1));
4300 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4301 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4303 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4307 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4308 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4312 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4313 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4314 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4316 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4318 FILE_SHARE_DELETE|FILE_SHARE_READ,
4320 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("Second open failed - %s\n", cli_errstr(cli1));
4326 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4327 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4330 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4333 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4334 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4338 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4339 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4341 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4342 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4343 printf("Third open failed - %s\n", cli_errstr(cli1));
4352 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4353 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4354 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4357 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4358 printf("[8] setting delete_on_close on file failed !\n");
4362 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4363 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4369 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4370 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4373 printf("Third rename succeeded (SHARE_NONE)\n");
4376 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4377 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4381 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4382 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4386 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4387 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4388 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4392 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4393 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4395 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4399 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4400 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4404 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4405 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4409 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4410 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4411 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4415 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4416 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4420 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4424 * Now check if the first name still exists ...
4427 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4428 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4429 printf("Opening original file after rename of open file fails: %s\n",
4433 printf("Opening original file after rename of open file works ...\n");
4434 (void)cli_close(cli1, fnum2);
4438 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4439 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4443 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4444 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4445 printf("getatr on file %s failed - %s ! \n",
4450 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4451 printf("Renamed file %s has wrong attr 0x%x "
4452 "(should be 0x%x)\n",
4455 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4458 printf("Renamed file %s has archive bit set\n", fname1);
4462 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4463 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4465 if (!torture_close_connection(cli1)) {
4472 static bool run_pipe_number(int dummy)
4474 struct cli_state *cli1;
4475 const char *pipe_name = "\\SPOOLSS";
4479 printf("starting pipenumber test\n");
4480 if (!torture_open_connection(&cli1, 0)) {
4484 cli_sockopt(cli1, sockops);
4486 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4487 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4488 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4492 printf("\r%6d", num_pipes);
4495 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4496 torture_close_connection(cli1);
4501 Test open mode returns on read-only files.
4503 static bool run_opentest(int dummy)
4505 static struct cli_state *cli1;
4506 static struct cli_state *cli2;
4507 const char *fname = "\\readonly.file";
4508 uint16_t fnum1, fnum2;
4511 bool correct = True;
4515 printf("starting open test\n");
4517 if (!torture_open_connection(&cli1, 0)) {
4521 cli_setatr(cli1, fname, 0, 0);
4522 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4524 cli_sockopt(cli1, sockops);
4526 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4527 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4531 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4532 printf("close2 failed (%s)\n", cli_errstr(cli1));
4536 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0))) {
4537 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4541 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4542 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4546 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4547 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4549 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4550 NT_STATUS_ACCESS_DENIED)) {
4551 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4554 printf("finished open test 1\n");
4556 cli_close(cli1, fnum1);
4558 /* Now try not readonly and ensure ERRbadshare is returned. */
4560 cli_setatr(cli1, fname, 0, 0);
4562 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4563 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4567 /* This will fail - but the error should be ERRshare. */
4568 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4570 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4571 NT_STATUS_SHARING_VIOLATION)) {
4572 printf("correct error code ERRDOS/ERRbadshare returned\n");
4575 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4576 printf("close2 failed (%s)\n", cli_errstr(cli1));
4580 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4582 printf("finished open test 2\n");
4584 /* Test truncate open disposition on file opened for read. */
4586 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4587 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4591 /* write 20 bytes. */
4593 memset(buf, '\0', 20);
4595 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4596 if (!NT_STATUS_IS_OK(status)) {
4597 printf("write failed (%s)\n", nt_errstr(status));
4601 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4602 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4606 /* Ensure size == 20. */
4607 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4608 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4613 printf("(3) file size != 20\n");
4617 /* Now test if we can truncate a file opened for readonly. */
4619 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4620 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4624 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4625 printf("close2 failed (%s)\n", cli_errstr(cli1));
4629 /* Ensure size == 0. */
4630 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4631 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4636 printf("(3) file size != 0\n");
4639 printf("finished open test 3\n");
4641 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4643 printf("Do ctemp tests\n");
4644 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4645 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4648 printf("ctemp gave path %s\n", tmp_path);
4649 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4650 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4652 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
4653 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4656 /* Test the non-io opens... */
4658 if (!torture_open_connection(&cli2, 1)) {
4662 cli_setatr(cli2, fname, 0, 0);
4663 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4665 cli_sockopt(cli2, sockops);
4667 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4669 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4670 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4671 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4675 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4676 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4677 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4681 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4682 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4685 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4686 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4690 printf("non-io open test #1 passed.\n");
4692 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4694 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4696 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4697 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4698 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4702 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4703 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4704 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4708 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4709 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4712 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4713 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4717 printf("non-io open test #2 passed.\n");
4719 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4721 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4723 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4724 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4725 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4729 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4730 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4731 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4735 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4736 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4739 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4740 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4744 printf("non-io open test #3 passed.\n");
4746 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4748 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4750 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4751 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4752 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4756 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4757 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4758 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4762 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4764 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4765 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4769 printf("non-io open test #4 passed.\n");
4771 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4773 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4775 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4776 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4777 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4781 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4782 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4783 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4787 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4788 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4792 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4793 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4797 printf("non-io open test #5 passed.\n");
4799 printf("TEST #6 testing 1 non-io open, one io open\n");
4801 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4803 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4804 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4805 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4809 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4810 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4811 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4815 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4816 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4820 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4821 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4825 printf("non-io open test #6 passed.\n");
4827 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4829 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4831 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4832 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4833 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4837 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4838 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4839 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4843 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4845 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4846 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4850 printf("non-io open test #7 passed.\n");
4852 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4854 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4855 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4856 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4857 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4858 if (!NT_STATUS_IS_OK(status)) {
4859 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4864 /* Write to ensure we have to update the file time. */
4865 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
4867 if (!NT_STATUS_IS_OK(status)) {
4868 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
4873 status = cli_close(cli1, fnum1);
4874 if (!NT_STATUS_IS_OK(status)) {
4875 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4881 if (!torture_close_connection(cli1)) {
4884 if (!torture_close_connection(cli2)) {
4891 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4893 uint16 major, minor;
4894 uint32 caplow, caphigh;
4897 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4898 printf("Server doesn't support UNIX CIFS extensions.\n");
4899 return NT_STATUS_NOT_SUPPORTED;
4902 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4904 if (!NT_STATUS_IS_OK(status)) {
4905 printf("Server didn't return UNIX CIFS extensions: %s\n",
4910 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4912 if (!NT_STATUS_IS_OK(status)) {
4913 printf("Server doesn't support setting UNIX CIFS extensions: "
4914 "%s.\n", nt_errstr(status));
4918 return NT_STATUS_OK;
4922 Test POSIX open /mkdir calls.
4924 static bool run_simple_posix_open_test(int dummy)
4926 static struct cli_state *cli1;
4927 const char *fname = "posix:file";
4928 const char *hname = "posix:hlink";
4929 const char *sname = "posix:symlink";
4930 const char *dname = "posix:dir";
4933 uint16_t fnum1 = (uint16_t)-1;
4934 SMB_STRUCT_STAT sbuf;
4935 bool correct = false;
4938 printf("Starting simple POSIX open test\n");
4940 if (!torture_open_connection(&cli1, 0)) {
4944 cli_sockopt(cli1, sockops);
4946 status = torture_setup_unix_extensions(cli1);
4947 if (!NT_STATUS_IS_OK(status)) {
4951 cli_setatr(cli1, fname, 0, 0);
4952 cli_posix_unlink(cli1, fname);
4953 cli_setatr(cli1, dname, 0, 0);
4954 cli_posix_rmdir(cli1, dname);
4955 cli_setatr(cli1, hname, 0, 0);
4956 cli_posix_unlink(cli1, hname);
4957 cli_setatr(cli1, sname, 0, 0);
4958 cli_posix_unlink(cli1, sname);
4960 /* Create a directory. */
4961 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4962 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4966 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4967 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4971 /* Test ftruncate - set file size. */
4972 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4973 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4977 /* Ensure st_size == 1000 */
4978 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4979 printf("stat failed (%s)\n", cli_errstr(cli1));
4983 if (sbuf.st_ex_size != 1000) {
4984 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4988 /* Test ftruncate - set file size back to zero. */
4989 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4990 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4994 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4995 printf("close failed (%s)\n", cli_errstr(cli1));
4999 /* Now open the file again for read only. */
5000 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5001 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
5005 /* Now unlink while open. */
5006 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5007 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5011 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5012 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5016 /* Ensure the file has gone. */
5017 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5018 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5022 /* Create again to test open with O_TRUNC. */
5023 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5024 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5028 /* Test ftruncate - set file size. */
5029 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5030 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5034 /* Ensure st_size == 1000 */
5035 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5036 printf("stat failed (%s)\n", cli_errstr(cli1));
5040 if (sbuf.st_ex_size != 1000) {
5041 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5045 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5046 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5050 /* Re-open with O_TRUNC. */
5051 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5052 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5056 /* Ensure st_size == 0 */
5057 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5058 printf("stat failed (%s)\n", cli_errstr(cli1));
5062 if (sbuf.st_ex_size != 0) {
5063 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5067 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5068 printf("close failed (%s)\n", cli_errstr(cli1));
5072 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5073 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5077 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5078 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5079 dname, cli_errstr(cli1));
5083 cli_close(cli1, fnum1);
5085 /* What happens when we try and POSIX open a directory for write ? */
5086 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5087 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5090 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5091 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5096 /* Create the file. */
5097 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5098 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5102 /* Write some data into it. */
5103 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5105 if (!NT_STATUS_IS_OK(status)) {
5106 printf("cli_write failed: %s\n", nt_errstr(status));
5110 cli_close(cli1, fnum1);
5112 /* Now create a hardlink. */
5113 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5114 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5118 /* Now create a symlink. */
5119 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5120 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5124 /* Open the hardlink for read. */
5125 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5126 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5130 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5131 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5135 if (memcmp(buf, "TEST DATA\n", 10)) {
5136 printf("invalid data read from hardlink\n");
5140 /* Do a POSIX lock/unlock. */
5141 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5142 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5146 /* Punch a hole in the locked area. */
5147 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5148 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5152 cli_close(cli1, fnum1);
5154 /* Open the symlink for read - this should fail. A POSIX
5155 client should not be doing opens on a symlink. */
5156 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5157 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5160 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5161 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5162 printf("POSIX open of %s should have failed "
5163 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5164 "failed with %s instead.\n",
5165 sname, cli_errstr(cli1));
5170 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5171 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5175 if (strcmp(namebuf, fname) != 0) {
5176 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5177 sname, fname, namebuf);
5181 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5182 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5186 printf("Simple POSIX open test passed\n");
5191 if (fnum1 != (uint16_t)-1) {
5192 cli_close(cli1, fnum1);
5193 fnum1 = (uint16_t)-1;
5196 cli_setatr(cli1, sname, 0, 0);
5197 cli_posix_unlink(cli1, sname);
5198 cli_setatr(cli1, hname, 0, 0);
5199 cli_posix_unlink(cli1, hname);
5200 cli_setatr(cli1, fname, 0, 0);
5201 cli_posix_unlink(cli1, fname);
5202 cli_setatr(cli1, dname, 0, 0);
5203 cli_posix_rmdir(cli1, dname);
5205 if (!torture_close_connection(cli1)) {
5213 static uint32 open_attrs_table[] = {
5214 FILE_ATTRIBUTE_NORMAL,
5215 FILE_ATTRIBUTE_ARCHIVE,
5216 FILE_ATTRIBUTE_READONLY,
5217 FILE_ATTRIBUTE_HIDDEN,
5218 FILE_ATTRIBUTE_SYSTEM,
5220 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5221 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5222 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5223 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5224 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5225 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5227 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5228 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5229 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5230 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5233 struct trunc_open_results {
5240 static struct trunc_open_results attr_results[] = {
5241 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5242 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5243 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5244 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5245 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5246 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5247 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5248 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5249 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5250 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5251 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5252 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5253 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5254 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5255 { 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 },
5256 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5257 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5258 { 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 },
5259 { 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 },
5260 { 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 },
5261 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5262 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5263 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5264 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5265 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5266 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5269 static bool run_openattrtest(int dummy)
5271 static struct cli_state *cli1;
5272 const char *fname = "\\openattr.file";
5274 bool correct = True;
5276 unsigned int i, j, k, l;
5278 printf("starting open attr test\n");
5280 if (!torture_open_connection(&cli1, 0)) {
5284 cli_sockopt(cli1, sockops);
5286 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5287 cli_setatr(cli1, fname, 0, 0);
5288 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5289 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5290 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5291 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5295 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5296 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5300 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5301 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5302 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5303 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5304 if (attr_results[l].num == k) {
5305 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5306 k, open_attrs_table[i],
5307 open_attrs_table[j],
5308 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5312 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5313 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5314 k, open_attrs_table[i], open_attrs_table[j],
5319 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5325 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5326 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5330 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5331 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5336 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5337 k, open_attrs_table[i], open_attrs_table[j], attr );
5340 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5341 if (attr_results[l].num == k) {
5342 if (attr != attr_results[l].result_attr ||
5343 open_attrs_table[i] != attr_results[l].init_attr ||
5344 open_attrs_table[j] != attr_results[l].trunc_attr) {
5345 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5346 open_attrs_table[i],
5347 open_attrs_table[j],
5349 attr_results[l].result_attr);
5359 cli_setatr(cli1, fname, 0, 0);
5360 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5362 printf("open attr test %s.\n", correct ? "passed" : "failed");
5364 if (!torture_close_connection(cli1)) {
5370 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5371 const char *name, void *state)
5373 int *matched = (int *)state;
5374 if (matched != NULL) {
5377 return NT_STATUS_OK;
5381 test directory listing speed
5383 static bool run_dirtest(int dummy)
5386 static struct cli_state *cli;
5388 struct timeval core_start;
5389 bool correct = True;
5392 printf("starting directory test\n");
5394 if (!torture_open_connection(&cli, 0)) {
5398 cli_sockopt(cli, sockops);
5401 for (i=0;i<torture_numops;i++) {
5403 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5404 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5405 fprintf(stderr,"Failed to open %s\n", fname);
5408 cli_close(cli, fnum);
5411 core_start = timeval_current();
5414 cli_list(cli, "a*.*", 0, list_fn, &matched);
5415 printf("Matched %d\n", matched);
5418 cli_list(cli, "b*.*", 0, list_fn, &matched);
5419 printf("Matched %d\n", matched);
5422 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5423 printf("Matched %d\n", matched);
5425 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5428 for (i=0;i<torture_numops;i++) {
5430 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5431 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5434 if (!torture_close_connection(cli)) {
5438 printf("finished dirtest\n");
5443 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5446 struct cli_state *pcli = (struct cli_state *)state;
5448 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5450 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5451 return NT_STATUS_OK;
5453 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5454 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5455 printf("del_fn: failed to rmdir %s\n,", fname );
5457 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5458 printf("del_fn: failed to unlink %s\n,", fname );
5460 return NT_STATUS_OK;
5465 sees what IOCTLs are supported
5467 bool torture_ioctl_test(int dummy)
5469 static struct cli_state *cli;
5470 uint16_t device, function;
5472 const char *fname = "\\ioctl.dat";
5476 if (!torture_open_connection(&cli, 0)) {
5480 printf("starting ioctl test\n");
5482 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5484 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5485 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5489 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5490 printf("ioctl device info: %s\n", nt_errstr(status));
5492 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5493 printf("ioctl job info: %s\n", nt_errstr(status));
5495 for (device=0;device<0x100;device++) {
5496 printf("ioctl test with device = 0x%x\n", device);
5497 for (function=0;function<0x100;function++) {
5498 uint32 code = (device<<16) | function;
5500 status = cli_raw_ioctl(cli, fnum, code, &blob);
5502 if (NT_STATUS_IS_OK(status)) {
5503 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5505 data_blob_free(&blob);
5510 if (!torture_close_connection(cli)) {
5519 tries varients of chkpath
5521 bool torture_chkpath_test(int dummy)
5523 static struct cli_state *cli;
5527 if (!torture_open_connection(&cli, 0)) {
5531 printf("starting chkpath test\n");
5533 /* cleanup from an old run */
5534 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5535 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5536 cli_rmdir(cli, "\\chkpath.dir");
5538 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5539 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5543 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5544 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5548 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5549 printf("open1 failed (%s)\n", cli_errstr(cli));
5552 cli_close(cli, fnum);
5554 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5555 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5559 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5560 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5564 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5565 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5566 NT_STATUS_NOT_A_DIRECTORY);
5568 printf("* chkpath on a file should fail\n");
5572 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5573 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5574 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5576 printf("* chkpath on a non existant file should fail\n");
5580 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5581 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5582 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5584 printf("* chkpath on a non existent component should fail\n");
5588 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5589 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5590 cli_rmdir(cli, "\\chkpath.dir");
5592 if (!torture_close_connection(cli)) {
5599 static bool run_eatest(int dummy)
5601 static struct cli_state *cli;
5602 const char *fname = "\\eatest.txt";
5603 bool correct = True;
5607 struct ea_struct *ea_list = NULL;
5608 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5611 printf("starting eatest\n");
5613 if (!torture_open_connection(&cli, 0)) {
5614 talloc_destroy(mem_ctx);
5618 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5619 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5620 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5621 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5622 0x4044, 0, &fnum))) {
5623 printf("open failed - %s\n", cli_errstr(cli));
5624 talloc_destroy(mem_ctx);
5628 for (i = 0; i < 10; i++) {
5629 fstring ea_name, ea_val;
5631 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5632 memset(ea_val, (char)i+1, i+1);
5633 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5634 if (!NT_STATUS_IS_OK(status)) {
5635 printf("ea_set of name %s failed - %s\n", ea_name,
5637 talloc_destroy(mem_ctx);
5642 cli_close(cli, fnum);
5643 for (i = 0; i < 10; i++) {
5644 fstring ea_name, ea_val;
5646 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5647 memset(ea_val, (char)i+1, i+1);
5648 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5649 if (!NT_STATUS_IS_OK(status)) {
5650 printf("ea_set of name %s failed - %s\n", ea_name,
5652 talloc_destroy(mem_ctx);
5657 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5658 if (!NT_STATUS_IS_OK(status)) {
5659 printf("ea_get list failed - %s\n", nt_errstr(status));
5663 printf("num_eas = %d\n", (int)num_eas);
5665 if (num_eas != 20) {
5666 printf("Should be 20 EA's stored... failing.\n");
5670 for (i = 0; i < num_eas; i++) {
5671 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5672 dump_data(0, ea_list[i].value.data,
5673 ea_list[i].value.length);
5676 /* Setting EA's to zero length deletes them. Test this */
5677 printf("Now deleting all EA's - case indepenent....\n");
5680 cli_set_ea_path(cli, fname, "", "", 0);
5682 for (i = 0; i < 20; i++) {
5684 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5685 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5686 if (!NT_STATUS_IS_OK(status)) {
5687 printf("ea_set of name %s failed - %s\n", ea_name,
5689 talloc_destroy(mem_ctx);
5695 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5696 if (!NT_STATUS_IS_OK(status)) {
5697 printf("ea_get list failed - %s\n", nt_errstr(status));
5701 printf("num_eas = %d\n", (int)num_eas);
5702 for (i = 0; i < num_eas; i++) {
5703 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5704 dump_data(0, ea_list[i].value.data,
5705 ea_list[i].value.length);
5709 printf("deleting EA's failed.\n");
5713 /* Try and delete a non existant EA. */
5714 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5715 if (!NT_STATUS_IS_OK(status)) {
5716 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5721 talloc_destroy(mem_ctx);
5722 if (!torture_close_connection(cli)) {
5729 static bool run_dirtest1(int dummy)
5732 static struct cli_state *cli;
5735 bool correct = True;
5737 printf("starting directory test\n");
5739 if (!torture_open_connection(&cli, 0)) {
5743 cli_sockopt(cli, sockops);
5745 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5746 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5747 cli_rmdir(cli, "\\LISTDIR");
5748 cli_mkdir(cli, "\\LISTDIR");
5750 /* Create 1000 files and 1000 directories. */
5751 for (i=0;i<1000;i++) {
5753 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5754 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5755 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5756 fprintf(stderr,"Failed to open %s\n", fname);
5759 cli_close(cli, fnum);
5761 for (i=0;i<1000;i++) {
5763 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5764 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5765 fprintf(stderr,"Failed to open %s\n", fname);
5770 /* Now ensure that doing an old list sees both files and directories. */
5772 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5773 printf("num_seen = %d\n", num_seen );
5774 /* We should see 100 files + 1000 directories + . and .. */
5775 if (num_seen != 2002)
5778 /* Ensure if we have the "must have" bits we only see the
5782 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5783 printf("num_seen = %d\n", num_seen );
5784 if (num_seen != 1002)
5788 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5789 printf("num_seen = %d\n", num_seen );
5790 if (num_seen != 1000)
5793 /* Delete everything. */
5794 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5795 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5796 cli_rmdir(cli, "\\LISTDIR");
5799 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5800 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5801 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5804 if (!torture_close_connection(cli)) {
5808 printf("finished dirtest1\n");
5813 static bool run_error_map_extract(int dummy) {
5815 static struct cli_state *c_dos;
5816 static struct cli_state *c_nt;
5821 uint32 flgs2, errnum;
5828 /* NT-Error connection */
5830 if (!(c_nt = open_nbt_connection())) {
5834 c_nt->use_spnego = False;
5836 status = cli_negprot(c_nt);
5838 if (!NT_STATUS_IS_OK(status)) {
5839 printf("%s rejected the NT-error negprot (%s)\n", host,
5845 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5847 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5851 /* DOS-Error connection */
5853 if (!(c_dos = open_nbt_connection())) {
5857 c_dos->use_spnego = False;
5858 c_dos->force_dos_errors = True;
5860 status = cli_negprot(c_dos);
5861 if (!NT_STATUS_IS_OK(status)) {
5862 printf("%s rejected the DOS-error negprot (%s)\n", host,
5864 cli_shutdown(c_dos);
5868 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5870 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5874 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5875 fstr_sprintf(user, "%X", error);
5877 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5878 password, strlen(password),
5879 password, strlen(password),
5881 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5884 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5886 /* Case #1: 32-bit NT errors */
5887 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5888 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5890 printf("/** Dos error on NT connection! (%s) */\n",
5892 nt_status = NT_STATUS(0xc0000000);
5895 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5896 password, strlen(password),
5897 password, strlen(password),
5899 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5901 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5903 /* Case #1: 32-bit NT errors */
5904 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5905 printf("/** NT error on DOS connection! (%s) */\n",
5907 errnum = errclass = 0;
5909 cli_dos_error(c_dos, &errclass, &errnum);
5912 if (NT_STATUS_V(nt_status) != error) {
5913 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5914 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
5915 get_nt_error_c_code(talloc_tos(), nt_status));
5918 printf("\t{%s,\t%s,\t%s},\n",
5919 smb_dos_err_class(errclass),
5920 smb_dos_err_name(errclass, errnum),
5921 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
5926 static bool run_sesssetup_bench(int dummy)
5928 static struct cli_state *c;
5929 const char *fname = "\\file.dat";
5934 if (!torture_open_connection(&c, 0)) {
5938 if (!NT_STATUS_IS_OK(cli_ntcreate(
5939 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5940 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5941 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5942 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5946 for (i=0; i<torture_numops; i++) {
5947 status = cli_session_setup(
5949 password, strlen(password),
5950 password, strlen(password),
5952 if (!NT_STATUS_IS_OK(status)) {
5953 d_printf("(%s) cli_session_setup failed: %s\n",
5954 __location__, nt_errstr(status));
5958 d_printf("\r%d ", (int)c->vuid);
5960 status = cli_ulogoff(c);
5961 if (!NT_STATUS_IS_OK(status)) {
5962 d_printf("(%s) cli_ulogoff failed: %s\n",
5963 __location__, nt_errstr(status));
5972 static bool subst_test(const char *str, const char *user, const char *domain,
5973 uid_t uid, gid_t gid, const char *expected)
5978 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5980 if (strcmp(subst, expected) != 0) {
5981 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5982 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5991 static void chain1_open_completion(struct tevent_req *req)
5995 status = cli_open_recv(req, &fnum);
5998 d_printf("cli_open_recv returned %s: %d\n",
6000 NT_STATUS_IS_OK(status) ? fnum : -1);
6003 static void chain1_write_completion(struct tevent_req *req)
6007 status = cli_write_andx_recv(req, &written);
6010 d_printf("cli_write_andx_recv returned %s: %d\n",
6012 NT_STATUS_IS_OK(status) ? (int)written : -1);
6015 static void chain1_close_completion(struct tevent_req *req)
6018 bool *done = (bool *)tevent_req_callback_data_void(req);
6020 status = cli_close_recv(req);
6025 d_printf("cli_close returned %s\n", nt_errstr(status));
6028 static bool run_chain1(int dummy)
6030 struct cli_state *cli1;
6031 struct event_context *evt = event_context_init(NULL);
6032 struct tevent_req *reqs[3], *smbreqs[3];
6034 const char *str = "foobar";
6037 printf("starting chain1 test\n");
6038 if (!torture_open_connection(&cli1, 0)) {
6042 cli_sockopt(cli1, sockops);
6044 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6045 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6046 if (reqs[0] == NULL) return false;
6047 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6050 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6051 (const uint8_t *)str, 0, strlen(str)+1,
6052 smbreqs, 1, &smbreqs[1]);
6053 if (reqs[1] == NULL) return false;
6054 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6056 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6057 if (reqs[2] == NULL) return false;
6058 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6060 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6061 if (!NT_STATUS_IS_OK(status)) {
6066 event_loop_once(evt);
6069 torture_close_connection(cli1);
6073 static void chain2_sesssetup_completion(struct tevent_req *req)
6076 status = cli_session_setup_guest_recv(req);
6077 d_printf("sesssetup returned %s\n", nt_errstr(status));
6080 static void chain2_tcon_completion(struct tevent_req *req)
6082 bool *done = (bool *)tevent_req_callback_data_void(req);
6084 status = cli_tcon_andx_recv(req);
6085 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6089 static bool run_chain2(int dummy)
6091 struct cli_state *cli1;
6092 struct event_context *evt = event_context_init(NULL);
6093 struct tevent_req *reqs[2], *smbreqs[2];
6097 printf("starting chain2 test\n");
6098 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6099 port_to_use, Undefined, 0);
6100 if (!NT_STATUS_IS_OK(status)) {
6104 cli_sockopt(cli1, sockops);
6106 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6108 if (reqs[0] == NULL) return false;
6109 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6111 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6112 "?????", NULL, 0, &smbreqs[1]);
6113 if (reqs[1] == NULL) return false;
6114 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6116 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6117 if (!NT_STATUS_IS_OK(status)) {
6122 event_loop_once(evt);
6125 torture_close_connection(cli1);
6130 struct torture_createdel_state {
6131 struct tevent_context *ev;
6132 struct cli_state *cli;
6135 static void torture_createdel_created(struct tevent_req *subreq);
6136 static void torture_createdel_closed(struct tevent_req *subreq);
6138 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6139 struct tevent_context *ev,
6140 struct cli_state *cli,
6143 struct tevent_req *req, *subreq;
6144 struct torture_createdel_state *state;
6146 req = tevent_req_create(mem_ctx, &state,
6147 struct torture_createdel_state);
6154 subreq = cli_ntcreate_send(
6155 state, ev, cli, name, 0,
6156 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6157 FILE_ATTRIBUTE_NORMAL,
6158 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6159 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6161 if (tevent_req_nomem(subreq, req)) {
6162 return tevent_req_post(req, ev);
6164 tevent_req_set_callback(subreq, torture_createdel_created, req);
6168 static void torture_createdel_created(struct tevent_req *subreq)
6170 struct tevent_req *req = tevent_req_callback_data(
6171 subreq, struct tevent_req);
6172 struct torture_createdel_state *state = tevent_req_data(
6173 req, struct torture_createdel_state);
6177 status = cli_ntcreate_recv(subreq, &fnum);
6178 TALLOC_FREE(subreq);
6179 if (!NT_STATUS_IS_OK(status)) {
6180 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6181 nt_errstr(status)));
6182 tevent_req_nterror(req, status);
6186 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6187 if (tevent_req_nomem(subreq, req)) {
6190 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6193 static void torture_createdel_closed(struct tevent_req *subreq)
6195 struct tevent_req *req = tevent_req_callback_data(
6196 subreq, struct tevent_req);
6199 status = cli_close_recv(subreq);
6200 if (!NT_STATUS_IS_OK(status)) {
6201 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6202 tevent_req_nterror(req, status);
6205 tevent_req_done(req);
6208 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6210 return tevent_req_simple_recv_ntstatus(req);
6213 struct torture_createdels_state {
6214 struct tevent_context *ev;
6215 struct cli_state *cli;
6216 const char *base_name;
6220 struct tevent_req **reqs;
6223 static void torture_createdels_done(struct tevent_req *subreq);
6225 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6226 struct tevent_context *ev,
6227 struct cli_state *cli,
6228 const char *base_name,
6232 struct tevent_req *req;
6233 struct torture_createdels_state *state;
6236 req = tevent_req_create(mem_ctx, &state,
6237 struct torture_createdels_state);
6243 state->base_name = talloc_strdup(state, base_name);
6244 if (tevent_req_nomem(state->base_name, req)) {
6245 return tevent_req_post(req, ev);
6247 state->num_files = MAX(num_parallel, num_files);
6249 state->received = 0;
6251 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6252 if (tevent_req_nomem(state->reqs, req)) {
6253 return tevent_req_post(req, ev);
6256 for (i=0; i<num_parallel; i++) {
6259 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6261 if (tevent_req_nomem(name, req)) {
6262 return tevent_req_post(req, ev);
6264 state->reqs[i] = torture_createdel_send(
6265 state->reqs, state->ev, state->cli, name);
6266 if (tevent_req_nomem(state->reqs[i], req)) {
6267 return tevent_req_post(req, ev);
6269 name = talloc_move(state->reqs[i], &name);
6270 tevent_req_set_callback(state->reqs[i],
6271 torture_createdels_done, req);
6277 static void torture_createdels_done(struct tevent_req *subreq)
6279 struct tevent_req *req = tevent_req_callback_data(
6280 subreq, struct tevent_req);
6281 struct torture_createdels_state *state = tevent_req_data(
6282 req, struct torture_createdels_state);
6283 size_t num_parallel = talloc_array_length(state->reqs);
6288 status = torture_createdel_recv(subreq);
6289 if (!NT_STATUS_IS_OK(status)){
6290 DEBUG(10, ("torture_createdel_recv returned %s\n",
6291 nt_errstr(status)));
6292 TALLOC_FREE(subreq);
6293 tevent_req_nterror(req, status);
6297 for (i=0; i<num_parallel; i++) {
6298 if (subreq == state->reqs[i]) {
6302 if (i == num_parallel) {
6303 DEBUG(10, ("received something we did not send\n"));
6304 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6307 TALLOC_FREE(state->reqs[i]);
6309 if (state->sent >= state->num_files) {
6310 tevent_req_done(req);
6314 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6316 if (tevent_req_nomem(name, req)) {
6319 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6321 if (tevent_req_nomem(state->reqs[i], req)) {
6324 name = talloc_move(state->reqs[i], &name);
6325 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6329 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6331 return tevent_req_simple_recv_ntstatus(req);
6334 struct swallow_notify_state {
6335 struct tevent_context *ev;
6336 struct cli_state *cli;
6338 uint32_t completion_filter;
6340 bool (*fn)(uint32_t action, const char *name, void *priv);
6344 static void swallow_notify_done(struct tevent_req *subreq);
6346 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6347 struct tevent_context *ev,
6348 struct cli_state *cli,
6350 uint32_t completion_filter,
6352 bool (*fn)(uint32_t action,
6357 struct tevent_req *req, *subreq;
6358 struct swallow_notify_state *state;
6360 req = tevent_req_create(mem_ctx, &state,
6361 struct swallow_notify_state);
6368 state->completion_filter = completion_filter;
6369 state->recursive = recursive;
6373 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6374 0xffff, state->completion_filter,
6376 if (tevent_req_nomem(subreq, req)) {
6377 return tevent_req_post(req, ev);
6379 tevent_req_set_callback(subreq, swallow_notify_done, req);
6383 static void swallow_notify_done(struct tevent_req *subreq)
6385 struct tevent_req *req = tevent_req_callback_data(
6386 subreq, struct tevent_req);
6387 struct swallow_notify_state *state = tevent_req_data(
6388 req, struct swallow_notify_state);
6390 uint32_t i, num_changes;
6391 struct notify_change *changes;
6393 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6394 TALLOC_FREE(subreq);
6395 if (!NT_STATUS_IS_OK(status)) {
6396 DEBUG(10, ("cli_notify_recv returned %s\n",
6397 nt_errstr(status)));
6398 tevent_req_nterror(req, status);
6402 for (i=0; i<num_changes; i++) {
6403 state->fn(changes[i].action, changes[i].name, state->priv);
6405 TALLOC_FREE(changes);
6407 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6408 0xffff, state->completion_filter,
6410 if (tevent_req_nomem(subreq, req)) {
6413 tevent_req_set_callback(subreq, swallow_notify_done, req);
6416 static bool print_notifies(uint32_t action, const char *name, void *priv)
6418 if (DEBUGLEVEL > 5) {
6419 d_printf("%d %s\n", (int)action, name);
6424 static void notify_bench_done(struct tevent_req *req)
6426 int *num_finished = (int *)tevent_req_callback_data_void(req);
6430 static bool run_notify_bench(int dummy)
6432 const char *dname = "\\notify-bench";
6433 struct tevent_context *ev;
6436 struct tevent_req *req1;
6437 struct tevent_req *req2 = NULL;
6438 int i, num_unc_names;
6439 int num_finished = 0;
6441 printf("starting notify-bench test\n");
6443 if (use_multishare_conn) {
6445 unc_list = file_lines_load(multishare_conn_fname,
6446 &num_unc_names, 0, NULL);
6447 if (!unc_list || num_unc_names <= 0) {
6448 d_printf("Failed to load unc names list from '%s'\n",
6449 multishare_conn_fname);
6452 TALLOC_FREE(unc_list);
6457 ev = tevent_context_init(talloc_tos());
6459 d_printf("tevent_context_init failed\n");
6463 for (i=0; i<num_unc_names; i++) {
6464 struct cli_state *cli;
6467 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6469 if (base_fname == NULL) {
6473 if (!torture_open_connection(&cli, i)) {
6477 status = cli_ntcreate(cli, dname, 0,
6478 MAXIMUM_ALLOWED_ACCESS,
6479 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6481 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6484 if (!NT_STATUS_IS_OK(status)) {
6485 d_printf("Could not create %s: %s\n", dname,
6490 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6491 FILE_NOTIFY_CHANGE_FILE_NAME |
6492 FILE_NOTIFY_CHANGE_DIR_NAME |
6493 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6494 FILE_NOTIFY_CHANGE_LAST_WRITE,
6495 false, print_notifies, NULL);
6497 d_printf("Could not create notify request\n");
6501 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6502 base_fname, 10, torture_numops);
6504 d_printf("Could not create createdels request\n");
6507 TALLOC_FREE(base_fname);
6509 tevent_req_set_callback(req2, notify_bench_done,
6513 while (num_finished < num_unc_names) {
6515 ret = tevent_loop_once(ev);
6517 d_printf("tevent_loop_once failed\n");
6522 if (!tevent_req_poll(req2, ev)) {
6523 d_printf("tevent_req_poll failed\n");
6526 status = torture_createdels_recv(req2);
6527 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6532 static bool run_mangle1(int dummy)
6534 struct cli_state *cli;
6535 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6539 time_t change_time, access_time, write_time;
6543 printf("starting mangle1 test\n");
6544 if (!torture_open_connection(&cli, 0)) {
6548 cli_sockopt(cli, sockops);
6550 if (!NT_STATUS_IS_OK(cli_ntcreate(
6551 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6552 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6553 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6556 cli_close(cli, fnum);
6558 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6559 if (!NT_STATUS_IS_OK(status)) {
6560 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6564 d_printf("alt_name: %s\n", alt_name);
6566 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6567 d_printf("cli_open(%s) failed: %s\n", alt_name,
6571 cli_close(cli, fnum);
6573 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6574 &write_time, &size, &mode);
6575 if (!NT_STATUS_IS_OK(status)) {
6576 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6584 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6586 size_t *to_pull = (size_t *)priv;
6587 size_t thistime = *to_pull;
6589 thistime = MIN(thistime, n);
6590 if (thistime == 0) {
6594 memset(buf, 0, thistime);
6595 *to_pull -= thistime;
6599 static bool run_windows_write(int dummy)
6601 struct cli_state *cli1;
6605 const char *fname = "\\writetest.txt";
6606 struct timeval start_time;
6610 printf("starting windows_write test\n");
6611 if (!torture_open_connection(&cli1, 0)) {
6615 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6616 printf("open failed (%s)\n", cli_errstr(cli1));
6620 cli_sockopt(cli1, sockops);
6622 start_time = timeval_current();
6624 for (i=0; i<torture_numops; i++) {
6626 off_t start = i * torture_blocksize;
6628 size_t to_pull = torture_blocksize - 1;
6630 status = cli_writeall(cli1, fnum, 0, &c,
6631 start + torture_blocksize - 1, 1, NULL);
6632 if (!NT_STATUS_IS_OK(status)) {
6633 printf("cli_write failed: %s\n", nt_errstr(status));
6637 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6638 null_source, &to_pull);
6639 if (!NT_STATUS_IS_OK(status)) {
6640 printf("cli_push returned: %s\n", nt_errstr(status));
6645 seconds = timeval_elapsed(&start_time);
6646 kbytes = (double)torture_blocksize * torture_numops;
6649 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6650 (double)seconds, (int)(kbytes/seconds));
6654 cli_close(cli1, fnum);
6655 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6656 torture_close_connection(cli1);
6660 static bool run_cli_echo(int dummy)
6662 struct cli_state *cli;
6665 printf("starting cli_echo test\n");
6666 if (!torture_open_connection(&cli, 0)) {
6669 cli_sockopt(cli, sockops);
6671 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6673 d_printf("cli_echo returned %s\n", nt_errstr(status));
6675 torture_close_connection(cli);
6676 return NT_STATUS_IS_OK(status);
6679 static bool run_uid_regression_test(int dummy)
6681 static struct cli_state *cli;
6684 bool correct = True;
6687 printf("starting uid regression test\n");
6689 if (!torture_open_connection(&cli, 0)) {
6693 cli_sockopt(cli, sockops);
6695 /* Ok - now save then logoff our current user. */
6696 old_vuid = cli->vuid;
6698 status = cli_ulogoff(cli);
6699 if (!NT_STATUS_IS_OK(status)) {
6700 d_printf("(%s) cli_ulogoff failed: %s\n",
6701 __location__, nt_errstr(status));
6706 cli->vuid = old_vuid;
6708 /* Try an operation. */
6709 status = cli_mkdir(cli, "\\uid_reg_test");
6710 if (NT_STATUS_IS_OK(status)) {
6711 d_printf("(%s) cli_mkdir succeeded\n",
6716 /* Should be bad uid. */
6717 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6718 NT_STATUS_USER_SESSION_DELETED)) {
6724 old_cnum = cli->cnum;
6726 /* Now try a SMBtdis with the invald vuid set to zero. */
6729 /* This should succeed. */
6730 status = cli_tdis(cli);
6732 if (NT_STATUS_IS_OK(status)) {
6733 d_printf("First tdis with invalid vuid should succeed.\n");
6735 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6740 cli->vuid = old_vuid;
6741 cli->cnum = old_cnum;
6743 /* This should fail. */
6744 status = cli_tdis(cli);
6745 if (NT_STATUS_IS_OK(status)) {
6746 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6750 /* Should be bad tid. */
6751 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6752 NT_STATUS_NETWORK_NAME_DELETED)) {
6758 cli_rmdir(cli, "\\uid_reg_test");
6767 static const char *illegal_chars = "*\\/?<>|\":";
6768 static char force_shortname_chars[] = " +,.[];=\177";
6770 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6771 const char *mask, void *state)
6773 struct cli_state *pcli = (struct cli_state *)state;
6775 NTSTATUS status = NT_STATUS_OK;
6777 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6779 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6780 return NT_STATUS_OK;
6782 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6783 status = cli_rmdir(pcli, fname);
6784 if (!NT_STATUS_IS_OK(status)) {
6785 printf("del_fn: failed to rmdir %s\n,", fname );
6788 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6789 if (!NT_STATUS_IS_OK(status)) {
6790 printf("del_fn: failed to unlink %s\n,", fname );
6802 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6803 const char *name, void *state)
6805 struct sn_state *s = (struct sn_state *)state;
6809 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6810 i, finfo->name, finfo->short_name);
6813 if (strchr(force_shortname_chars, i)) {
6814 if (!finfo->short_name[0]) {
6815 /* Shortname not created when it should be. */
6816 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6817 __location__, finfo->name, i);
6820 } else if (finfo->short_name[0]){
6821 /* Shortname created when it should not be. */
6822 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6823 __location__, finfo->short_name, finfo->name);
6827 return NT_STATUS_OK;
6830 static bool run_shortname_test(int dummy)
6832 static struct cli_state *cli;
6833 bool correct = True;
6838 printf("starting shortname test\n");
6840 if (!torture_open_connection(&cli, 0)) {
6844 cli_sockopt(cli, sockops);
6846 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6847 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6848 cli_rmdir(cli, "\\shortname");
6850 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6851 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6852 __location__, cli_errstr(cli));
6857 strlcpy(fname, "\\shortname\\", sizeof(fname));
6858 strlcat(fname, "test .txt", sizeof(fname));
6862 for (i = 32; i < 128; i++) {
6864 uint16_t fnum = (uint16_t)-1;
6868 if (strchr(illegal_chars, i)) {
6873 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6874 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6875 if (!NT_STATUS_IS_OK(status)) {
6876 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6877 __location__, fname, cli_errstr(cli));
6881 cli_close(cli, fnum);
6884 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6886 if (s.matched != 1) {
6887 d_printf("(%s) failed to list %s: %s\n",
6888 __location__, fname, cli_errstr(cli));
6892 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6893 d_printf("(%s) failed to delete %s: %s\n",
6894 __location__, fname, cli_errstr(cli));
6907 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6908 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6909 cli_rmdir(cli, "\\shortname");
6910 torture_close_connection(cli);
6914 static void pagedsearch_cb(struct tevent_req *req)
6917 struct tldap_message *msg;
6920 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6921 if (rc != TLDAP_SUCCESS) {
6922 d_printf("tldap_search_paged_recv failed: %s\n",
6923 tldap_err2string(rc));
6926 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6930 if (!tldap_entry_dn(msg, &dn)) {
6931 d_printf("tldap_entry_dn failed\n");
6934 d_printf("%s\n", dn);
6938 static bool run_tldap(int dummy)
6940 struct tldap_context *ld;
6943 struct sockaddr_storage addr;
6944 struct tevent_context *ev;
6945 struct tevent_req *req;
6949 if (!resolve_name(host, &addr, 0, false)) {
6950 d_printf("could not find host %s\n", host);
6953 status = open_socket_out(&addr, 389, 9999, &fd);
6954 if (!NT_STATUS_IS_OK(status)) {
6955 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6959 ld = tldap_context_create(talloc_tos(), fd);
6962 d_printf("tldap_context_create failed\n");
6966 rc = tldap_fetch_rootdse(ld);
6967 if (rc != TLDAP_SUCCESS) {
6968 d_printf("tldap_fetch_rootdse failed: %s\n",
6969 tldap_errstr(talloc_tos(), ld, rc));
6973 basedn = tldap_talloc_single_attribute(
6974 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6975 if (basedn == NULL) {
6976 d_printf("no defaultNamingContext\n");
6979 d_printf("defaultNamingContext: %s\n", basedn);
6981 ev = tevent_context_init(talloc_tos());
6983 d_printf("tevent_context_init failed\n");
6987 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6988 TLDAP_SCOPE_SUB, "(objectclass=*)",
6990 NULL, 0, NULL, 0, 0, 0, 0, 5);
6992 d_printf("tldap_search_paged_send failed\n");
6995 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6997 tevent_req_poll(req, ev);
7001 /* test search filters against rootDSE */
7002 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7003 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7005 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7006 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7007 talloc_tos(), NULL, NULL);
7008 if (rc != TLDAP_SUCCESS) {
7009 d_printf("tldap_search with complex filter failed: %s\n",
7010 tldap_errstr(talloc_tos(), ld, rc));
7018 /* Torture test to ensure no regression of :
7019 https://bugzilla.samba.org/show_bug.cgi?id=7084
7022 static bool run_dir_createtime(int dummy)
7024 struct cli_state *cli;
7025 const char *dname = "\\testdir";
7026 const char *fname = "\\testdir\\testfile";
7028 struct timespec create_time;
7029 struct timespec create_time1;
7033 if (!torture_open_connection(&cli, 0)) {
7037 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7038 cli_rmdir(cli, dname);
7040 status = cli_mkdir(cli, dname);
7041 if (!NT_STATUS_IS_OK(status)) {
7042 printf("mkdir failed: %s\n", nt_errstr(status));
7046 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7048 if (!NT_STATUS_IS_OK(status)) {
7049 printf("cli_qpathinfo2 returned %s\n",
7054 /* Sleep 3 seconds, then create a file. */
7057 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7059 if (!NT_STATUS_IS_OK(status)) {
7060 printf("cli_open failed: %s\n", nt_errstr(status));
7064 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7066 if (!NT_STATUS_IS_OK(status)) {
7067 printf("cli_qpathinfo2 (2) returned %s\n",
7072 if (timespec_compare(&create_time1, &create_time)) {
7073 printf("run_dir_createtime: create time was updated (error)\n");
7075 printf("run_dir_createtime: create time was not updated (correct)\n");
7081 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7082 cli_rmdir(cli, dname);
7083 if (!torture_close_connection(cli)) {
7090 static bool run_streamerror(int dummy)
7092 struct cli_state *cli;
7093 const char *dname = "\\testdir";
7094 const char *streamname =
7095 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7097 time_t change_time, access_time, write_time;
7099 uint16_t mode, fnum;
7102 if (!torture_open_connection(&cli, 0)) {
7106 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7107 cli_rmdir(cli, dname);
7109 status = cli_mkdir(cli, dname);
7110 if (!NT_STATUS_IS_OK(status)) {
7111 printf("mkdir failed: %s\n", nt_errstr(status));
7115 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7117 status = cli_nt_error(cli);
7119 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7120 printf("pathinfo returned %s, expected "
7121 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7126 status = cli_ntcreate(cli, streamname, 0x16,
7127 FILE_READ_DATA|FILE_READ_EA|
7128 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7129 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7130 FILE_OPEN, 0, 0, &fnum);
7132 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7133 printf("ntcreate returned %s, expected "
7134 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7140 cli_rmdir(cli, dname);
7144 static bool run_local_substitute(int dummy)
7148 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7149 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7150 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7151 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7152 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7153 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7154 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7155 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7157 /* Different captialization rules in sub_basic... */
7159 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7165 static bool run_local_base64(int dummy)
7170 for (i=1; i<2000; i++) {
7171 DATA_BLOB blob1, blob2;
7174 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7176 generate_random_buffer(blob1.data, blob1.length);
7178 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7180 d_fprintf(stderr, "base64_encode_data_blob failed "
7181 "for %d bytes\n", i);
7184 blob2 = base64_decode_data_blob(b64);
7187 if (data_blob_cmp(&blob1, &blob2)) {
7188 d_fprintf(stderr, "data_blob_cmp failed for %d "
7192 TALLOC_FREE(blob1.data);
7193 data_blob_free(&blob2);
7198 static bool run_local_gencache(int dummy)
7204 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7205 d_printf("%s: gencache_set() failed\n", __location__);
7209 if (!gencache_get("foo", NULL, NULL)) {
7210 d_printf("%s: gencache_get() failed\n", __location__);
7214 if (!gencache_get("foo", &val, &tm)) {
7215 d_printf("%s: gencache_get() failed\n", __location__);
7219 if (strcmp(val, "bar") != 0) {
7220 d_printf("%s: gencache_get() returned %s, expected %s\n",
7221 __location__, val, "bar");
7228 if (!gencache_del("foo")) {
7229 d_printf("%s: gencache_del() failed\n", __location__);
7232 if (gencache_del("foo")) {
7233 d_printf("%s: second gencache_del() succeeded\n",
7238 if (gencache_get("foo", &val, &tm)) {
7239 d_printf("%s: gencache_get() on deleted entry "
7240 "succeeded\n", __location__);
7244 blob = data_blob_string_const_null("bar");
7245 tm = time(NULL) + 60;
7247 if (!gencache_set_data_blob("foo", &blob, tm)) {
7248 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7252 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7253 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7257 if (strcmp((const char *)blob.data, "bar") != 0) {
7258 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7259 __location__, (const char *)blob.data, "bar");
7260 data_blob_free(&blob);
7264 data_blob_free(&blob);
7266 if (!gencache_del("foo")) {
7267 d_printf("%s: gencache_del() failed\n", __location__);
7270 if (gencache_del("foo")) {
7271 d_printf("%s: second gencache_del() succeeded\n",
7276 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7277 d_printf("%s: gencache_get_data_blob() on deleted entry "
7278 "succeeded\n", __location__);
7285 static bool rbt_testval(struct db_context *db, const char *key,
7288 struct db_record *rec;
7289 TDB_DATA data = string_tdb_data(value);
7293 rec = db->fetch_locked(db, db, string_tdb_data(key));
7295 d_fprintf(stderr, "fetch_locked failed\n");
7298 status = rec->store(rec, data, 0);
7299 if (!NT_STATUS_IS_OK(status)) {
7300 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7305 rec = db->fetch_locked(db, db, string_tdb_data(key));
7307 d_fprintf(stderr, "second fetch_locked failed\n");
7310 if ((rec->value.dsize != data.dsize)
7311 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7312 d_fprintf(stderr, "Got wrong data back\n");
7322 static bool run_local_rbtree(int dummy)
7324 struct db_context *db;
7328 db = db_open_rbt(NULL);
7331 d_fprintf(stderr, "db_open_rbt failed\n");
7335 for (i=0; i<1000; i++) {
7338 if (asprintf(&key, "key%ld", random()) == -1) {
7341 if (asprintf(&value, "value%ld", random()) == -1) {
7346 if (!rbt_testval(db, key, value)) {
7353 if (asprintf(&value, "value%ld", random()) == -1) {
7358 if (!rbt_testval(db, key, value)) {
7377 local test for character set functions
7379 This is a very simple test for the functionality in convert_string_error()
7381 static bool run_local_convert_string(int dummy)
7383 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7384 const char *test_strings[2] = { "March", "M\303\244rz" };
7388 for (i=0; i<2; i++) {
7389 const char *str = test_strings[i];
7390 int len = strlen(str);
7391 size_t converted_size;
7394 memset(dst, 'X', sizeof(dst));
7396 /* first try with real source length */
7397 ret = convert_string_error(CH_UNIX, CH_UTF8,
7402 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7406 if (converted_size != len) {
7407 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7408 str, len, (int)converted_size);
7412 if (strncmp(str, dst, converted_size) != 0) {
7413 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7417 if (strlen(str) != converted_size) {
7418 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7419 (int)strlen(str), (int)converted_size);
7423 if (dst[converted_size] != 'X') {
7424 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7428 /* now with srclen==-1, this causes the nul to be
7430 ret = convert_string_error(CH_UNIX, CH_UTF8,
7435 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7439 if (converted_size != len+1) {
7440 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7441 str, len, (int)converted_size);
7445 if (strncmp(str, dst, converted_size) != 0) {
7446 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7450 if (len+1 != converted_size) {
7451 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7452 len+1, (int)converted_size);
7456 if (dst[converted_size] != 'X') {
7457 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7464 TALLOC_FREE(tmp_ctx);
7467 TALLOC_FREE(tmp_ctx);
7472 struct talloc_dict_test {
7476 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7478 int *count = (int *)priv;
7483 static bool run_local_talloc_dict(int dummy)
7485 struct talloc_dict *dict;
7486 struct talloc_dict_test *t;
7489 dict = talloc_dict_init(talloc_tos());
7494 t = talloc(talloc_tos(), struct talloc_dict_test);
7501 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7506 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7519 static bool run_local_string_to_sid(int dummy) {
7522 if (string_to_sid(&sid, "S--1-5-32-545")) {
7523 printf("allowing S--1-5-32-545\n");
7526 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7527 printf("allowing S-1-5-32-+545\n");
7530 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")) {
7531 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7534 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7535 printf("allowing S-1-5-32-545-abc\n");
7538 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7539 printf("could not parse S-1-5-32-545\n");
7542 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7543 printf("mis-parsed S-1-5-32-545 as %s\n",
7544 sid_string_tos(&sid));
7550 static bool run_local_binary_to_sid(int dummy) {
7551 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7552 static const char good_binary_sid[] = {
7553 0x1, /* revision number */
7555 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7556 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7557 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7558 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7559 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7560 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7561 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7562 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7563 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7564 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7565 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7566 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7567 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7568 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7569 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7570 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7573 static const char long_binary_sid[] = {
7574 0x1, /* revision number */
7576 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7577 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7578 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7579 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7580 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7581 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7582 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7583 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7584 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7585 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7586 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7587 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7588 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7589 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7590 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7591 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7592 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7593 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7594 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7597 static const char long_binary_sid2[] = {
7598 0x1, /* revision number */
7600 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7601 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7602 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7603 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7604 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7605 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7606 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7607 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7608 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7609 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7610 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7611 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7612 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7613 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7614 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7615 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7616 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7617 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7618 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7619 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7620 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7621 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7622 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7623 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7624 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7625 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7626 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7627 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7628 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7629 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7630 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7631 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7632 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7635 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7638 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7641 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7647 /* Split a path name into filename and stream name components. Canonicalise
7648 * such that an implicit $DATA token is always explicit.
7650 * The "specification" of this function can be found in the
7651 * run_local_stream_name() function in torture.c, I've tried those
7652 * combinations against a W2k3 server.
7655 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7656 char **pbase, char **pstream)
7659 char *stream = NULL;
7660 char *sname; /* stream name */
7661 const char *stype; /* stream type */
7663 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7665 sname = strchr_m(fname, ':');
7667 if (lp_posix_pathnames() || (sname == NULL)) {
7668 if (pbase != NULL) {
7669 base = talloc_strdup(mem_ctx, fname);
7670 NT_STATUS_HAVE_NO_MEMORY(base);
7675 if (pbase != NULL) {
7676 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7677 NT_STATUS_HAVE_NO_MEMORY(base);
7682 stype = strchr_m(sname, ':');
7684 if (stype == NULL) {
7685 sname = talloc_strdup(mem_ctx, sname);
7689 if (StrCaseCmp(stype, ":$DATA") != 0) {
7691 * If there is an explicit stream type, so far we only
7692 * allow $DATA. Is there anything else allowed? -- vl
7694 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7696 return NT_STATUS_OBJECT_NAME_INVALID;
7698 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7702 if (sname == NULL) {
7704 return NT_STATUS_NO_MEMORY;
7707 if (sname[0] == '\0') {
7709 * no stream name, so no stream
7714 if (pstream != NULL) {
7715 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7716 if (stream == NULL) {
7719 return NT_STATUS_NO_MEMORY;
7722 * upper-case the type field
7724 strupper_m(strchr_m(stream, ':')+1);
7728 if (pbase != NULL) {
7731 if (pstream != NULL) {
7734 return NT_STATUS_OK;
7737 static bool test_stream_name(const char *fname, const char *expected_base,
7738 const char *expected_stream,
7739 NTSTATUS expected_status)
7743 char *stream = NULL;
7745 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7746 if (!NT_STATUS_EQUAL(status, expected_status)) {
7750 if (!NT_STATUS_IS_OK(status)) {
7754 if (base == NULL) goto error;
7756 if (strcmp(expected_base, base) != 0) goto error;
7758 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7759 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7761 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7765 TALLOC_FREE(stream);
7769 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7770 fname, expected_base ? expected_base : "<NULL>",
7771 expected_stream ? expected_stream : "<NULL>",
7772 nt_errstr(expected_status));
7773 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7774 base ? base : "<NULL>", stream ? stream : "<NULL>",
7777 TALLOC_FREE(stream);
7781 static bool run_local_stream_name(int dummy)
7785 ret &= test_stream_name(
7786 "bla", "bla", NULL, NT_STATUS_OK);
7787 ret &= test_stream_name(
7788 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7789 ret &= test_stream_name(
7790 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7791 ret &= test_stream_name(
7792 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7793 ret &= test_stream_name(
7794 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7795 ret &= test_stream_name(
7796 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7797 ret &= test_stream_name(
7798 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7799 ret &= test_stream_name(
7800 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7805 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7807 if (a.length != b.length) {
7808 printf("a.length=%d != b.length=%d\n",
7809 (int)a.length, (int)b.length);
7812 if (memcmp(a.data, b.data, a.length) != 0) {
7813 printf("a.data and b.data differ\n");
7819 static bool run_local_memcache(int dummy)
7821 struct memcache *cache;
7823 DATA_BLOB d1, d2, d3;
7824 DATA_BLOB v1, v2, v3;
7826 TALLOC_CTX *mem_ctx;
7828 size_t size1, size2;
7831 cache = memcache_init(NULL, 100);
7833 if (cache == NULL) {
7834 printf("memcache_init failed\n");
7838 d1 = data_blob_const("d1", 2);
7839 d2 = data_blob_const("d2", 2);
7840 d3 = data_blob_const("d3", 2);
7842 k1 = data_blob_const("d1", 2);
7843 k2 = data_blob_const("d2", 2);
7845 memcache_add(cache, STAT_CACHE, k1, d1);
7846 memcache_add(cache, GETWD_CACHE, k2, d2);
7848 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7849 printf("could not find k1\n");
7852 if (!data_blob_equal(d1, v1)) {
7856 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7857 printf("could not find k2\n");
7860 if (!data_blob_equal(d2, v2)) {
7864 memcache_add(cache, STAT_CACHE, k1, d3);
7866 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7867 printf("could not find replaced k1\n");
7870 if (!data_blob_equal(d3, v3)) {
7874 memcache_add(cache, GETWD_CACHE, k1, d1);
7876 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7877 printf("Did find k2, should have been purged\n");
7883 cache = memcache_init(NULL, 0);
7885 mem_ctx = talloc_init("foo");
7887 str1 = talloc_strdup(mem_ctx, "string1");
7888 str2 = talloc_strdup(mem_ctx, "string2");
7890 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7891 data_blob_string_const("torture"), &str1);
7892 size1 = talloc_total_size(cache);
7894 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7895 data_blob_string_const("torture"), &str2);
7896 size2 = talloc_total_size(cache);
7898 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7900 if (size2 > size1) {
7901 printf("memcache leaks memory!\n");
7911 static void wbclient_done(struct tevent_req *req)
7914 struct winbindd_response *wb_resp;
7915 int *i = (int *)tevent_req_callback_data_void(req);
7917 wbc_err = wb_trans_recv(req, req, &wb_resp);
7920 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7923 static bool run_local_wbclient(int dummy)
7925 struct event_context *ev;
7926 struct wb_context **wb_ctx;
7927 struct winbindd_request wb_req;
7928 bool result = false;
7931 BlockSignals(True, SIGPIPE);
7933 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7938 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7939 if (wb_ctx == NULL) {
7943 ZERO_STRUCT(wb_req);
7944 wb_req.cmd = WINBINDD_PING;
7946 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7948 for (i=0; i<nprocs; i++) {
7949 wb_ctx[i] = wb_context_init(ev, NULL);
7950 if (wb_ctx[i] == NULL) {
7953 for (j=0; j<torture_numops; j++) {
7954 struct tevent_req *req;
7955 req = wb_trans_send(ev, ev, wb_ctx[i],
7956 (j % 2) == 0, &wb_req);
7960 tevent_req_set_callback(req, wbclient_done, &i);
7966 while (i < nprocs * torture_numops) {
7967 event_loop_once(ev);
7976 static void getaddrinfo_finished(struct tevent_req *req)
7978 char *name = (char *)tevent_req_callback_data_void(req);
7979 struct addrinfo *ainfo;
7982 res = getaddrinfo_recv(req, &ainfo);
7984 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7987 d_printf("gai(%s) succeeded\n", name);
7988 freeaddrinfo(ainfo);
7991 static bool run_getaddrinfo_send(int dummy)
7993 TALLOC_CTX *frame = talloc_stackframe();
7994 struct fncall_context *ctx;
7995 struct tevent_context *ev;
7996 bool result = false;
7997 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7998 "www.slashdot.org", "heise.de" };
7999 struct tevent_req *reqs[4];
8002 ev = event_context_init(frame);
8007 ctx = fncall_context_init(frame, 4);
8009 for (i=0; i<ARRAY_SIZE(names); i++) {
8010 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8012 if (reqs[i] == NULL) {
8015 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8016 discard_const_p(void, names[i]));
8019 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8020 tevent_loop_once(ev);
8029 static bool dbtrans_inc(struct db_context *db)
8031 struct db_record *rec;
8036 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8038 printf(__location__ "fetch_lock failed\n");
8042 if (rec->value.dsize != sizeof(uint32_t)) {
8043 printf(__location__ "value.dsize = %d\n",
8044 (int)rec->value.dsize);
8048 val = (uint32_t *)rec->value.dptr;
8051 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8054 if (!NT_STATUS_IS_OK(status)) {
8055 printf(__location__ "store failed: %s\n",
8066 static bool run_local_dbtrans(int dummy)
8068 struct db_context *db;
8069 struct db_record *rec;
8074 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8075 O_RDWR|O_CREAT, 0600);
8077 printf("Could not open transtest.db\n");
8081 res = db->transaction_start(db);
8083 printf(__location__ "transaction_start failed\n");
8087 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8089 printf(__location__ "fetch_lock failed\n");
8093 if (rec->value.dptr == NULL) {
8095 status = rec->store(
8096 rec, make_tdb_data((uint8_t *)&initial,
8099 if (!NT_STATUS_IS_OK(status)) {
8100 printf(__location__ "store returned %s\n",
8108 res = db->transaction_commit(db);
8110 printf(__location__ "transaction_commit failed\n");
8118 res = db->transaction_start(db);
8120 printf(__location__ "transaction_start failed\n");
8124 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8125 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8129 for (i=0; i<10; i++) {
8130 if (!dbtrans_inc(db)) {
8135 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8136 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8140 if (val2 != val + 10) {
8141 printf(__location__ "val=%d, val2=%d\n",
8142 (int)val, (int)val2);
8146 printf("val2=%d\r", val2);
8148 res = db->transaction_commit(db);
8150 printf(__location__ "transaction_commit failed\n");
8160 * Just a dummy test to be run under a debugger. There's no real way
8161 * to inspect the tevent_select specific function from outside of
8165 static bool run_local_tevent_select(int dummy)
8167 struct tevent_context *ev;
8168 struct tevent_fd *fd1, *fd2;
8169 bool result = false;
8171 ev = tevent_context_init_byname(NULL, "select");
8173 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8177 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8179 d_fprintf(stderr, "tevent_add_fd failed\n");
8182 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8184 d_fprintf(stderr, "tevent_add_fd failed\n");
8189 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8191 d_fprintf(stderr, "tevent_add_fd failed\n");
8201 static double create_procs(bool (*fn)(int), bool *result)
8204 volatile pid_t *child_status;
8205 volatile bool *child_status_out;
8208 struct timeval start;
8212 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8213 if (!child_status) {
8214 printf("Failed to setup shared memory\n");
8218 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8219 if (!child_status_out) {
8220 printf("Failed to setup result status shared memory\n");
8224 for (i = 0; i < nprocs; i++) {
8225 child_status[i] = 0;
8226 child_status_out[i] = True;
8229 start = timeval_current();
8231 for (i=0;i<nprocs;i++) {
8234 pid_t mypid = getpid();
8235 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8237 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8240 if (torture_open_connection(¤t_cli, i)) break;
8242 printf("pid %d failed to start\n", (int)getpid());
8248 child_status[i] = getpid();
8250 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8252 child_status_out[i] = fn(i);
8259 for (i=0;i<nprocs;i++) {
8260 if (child_status[i]) synccount++;
8262 if (synccount == nprocs) break;
8264 } while (timeval_elapsed(&start) < 30);
8266 if (synccount != nprocs) {
8267 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8269 return timeval_elapsed(&start);
8272 /* start the client load */
8273 start = timeval_current();
8275 for (i=0;i<nprocs;i++) {
8276 child_status[i] = 0;
8279 printf("%d clients started\n", nprocs);
8281 for (i=0;i<nprocs;i++) {
8282 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8287 for (i=0;i<nprocs;i++) {
8288 if (!child_status_out[i]) {
8292 return timeval_elapsed(&start);
8295 #define FLAG_MULTIPROC 1
8302 {"FDPASS", run_fdpasstest, 0},
8303 {"LOCK1", run_locktest1, 0},
8304 {"LOCK2", run_locktest2, 0},
8305 {"LOCK3", run_locktest3, 0},
8306 {"LOCK4", run_locktest4, 0},
8307 {"LOCK5", run_locktest5, 0},
8308 {"LOCK6", run_locktest6, 0},
8309 {"LOCK7", run_locktest7, 0},
8310 {"LOCK8", run_locktest8, 0},
8311 {"LOCK9", run_locktest9, 0},
8312 {"UNLINK", run_unlinktest, 0},
8313 {"BROWSE", run_browsetest, 0},
8314 {"ATTR", run_attrtest, 0},
8315 {"TRANS2", run_trans2test, 0},
8316 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8317 {"TORTURE",run_torture, FLAG_MULTIPROC},
8318 {"RANDOMIPC", run_randomipc, 0},
8319 {"NEGNOWAIT", run_negprot_nowait, 0},
8320 {"NBENCH", run_nbench, 0},
8321 {"NBENCH2", run_nbench2, 0},
8322 {"OPLOCK1", run_oplock1, 0},
8323 {"OPLOCK2", run_oplock2, 0},
8324 {"OPLOCK3", run_oplock3, 0},
8325 {"OPLOCK4", run_oplock4, 0},
8326 {"DIR", run_dirtest, 0},
8327 {"DIR1", run_dirtest1, 0},
8328 {"DIR-CREATETIME", run_dir_createtime, 0},
8329 {"DENY1", torture_denytest1, 0},
8330 {"DENY2", torture_denytest2, 0},
8331 {"TCON", run_tcon_test, 0},
8332 {"TCONDEV", run_tcon_devtype_test, 0},
8333 {"RW1", run_readwritetest, 0},
8334 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8335 {"RW3", run_readwritelarge, 0},
8336 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8337 {"OPEN", run_opentest, 0},
8338 {"POSIX", run_simple_posix_open_test, 0},
8339 {"POSIX-APPEND", run_posix_append, 0},
8340 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8341 {"ASYNC-ECHO", run_async_echo, 0},
8342 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8343 { "SHORTNAME-TEST", run_shortname_test, 0},
8344 { "ADDRCHANGE", run_addrchange, 0},
8346 {"OPENATTR", run_openattrtest, 0},
8348 {"XCOPY", run_xcopy, 0},
8349 {"RENAME", run_rename, 0},
8350 {"DELETE", run_deletetest, 0},
8351 {"DELETE-LN", run_deletetest_ln, 0},
8352 {"PROPERTIES", run_properties, 0},
8353 {"MANGLE", torture_mangle, 0},
8354 {"MANGLE1", run_mangle1, 0},
8355 {"W2K", run_w2ktest, 0},
8356 {"TRANS2SCAN", torture_trans2_scan, 0},
8357 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8358 {"UTABLE", torture_utable, 0},
8359 {"CASETABLE", torture_casetable, 0},
8360 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8361 {"PIPE_NUMBER", run_pipe_number, 0},
8362 {"TCON2", run_tcon2_test, 0},
8363 {"IOCTL", torture_ioctl_test, 0},
8364 {"CHKPATH", torture_chkpath_test, 0},
8365 {"FDSESS", run_fdsesstest, 0},
8366 { "EATEST", run_eatest, 0},
8367 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8368 { "CHAIN1", run_chain1, 0},
8369 { "CHAIN2", run_chain2, 0},
8370 { "WINDOWS-WRITE", run_windows_write, 0},
8371 { "CLI_ECHO", run_cli_echo, 0},
8372 { "GETADDRINFO", run_getaddrinfo_send, 0},
8373 { "TLDAP", run_tldap },
8374 { "STREAMERROR", run_streamerror },
8375 { "NOTIFY-BENCH", run_notify_bench },
8376 { "BAD-NBT-SESSION", run_bad_nbt_session },
8377 { "SMB-ANY-CONNECT", run_smb_any_connect },
8378 { "NOTIFY-ONLINE", run_notify_online },
8379 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8380 { "LOCAL-GENCACHE", run_local_gencache, 0},
8381 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8382 { "LOCAL-BASE64", run_local_base64, 0},
8383 { "LOCAL-RBTREE", run_local_rbtree, 0},
8384 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8385 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8386 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8387 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8388 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8389 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8390 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8391 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8396 /****************************************************************************
8397 run a specified test or "ALL"
8398 ****************************************************************************/
8399 static bool run_test(const char *name)
8406 if (strequal(name,"ALL")) {
8407 for (i=0;torture_ops[i].name;i++) {
8408 run_test(torture_ops[i].name);
8413 for (i=0;torture_ops[i].name;i++) {
8414 fstr_sprintf(randomfname, "\\XX%x",
8415 (unsigned)random());
8417 if (strequal(name, torture_ops[i].name)) {
8419 printf("Running %s\n", name);
8420 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8421 t = create_procs(torture_ops[i].fn, &result);
8424 printf("TEST %s FAILED!\n", name);
8427 struct timeval start;
8428 start = timeval_current();
8429 if (!torture_ops[i].fn(0)) {
8431 printf("TEST %s FAILED!\n", name);
8433 t = timeval_elapsed(&start);
8435 printf("%s took %g secs\n\n", name, t);
8440 printf("Did not find a test named %s\n", name);
8448 static void usage(void)
8452 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8453 printf("Please use samba4 torture.\n\n");
8455 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8457 printf("\t-d debuglevel\n");
8458 printf("\t-U user%%pass\n");
8459 printf("\t-k use kerberos\n");
8460 printf("\t-N numprocs\n");
8461 printf("\t-n my_netbios_name\n");
8462 printf("\t-W workgroup\n");
8463 printf("\t-o num_operations\n");
8464 printf("\t-O socket_options\n");
8465 printf("\t-m maximum protocol\n");
8466 printf("\t-L use oplocks\n");
8467 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8468 printf("\t-A showall\n");
8469 printf("\t-p port\n");
8470 printf("\t-s seed\n");
8471 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8472 printf("\t-f filename filename to test\n");
8475 printf("tests are:");
8476 for (i=0;torture_ops[i].name;i++) {
8477 printf(" %s", torture_ops[i].name);
8481 printf("default test is ALL\n");
8486 /****************************************************************************
8488 ****************************************************************************/
8489 int main(int argc,char *argv[])
8495 bool correct = True;
8496 TALLOC_CTX *frame = talloc_stackframe();
8497 int seed = time(NULL);
8499 #ifdef HAVE_SETBUFFER
8500 setbuffer(stdout, NULL, 0);
8503 setup_logging("smbtorture", DEBUG_STDOUT);
8507 if (is_default_dyn_CONFIGFILE()) {
8508 if(getenv("SMB_CONF_PATH")) {
8509 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8512 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8519 for(p = argv[1]; *p; p++)
8523 if (strncmp(argv[1], "//", 2)) {
8527 fstrcpy(host, &argv[1][2]);
8528 p = strchr_m(&host[2],'/');
8533 fstrcpy(share, p+1);
8535 fstrcpy(myname, get_myname(talloc_tos()));
8537 fprintf(stderr, "Failed to get my hostname.\n");
8541 if (*username == 0 && getenv("LOGNAME")) {
8542 fstrcpy(username,getenv("LOGNAME"));
8548 fstrcpy(workgroup, lp_workgroup());
8550 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8554 port_to_use = atoi(optarg);
8557 seed = atoi(optarg);
8560 fstrcpy(workgroup,optarg);
8563 max_protocol = interpret_protocol(optarg, max_protocol);
8566 nprocs = atoi(optarg);
8569 torture_numops = atoi(optarg);
8572 lp_set_cmdline("log level", optarg);
8581 local_path = optarg;
8584 torture_showall = True;
8587 fstrcpy(myname, optarg);
8590 client_txt = optarg;
8597 use_kerberos = True;
8599 d_printf("No kerberos support compiled in\n");
8605 fstrcpy(username,optarg);
8606 p = strchr_m(username,'%');
8609 fstrcpy(password, p+1);
8614 fstrcpy(multishare_conn_fname, optarg);
8615 use_multishare_conn = True;
8618 torture_blocksize = atoi(optarg);
8621 test_filename = SMB_STRDUP(optarg);
8624 printf("Unknown option %c (%d)\n", (char)opt, opt);
8629 d_printf("using seed %d\n", seed);
8633 if(use_kerberos && !gotuser) gotpass = True;
8636 p = getpass("Password:");
8638 fstrcpy(password, p);
8643 printf("host=%s share=%s user=%s myname=%s\n",
8644 host, share, username, myname);
8646 if (argc == optind) {
8647 correct = run_test("ALL");
8649 for (i=optind;i<argc;i++) {
8650 if (!run_test(argv[i])) {